从 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 宏将 os.system() 命令写入 python 脚本并执行它?
从 Python 控制 Libreoffice Impress