【问题标题】:Call Function in Excel VSTO Add-in from Python (SAP Analysis Plug-in VBA macros) (Run-time error 1004: The macro may not be available)从 Python 调用 Excel VSTO 外接程序中的函数(SAP 分析插件 VBA 宏)(运行时错误 1004:宏可能不可用)
【发布时间】:2021-04-23 01:42:28
【问题描述】:

问题总结

我在尝试在 Excel 工作簿中执行 VBA 宏的 Python 代码时遇到问题。每当它尝试使用excel_instance.Application.Run() 时都会引发错误:

运行时错误“1004”:无法运行宏“SAPLogon”。宏可以 在此工作簿中不可用,或者所有宏都可能被禁用。

因此,显然脚本无法识别函数 SAPLogonSAPExecuteCommand(属于 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

  • 尝试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


    【解决方案1】:

    在您的 VSTO 插件中,如果您创建一个宏来运行一些没有任何 ui 的后台代码,那么我建议创建 XLL 而不是 VSTO 插件,以便您可以使用问题中提到的 RegisterXLL 函数注册它。

    您可以使用 Excel-DNA 框架 创建 XLL。你不需要写太多的代码, 只需复制粘贴 VSTO 代码并更改一些参考。

    或者您可以尝试使用 excel_instance.AddIns.Add(addin_path) 添加 VSTO 插件,然后再使用 installed=true。 但在此之前,请检查您的插件是否已在您的用户/机器注册表中注册。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多