使用 win32com python 库将 VBA 宏应用到 Excel 文件

Appliying a VBA macro to an Excel file using win32com python library

我正在尝试使用 python 和 win32com 库应用 VBA 宏,想法是创建一个固定的 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)。但是错误继续发生

如果有人知道如何修复它会很棒

谢谢大家

因为 .xlsx.xlsm 是根本不同类型的二进制文件,您不能简单地使用行复制和重命名:

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

(奇怪的是,您的教程 link 没有显示 Pandas 生成的 .xlsx 文件如何在随后的附加宏步骤中变成 .xlsm。)

而是使用 Excel 编写器对象来迁移宏并另存为 .xlsm。此外,在 writer 对象上使用 with 上下文管理器以在处理后有效地关闭 i/o 对象。

# 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()