Llamar macros en Basic desde Python

Es posible llamar macros escritas en LibreOffice Basic desde secuencias de órdenes en Python y sacar provecho de funcionalidades tales como:

The LibreOffice Application Programming Interface (API) Scripting Framework supports inter-language script execution between Python and Basic, or other supported programming languages for that matter. Arguments can be passed back and forth across calls, provided that they represent primitive data types that both languages recognize, and assuming that the Scripting Framework converts them appropriately.


Es recomendable familiarizarse con los módulos estándares de Python y las funcionalidades de la API de LibreOffice antes de efectuar llamadas entre los lenguajes Python, Basic, JavaScript o cualquier otro motor de secuencias de órdenes.


Es posible que, al intentar ejecutar secuencias de órdenes escritas en Python desde un entorno integrado de desarrollo (EID), falte el motor de BASIC incrustado en LibreOffice. En estos contextos, evite las llamadas de Python a LibreOffice Basic. Por el contrario, el entorno Python y los objetos de red universales (UNO, por sus siglas en inglés) siempre estarán disponibles. Para más información, consulte Puesta en funcionamiento de un EID para Python.

Recuperación de secuencias de órdenes en Basic en LibreOffice

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:
		     '''Tomar el objeto de secuencia de Basic antes de la invocación.'''
		     ctx = uno.getComponentContext()
		     smgr = ctx.ServiceManager
		     if isEmbedded:
		         desktop = smgr.createInstanceWithContext('com.sun.star.frame.Desktop', ctx)
		         scriptPro = desktop.CurrentComponent.getScriptProvider()
		         location = "document"
		         mspf = smgr.createInstanceWithContext(
		             "com.sun.star.script.provider.MasterScriptProviderFactory", ctx)
		         scriptPro = mspf.createScriptProvider("")
		         location = "application"
		     scriptName = "vnd.sun.star.script:"+library+"."+module+"."+macro+ \
		     xScript = scriptPro.getScript(scriptName)
		     return xScript

Ejecución de secuencias de órdenes en Basic en LibreOffice

La documentación del Kit de desarrollo de software (SDK) de LibreOffice correspondiente a la interfaz com.sun.star.script.provider.XScript detalla la convención para efectuar llamadas entre lenguajes de programación. La invocación de funciones requere tres matrices:

Sintaxis de Python

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

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

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

Ejemplos de secuencias de órdenes personales y compartidas

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.


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,), (), ())

Ejemplos de secuencias de órdenes incrustadas en documentos

*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):
	      """Muestra las cadenas o expresiones numéricas especificadas en un cuadro de diálogo."""
	      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 '''
	      ' se aceptan todos los argumentos convertibles de CStr()
	      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()

¡Necesitamos su ayuda!