【发布时间】:2021-04-23 01:42:28
【问题描述】:
问题总结
我在尝试在 Excel 工作簿中执行 VBA 宏的 Python 代码时遇到问题。每当它尝试使用excel_instance.Application.Run() 时都会引发错误:
运行时错误“1004”:无法运行宏“SAPLogon”。宏可以 在此工作簿中不可用,或者所有宏都可能被禁用。
因此,显然脚本无法识别函数 SAPLogon 和 SAPExecuteCommand(属于 SAP VSTO 插件。我相信它正在发生,因为 SAP 插件未加载(有关此部分的更多信息) : 为什么我认为问题与加载插件有关?)到我创建的 Excel 实例中。至少我认为是这样。
有人知道怎么解决吗?
详细问题
我对这个项目的目的是自动刷新使用 SAP Analysis for Office AddIn 的 Excel 工作簿。此插件与 SAP 连接以从业务仓库中提取信息。据我所知,它是用 VSTO 编程制作的,它有一个宏 API,可以在 VBA 代码的帮助下在 Excel 中使用它(更多信息here)
我想将它与 Python 集成,以便我可以将此代码嵌入到另一个项目中,从而自动从 SAP 获取数据片段。因此,在blog(用 VBA 实现解决方案)的帮助下,我开始寻找自己的 Python 解决方案。
在这里您可以看到我想用 Python 脚本介绍的详细流程:
- 绿色: 表示我设法实现的流程
- 红色: 当前不工作的进程
我目前使用的 Python 代码
import win32com.client as win32 # allow easy access to Window’s Component Object Model (COM) and control Microsoft applications
from pathlib import Path # Module to handle file paths
# Path of excel file to import
sap_aof_excel_file = Path.cwd().joinpath('Test_Data.xlsm')
# Declaring variables
bwclient = "999"
bwuser = "USERNAME"
bwpassword = "PASSWORD"
# Launch Excel: Create an Exel object and store it into a variable named 'excel_instance'
excel_instance = win32.gencache.EnsureDispatch('excel_instance.Application')
# Make it visible otherwise it doesn’t work
excel_instance.Visible = True
excel_instance.DisplayAlerts = False
# Open the file in the new Excel instance,
# The 1st false: don't update the links
# The 2nd false: and don't open it read-only
workbook_sap = excel_instance.Workbooks.Open(sap_aof_excel_file, False, False)
# Force the plugin to be enabled in the instance of Excel
for addin in excel_instance.Application.COMAddIns:
if addin.progID == 'SapExcelAddIn':
if addin.Connect == False:
addin.Connect = True
elif addin.Connect == True:
addin.Connect = False
addin.Connect = True
# logs in to Business Warehouse
lResult = excel_instance.Application.Run("SAPLogon", "DS_1", bwclient, bwuser, bwpassword)
# execute a command to refresh the data
lResult = excel_instance.Application.Run("SAPExecuteCommand", "RefreshData", "DS_1")
# Save the file and close it
workbook_sap.Save
workbook_sap.Close()
# force the application to close
excel_instance.DisplayAlerts = True
excel_instance.Application.Quit()
# Clear out the memory
excel_instance = None
workbook_sap = None
为什么我认为问题与加载插件有关?
我真的在想办法解决这个问题。我意识到,如果我自己打开 Excel 工作簿,SAPLogon 函数在被 VBA 宏调用时运行良好。如果我从 Python 脚本调用它,它只会不起作用。于是去了VBA Studio,看到Python发起的实例显然没有加载插件。
我自己打开的工作簿:在资源管理器中加载了插件
使用 Python 语句打开的工作簿:没有插件
Python中用来打开实例的语句是win32.gencache.EnsureDispatch('Excel.Application')
所以我决定做一个测试。如果我调用另一个插件,例如 Data Analysis,它会起作用吗?
答案是:不。它会引发与 SAP 插件相同的错误。
这让我很高兴。至少我认为这是与COM接口有关的问题,与通过Python访问SAP Plugin的限制无关。经过一番研究,我发现您可以使用 RegisterXLL 方法加载某些类型的插件。所以我在我的代码中添加了以下几行:
# Register (or loads) XLL Excel Plugin called Data Analysis
excel_instance.RegisterXLL(r'C:\Program Files (x86)\Microsoft Office\root\Office16\Library\Analysis\ANALYS32.XLL')
# Call "Moveavg" Analysis ToolPack Function after execution of RegisterXLL
lResult = excel_instance.Application.Run("Moveavg", 'arnols', 'souza', False, True, False)
成功了!
代码执行数据分析插件中的函数。
很明显,我尝试以相同的方式加载 SAP 插件。但这并不成功。此方法仅适用于 XLL,不适用于 VSTO 插件。另外,我找不到正确加载 VSTO 插件的解决方案。
excel_instance.RegisterXLL(r'C:\Program Files (x86)\SAP BusinessObjects\Office AddIn\SapExcelAddIn.vsto')
它会引发错误。 =(
我尝试过但没有成功的替代方案
-
试探一:从其他解决方案调用 VSTO 函数 (Link)
- 注意:我尝试使用下面的语句调用 SAPLogon 函数
excel_instance.Application.COMAddIns['SapExcelAddIn'].Object.SAPLogon("DS_1", bwclient, bwuser, bwpassword) - 发生了什么:错误
- 注意:我尝试使用下面的语句调用 SAPLogon 函数
属性错误:.SAPLogon
-
尝试2:尝试动态启动Excel实例
- 注意:更改了代码中的语句
excel_instance = win32.dynamic.Dispatch('Excel.Application') - 发生了什么:没有什么不同
- 注意:更改了代码中的语句
-
试探3:尝试指定Plugin所在的位置
- 注意:尝试了两条路径到插件所在的地方
# Need to load the add ins before opening the workbook
#addin_path = r'C:\Program Files (x86)\SAP BusinessObjects\Office AddIn\SapExcelAddIn.vsto'
addin_path = r'C:\Program Files (x86)\SAP BusinessObjects\Office AddIn\SapExcelAddIn.dll'
excel_instance.AddIns.Add(addin_path).Installed = True
- 发生了什么:错误
com_error: (-2147352567, '发生异常。', (0, 'Microsoft Excel', 'AddIns类的添加方法失败', 'xlmain11.chm', 0, -2146827284), 无)
-
尝试 4:尝试用绝对路径调用函数
- 注释:大量的假设
test0 = "SAPLogon"
test1 = r'C:\Program Files (x86)\SAP BusinessObjects\Office AddIn\SapExcelAddIn.vsto!SAPLogon'
test2 = r'C:\Program Files (x86)\SAP BusinessObjects\Office AddIn\SapExcelAddIn.vsto|vstolocal!SAPLogon'
test3 = r"'C:\Program Files (x86)\SAP BusinessObjects\Office AddIn\SapExcelAddIn.vsto'!SAPLogon"
test4 = r"'C:\Program Files (x86)\SAP BusinessObjects\Office AddIn\SapExcelAddIn.vsto|vstolocal'!SAPLogon"
test5 = 'SapExcelAddIn.vsto!SAPLogon'
test6 = 'SapExcelAddIn.vsto|vstolocal!SAPLogon'
lResult = excel_instance.Application.Run(testn, "DS_1", bwclient, bwuser, bwpassword)
- 发生了什么:错误
com_error: (-2147352567, '发生异常。', (0, 'Microsoft Excel', “无法运行宏 'SAPLogon'。该宏可能在 此工作簿或所有宏可能被禁用。", 'xlmain11.chm', 0, -2146827284),无)
【问题讨论】:
标签: python vba com vsto win32com