Применение макроса VBA к файлу Excel с использованием библиотеки Python win32com - PullRequest
1 голос
/ 22 сентября 2019

Я пытаюсь применить макрос VBA, используя python и библиотеку win32com, идея состоит в том, чтобы создать фиксированный файл Excel, сохранить макрос и затем запустить его.Я взял эту идею отсюда: https://redoakstrategic.com/pythonexcelmacro/

Проблема возникает, когда скрипт должен работать с файлом xlsm и запускать макрос с помощью Application.Run ().Мой код:

import pandas as pd 
import win32com.client 
import os

#creating the dataframe
df = df1=pd.read_excel ("normal_excel_file.xlsx", index_col=0)
filename = "normal_excel_file.xlsx"
writer = pd.ExcelWriter(filename, engine='xlsxwriter')
df.to_excel(writer, sheet_name='data', index=False)

#copiying and renaming the file to xlsm
shutil.copy("normal_excel_file.xlsx", "(1)normal_excel_file.xlsx")
os.rename("(1)normal_excel_file.xlsx", "macros_excel_file.xlsm")

#adding the macro to the workbook
filename_macro = r"C:\Users\John\Desktop\Python_scripts\Running VBA Macro\macros_excel_file.xlsm"
workbook = writer.book
workbook.filename = filename_macro
workbook.add_vba_project('vbaProject.bin')
writer.save()

И конфликтующая часть:

 if os.path.exists(filename_macro):
        xl = win32com.client.Dispatch('Excel.Application')
        xl.Workbooks.Open(Filename = filename_macro, ReadOnly=1)

        #assuming that there is only one macro, and is stored as "ThisWorkbook.Macro1" in the file

        xl.Application.Run("ThisWorkbook.Macro1") #I also try using only "Macro1" and the whole path of the file
        xl.Application.Quit()
        del xl

И я получаю следующую ошибку.Сначала сообщение об ошибке:

com_error: (-2147352567, 'An exception occurred.', (0, 'Microsoft Excel', 'The "ThisWorkbook.Macro1" macro cannot be executed. The macro may not be available in this book or all of them may have been disabled. the macros. ',' xlmain11.chm ', 0, -2146827284), None)

И весь текст ошибки:

com_error                                 Traceback (most recent call last)
<ipython-input-16-6e91b8d2f622> in <module>
      3     xl = win32com.client.Dispatch('Excel.Application')
      4     xl.Workbooks.Open(Filename = filename_macro, ReadOnly=1)
----> 5     xl.Application.Run("ThisWorkbook.Macro1")
      6     xl.Application.Quit()
      7     del xl

~\Anaconda3\lib\site-packages\win32com\client\dynamic.py in Run(self, Macro, Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7, Arg8, Arg9, Arg10, Arg11, Arg12, Arg13, Arg14, Arg15, Arg16, Arg17, Arg18, Arg19, Arg20, Arg21, Arg22, Arg23, Arg24, Arg25, Arg26, Arg27, Arg28, Arg29, Arg30)

~\Anaconda3\lib\site-packages\win32com\client\dynamic.py in _ApplyTypes_(self, dispid, wFlags, retType, argTypes, user, resultCLSID, *args)
    285 
    286         def _ApplyTypes_(self, dispid, wFlags, retType, argTypes, user, resultCLSID, *args):
--> 287                 result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args)
    288                 return self._get_good_object_(result, user, resultCLSID)
    289 

com_error: (-2147352567, 'An exception occurred.', (0, 'Microsoft Excel', 'The "ThisWorkbook.Macro1" macro cannot be executed. The macro may not be available in this book or all of them may have been disabled. the macros. ',' xlmain11.chm ', 0, -2146827284), None)

Я иду в Центр управления безопасностью в Microsoft Office и разрешаю все типы макросов (https://support.office.com/en-us/article/enable-or-disable-macros-in-office-files-12b036fd-d140-4e74-b45e-16fed1a7e5c6?ui=en-US&rs=en-US&ad=US). Но ошибка продолжает возникать

Если кто-нибудь знает, как это исправить, было бы здорово

Спасибо всем

1 Ответ

0 голосов
/ 24 сентября 2019

Поскольку .xlsx до .xlsm - это принципиально разные типы двоичных файлов, вы не можете просто скопировать и переименовать, используя строки:

shutil.copy("normal_excel_file.xlsx", "(1)normal_excel_file.xlsx")
os.rename("(1)normal_excel_file.xlsx", "macros_excel_file.xlsm")

(как ни странно, ваша ссылка на учебник не показывает, как сгенерированы пандыФайл .xlsx становится .xlsm на следующем шаге присоединенного макроса.)

Вместо этого используйте объект записи Excel для переноса макроса и сохранения как .xlsm.Также используйте диспетчер контекста with для объекта writer , чтобы эффективно закрыть объект ввода-вывода после обработки.

# creating the dataframe
path = "C:\Users\John\Desktop\Python_scripts\Running VBA Macro"
filename = "normal_excel_file.xlsx"
filename_macro = "macros_excel_file.xlsm"

df = pd.read_excel(filename, index_col=0)
with pd.ExcelWriter(filename, engine='xlsxwriter') as writer:
    df.to_excel(writer, sheet_name='data', index=False)
    workbook = writer.book
    workbook.filename = filename_macro
    workbook.add_vba_project('vbaProject.bin')
    writer.save()

# RUN MACRO
if os.path.exists(os.path.join(path, filename_macro)):
    wb = xl.Workbooks.Open(Filename = filename_macro, ReadOnly=1)
    xl.Application.Run("ThisWorkbook.Macro1")
    xl.Application.Quit()
...