как обновить существующий лист xlsm с помощью макросов, используя pandas, openpyxl, xlwings без потери макросов - PullRequest
4 голосов
/ 08 июля 2019

Прежде всего, я расскажу о своих нуждах из этого поста ..... Теперь мне нужно обновить существующий файл excel xlsm из другого файла excel csv, так как этот csv файл экспортируется csv из почтового ящика outlook mail, и это шаблон моей почты outlook csv

|---------------------|------------------|------------------|------------|
|      Subject        |       Body       |    From: (Name)  | To: (Name) |
|---------------------|------------------|------------------|------------|
|blabla LCAIN5678 bla |bla bla bla bla   |bla bla bla bla   |bla bla bla |
|---------------------|------------------|------------------|------------|

Пока я работаю и анализирую этот файл csv, используя str.extract после того, как я прочитал с пандами иэто мой извлекающий код для извлечения определенных данных из файла csv, для извлечения определенной строки, подобной этой LCAIN5678 содержит пять символов и пять чисел, а затем используйте dropna() с,

Этот код

# this object extract 5 chars and 5 numbers from specific column in csv
replaced_sbj_value = myOutlook_inBox['Subject']
.str.extract(pat='(L(?:DEL|CAI|SIN).\d{5})').dropna()

Это мой xlsm файл, читаемый пандами

gov_tracker_sheet = pd.read_excel(r'' + mydi
                              sheet_name
                              header=1) 

, и это мой csv файл, читаемый пандами

myOutlook_inBox = pd.read_csv(r'' + mydir + 'test.CSV
                          encoding='latin-1')    

Затем я инициализируюсьэто так

myOutlook_inBox["Subject"] = replaced_sbj_value
print (replaced_sbj_value)

Чтобы быть таким

|-----------------|
|    Subject      |
|-----------------|
|   LCAIN5678     |
|-----------------|

Затем я создаю условие, используя некоторые функции, такие как loc str.contains

Как это условиетак как это условие фильтры для некоторых текстов в csv

# Condition 1: any mail from mowafy to te
frm_mwfy_to_te = myOutlook_inBox.loc[myOutlook_inBox['From: 
(Name)'].str.contains("mowafy", na=False) \
                                 & myOutlook_inBox['To: 
(Name)'].str.contains("te", na=False)] \
.drop_duplicates(keep=False)

тогда я создаюпеременная с помощью метода join для join переменная frm_mwfy_to_te для файла Excel xlsm, который я хочу обновить

filtered_data_cond1 = gov_tracker_sheet.loc[
gov_tracker_sheet['SiteCode']
.str.contains('|'.join(frm_mwfy_to_te.Subject))]
print(filtered_data_cond1)

, так как в результате просто получите строки, которые я хочу обновитьиз xlsm файла Excel

Итак, наконец, создайте значение кортежа для обновления Dataframe с помощью этой переменной. И это моя tuple переменная

values = tuple(filtered_data_cond1['Pending  '].values.tolist())

Какэто вывод моего tuple значения

(u'TE', u'PP', u'TE', u'TE', u'TE', u'TE', u'TE', u'TE', u'TE')

Итак, с этого момента я начал использовать Regex с использованием метода replace.

И это моя переменная замены, которую я создал

updated_gov_tracker = gov_tracker_sheet.replace(to_replace=values,
                                            value='xxxxxxxxxxxx', 
regex=False)

Этот код работает, но он просто заменяет все строки в файле xlsm, который содержит TE Мне нужно обновить только необходимые строки

, и я использовал другой способ, который некоторые считают, какэто, но это не работает нормально

updated_gov_tracker=re.sub(values,"xxxxxxxxx",gov_tracker_sheet)

Второе, что мне нужно, я хочу заменить свой новый Dataframe на старый xlsm лист таблицы без потери моего macros в excel

Отредактировано

и это мой существующий файл Excel, который я хочу обновить, выглядит как

enter image description here

и это мой csv Outlook Inbox Excel выглядит следующим образом

enter image description here

Теперь после поиска я обнаружил, что xlwings также может помочь мне, выбрав диапазон строки и записав новый updatedvalue, поэтому мне нужно теперь взять переменную tuple, так как эта переменная содержит stringsстолбца под названием код сайта, теперь мне нужно обновить первый лист Excel xlsm в зависимости от строк значений в этом кортеже

Пример

У меня есть значение кортежа, похожее на это LCAIN12345 LCAIN54632 LCAIN78965 blablabla

Теперь эти значения уже существуют на листе xlsm в столбце с именем SiteCode на листе с именем Gov_Tracker Я хочу обновить некоторые столбцы в зависимости от rows от этих значений, как я хочу обновить в столбцах с именемPending, Pending Status и blablabla

Теперь я хочу изменить значения строк в этом столбце, например, изменить старое значение в Pending, Pending Status, blablabla equals на новые значения TE,Ожидание TE Acceptance` блаблабла

надеюсь, эта информация достаточно ясна

1 Ответ

1 голос
/ 08 июля 2019

Самое простое решение для создания xlsm с XlsxWriter - вручную изменить окончание файла, а затем включить макросы в дополнительный шаг (см. здесь ):

import pandas as pd

df = pd.DataFrame({'First' : [5, 2, 0, 10, 4], 
                   'Second' : [9, 8, 21, 3, 8]})

writer = pd.ExcelWriter('test.xlsx', engine='xlsxwriter')

df.to_excel(writer, sheet_name='Sheet1')

workbook  = writer.book
workbook.filename = 'test.xlsm'
workbook.add_vba_project('./vbaProject.bin')

writer.save()

См. Это ответ .Вы можете извлечь макросы (vbaProject.bin) с помощью утилиты vba_extract.py, которая поставляется с пакетом XslxWriter.

$ vba_extract.py macro_file.xlsm
Extracted: vbaProject.bin
...