从 python 执行 LibreOffice Calc Basic 宏

Posted

技术标签:

【中文标题】从 python 执行 LibreOffice Calc Basic 宏【英文标题】:Execute LibreOffice Calc Basic macro from python 【发布时间】:2020-04-03 14:52:59 【问题描述】:

我正在尝试使用 Python 自动化 LibreOffice 电子表格。我得到一个桌面并使用

打开电子表格
file_url = uno.systemPathToFileUrl(os.path.abspath("/path/to/file/estimation.xlsm"))
doc = desktop.loadComponentFromURL(file_url, "_blank", 0, oo_properties(MacroExecutionMode=4))

以下代码将打印基本脚本

the_basic_libs = doc.BasicLibraries
the_vba = the_basic_libs.getByName("VBAProject")
the_takerate = the_vba.getByName("TakeRate")
print(the_takerate)

打印的模块的第一行是:

Rem Attribute VBA_ModuleType=VBAModule
Option VBASupport 1

Public Sub TakeRateScenarioAnalysis()
Dim StartCell As Range

我得到了脚本

oor = OORunner()
msp = oor.get_context().getValueByName("/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory")
sp = msp.createScriptProvider("")
scriptx = sp.getScript("vnd.sun.star.script:VBAProject.TakeRate.TakeRateScenarioAnalysis?language=Basic&location=document")

返回如下错误

Traceback (most recent call last):
  File "./runProjectEstimate.py", line 198, in <module>
    scriptx = sp.getScript("vnd.sun.star.script:VBAProject.TakeRate.TakeRateScenarioAnalysis?language=Basic&location=document")
__main__.ScriptFrameworkErrorException: The following Basic script could not be found:
library: 'VBAProject'
module: 'TakeRate'
method: 'TakeRateScenarioAnalysis'
location: 'document'

脚本 URI 有问题吗?我不知道为什么我可以打印脚本但脚本提供者找不到它。

【问题讨论】:

在找到脚本提供者工厂 API 文档后,我注意到 createScriptProvider 调用需要一个上下文,因此我将该行更改为 msp.createScriptProvider(oor.get_context()),结果与之前的错误相同。 为了更容易重现问题,请尽量避免在您的问题中未定义的名称,例如 OORunner。在这种情况下,最好直接写msp = ctx.getValueByName("/singletons/com.sun.star.script.provider.theMasterScriptProviderFactory") 【参考方案1】:

以下内容对我有用:

scriptx = sp.getScript(
    'vnd.sun.star.script:Standard.Module1.TakeRateScenarioAnalysis?'
    'language=Basic&location=application')

但是,如您的问题中所述,这没有:

scriptx = sp.getScript(
    "vnd.sun.star.script:VBAProject.TakeRate.TakeRateScenarioAnalysis?"
    "language=Basic&location=document")

从这些结果来看,当宏存储在文档中时,似乎不可能以这种方式调用宏。这很可能是权限问题。从可能由其他人创建的文档中调用宏是传播病毒的好方法,因此 LO 试图阻止这种情况。

将您的VBAProject 库移动到My Macros 而不是文档内部是否可以接受?然后一切都应该按预期工作。

几个相关链接可能会提供更多想法:

How to call an existing LibreOffice python macro from a python script Running Libreoffice BASIC macro from python

编辑

有一种方法可以调用存储在文档中的宏。 从文档中获取脚本提供程序,而不是主脚本提供程序。

oScriptProvider = doc.getScriptProvider()
oScript = oScriptProvider.getScript(
    "vnd.sun.star.script:Standard.Module1.SayHello?"
    "language=Basic&location=document")
oScript.invoke((), (), ())

【讨论】:

谢谢,这个解决方案有效。我将脚本移至“我的宏”,自动化可以找到该脚本。我想不从文档中运行宏不仅仅是一个建议,而是通过 API 强制执行的。 给任何有同样问题的人的笔记。我使用的宏是在 Excel 的 VisualBasic 中创建的。当宏在文档中时,VBA 兼容性允许脚本在从 UI 调用时运行。当我将它移到我的宏库时,我无法让它在兼容模式下运行。所以像 Frame("myNamedCell") 这样的结构会导致错误。我必须将它们转换为 sheet.getCellRangeByName("myNamedCell") 以及其他 VBA 语法。 你可以设置Option Compatible。但是,我建议您改写命令,就像您所做的那样。

以上是关于从 python 执行 LibreOffice Calc Basic 宏的主要内容,如果未能解决你的问题,请参考以下文章

从命令行到 libreoffice 的配置文件的路径

如何使用 LibreOffice 宏将 os.system() 命令写入 python 脚本并执行它?

Libreoffice 无法在 php 运行时启动

从 Python 控制 Libreoffice Impress

从 python 运行 Libreoffice BASIC 宏

如何在 LibreOffice 中运行 python 宏?