从 Python 中调用 BASIC 宏

您可以在 Python 脚本中调用 LibreOffice Basic 宏,从而访问一些重要的特性,比如:

LibreOffice 的应用程序编程接口 (API) 脚本框架支持在 Python 和 Basic 之间(或者其他受支持的编程语言之间)的跨语言脚本执行。参数可以互相之间来回传递,仅需要该参数是各个语言都能够识别的基本数据类型、且脚本框架能够对该参数进行适当的类型转换。

tip

我们建议您,在 Python, Basic, JavaScript 以及其他脚本引擎之间进行先跨语言调用之前,先熟悉 Python 的标准模块以及 LibreOffice 的API特性。


warning

如果您是在集成开发环境 (IDE) 中运行 Python 脚本,此时 LibreOffice 内置的 Basic 引擎可能不存在,您应当避免在这种情况下进行从 Python 到 LibreOffice Basic 的调用。但无论如何,Python 环境以及“通用网络对象” (Universal Networks Objects, UNO) 总是可用的。更多信息,请参考:搭建集成开发环境以进行 Python 开发


拉取LibreOffice BASIC脚本

LibreOffice Basic macros can be personal, shared, or embedded in documents. In order to execute them, Python run time needs to be provided with Basic macro locations. Implementing the com.sun.star.script.provider.XScriptProvider interface allows the retrieval of executable scripts:


		 import uno
		 from com.sun.star.script.provider import Xscript
		     
		 def getBasicScript(macro='Main', module='Module1', library='Standard',
		         isEmbedded=False) -> XScript:
		     '''Grab Basic script object before invocation.'''
		     ctx = uno.getComponentContext()
		     smgr = ctx.ServiceManager
		     if isEmbedded:
		         desktop = smgr.createInstanceWithContext('com.sun.star.frame.Desktop', ctx)
		         scriptPro = desktop.CurrentComponent.getScriptProvider()
		         location = "document"
		     else:
		         mspf = smgr.createInstanceWithContext(
		             "com.sun.star.script.provider.MasterScriptProviderFactory", ctx)
		         scriptPro = mspf.createScriptProvider("")
		         location = "application"
		     scriptName = "vnd.sun.star.script:"+library+"."+module+"."+macro+ \
		                  "?language=Basic&location="+location
		     xScript = scriptPro.getScript(scriptName)
		     return xScript
		 

运行 LibreOffice BASIC 脚本

LibreOffice 软件开发工具包 (SDK) 文档中的 com.sun.star.script.provider.XScript 界面部分详细描述了跨语言调用的约定。对函数的调用需要三个数组:

Python 语法

results = script.invoke((prompt,buttons,title), (), ())

script.invoke((message,), tuple, ())

script.invoke((args), (), results)

个人使用脚本或共享脚本的示例

Examples in Input/Output to Screen detail Python to Basic invocation calls. Monitoring Document Events illustrates the usage of *args Python idiom to print a variable number of parameters to Access2Base logging console dialog.

tip

At time of development you can interrupt Python script execution using Xray extension in order to inspect properties and methods of UNO objects. The APSO extension debugger allows object introspection using either Xray either MRI extensions.



	  def xray(myObject):
	  	  script = getBasicScript(library="XrayTool", module="_Main", macro="Xray")
	  	  script.invoke((myObject,), (), ())
	  

嵌入到文档内脚本的示例

*argsPython simplified syntax can be used in conjunction with LibreOffice Basic routines that accept a variable number of arguments. Below Print and SUM Python functions call their Basic Print and SUM counterparts, using aforementioned getBasicScript function. Exception handling is not detailed.


	  # -*- coding: utf-8 -*-
	  from __future__ import unicode_literals
	      
	  def Print(*args):
	      """Outputs the specified strings or numeric expressions in a dialog box."""
	      xScript = getBasicScript("Print", "Scripting", embedded=True)
	      xScript.invoke((args), (), ())
	      
	  def SUM(*args):
	      """SUM the specified number expression."""
	      xScript = getBasicScript("SUM", "Scripting", embedded=True)
	      res = xScript.invoke((args), (), ())
	      return res[0]
	      
	  # def getBasicScript()  # see above
	      
	  def playWithArgs():
	      Print("Fun with *args ", -9.81, 297864.681974, 8762E-137)
	      Print(SUM(45, -9.81, 297864.681974))
	      Print(SUM(45, -9.81, 297864.681974, 8762E+137))
	      
	  g_exportedScripts = (playWithArgs,)
	  

The LibreOffice Basic Print and SUM document-based routines accept a variable number of arguments. The Private or Public attributes have no effect. The arguments type checking is skipped for clarity.


	  Option Compatible ' "Standard.Scripting" module
	  Option Explicit
	      
	  Private Sub Print(ParamArray args() As Variant, Optional sep As String = " ")
	      ''' Print item list of variable number '''
	      ' all CStr() convertible args are accepted
	      Dim str As String, i As Integer
	      If UBound(args) >= 0 Then
	          For i = 0 To UBound(args)
	              str = str + Cstr(args(i))+ sep 
	          Next i
	      End If
	      Print str
	  End Sub ' Standard.Scripting.Print()
	      
	  Public Function SUM(ParamArray args() As Variant) As Variant
	      ''' SUM a variable list of numbers '''
	      Dim ndx As Integer
	      If UBound(args) >= 0 Then
	          For ndx = 0 To UBound(args)
	              SUM = SUM + args(ndx)
	          Next ndx
	      End If
	  End Function ' Standard.Scripting.SUM()
	  

请支持我们!