Richiamare macro Basic da Python

È possibile richiamare LibreOffice macro Basic da script Python e si possono ottenere funzioni degne di nota, come ad esempio:

L'API (Application Programming Interface) Scripting Framework di LibreOffice supporta l'esecuzione di script tra linguaggi Python e Basic o altri linguaggi di programmazione supportati. Gli argomenti possono essere passati avanti e indietro tra le chiamate, a condizione che rappresentino tipi di dati primitivi riconosciuti da entrambi i linguaggi e che la Scripting Framework li converta in modo appropriato.

tip

È consigliabile disporre di una certa conoscenza dei moduli standard Python e delle caratteristiche delle API LibreOffice prima di eseguire funzioni di chiamata tra linguaggi Basic, Python, JavaScript o qualsiasi altro motore di script.


warning

Durante l'esecuzione di script Python da un ambiente di sviluppo integrato (IDE), il motore Basic LibreOffice nidificato può non essere presente. In tale contesto occorre evitare di eseguire chiamate da Python a LibreOffice Basic, anche se l'ambiente Python e gli Universal Networks Objects (UNO) sono totalmente disponibili. Fate riferimento a Configurazione di un ambiente di sviluppo integrato (IDE, Integrated Development Environment) per Python per ulteriori informazioni.


Richiamare script LibreOffice Basic

Le macro LibreOffice Basic possono essere personali, condivise o incorporate nei documenti. Per poterle eseguire Python deve disporre della posizione delle macro Basic. L'implementazione dell'interfaccia com.sun.star.script.provider.XScriptProvider consente il recupero di script eseguibili:


		 import uno
		 from com.sun.star.script.provider import Xscript
		     
		 def getBasicScript(macro='Main', module='Module1', library='Standard',
		         isEmbedded=False) -> XScript:
		     '''Prende l'oggetto script Basic prima di invocare.'''
		     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
		 

Eseguire script LibreOffice Basic

La documentazione LibreOffice Software Development Kit (SDK) per l'interfaccia com.sun.star.script.provider.XScript specifica la convenzione per le chiamate tra linguaggi. L'invocazione delle funzioni richiede tre matrici:

Sintassi Python

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

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

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

Esempi di script personali o condivisi

Esempi contenuti in Input/output su schermo specificano le chiamate da Python a Basic. Monitoraggio degli eventi del documento illustra l'uso del parametro *args dell'idioma Python per stampare un numero variabile di parametri nella finestra di dialogo della console di registro Access2Base.

tip

Al momento dello sviluppo è possibile interrompere l'esecuzione dello script Python tramite l'estensione Xray per esaminare le proprietà e i metodi degli oggetti UNO. Il debugger dell'estensione APSO consente l'introspezione degli oggetti attraverso l'uso delle estensioni Xray e MRI.



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

Esempi di script incorporati nei documenti

La sintassi semplificata *args di Python può essere impiegata in combinazione con le routine LibreOffice Basic che accettino un numero variabile di argomenti. Le seguenti funzioni di Python Print, e SUM richiamano le corrispondenti controparti Basic Print e SUM mediante la funzione getBasicScript precedentemente menzionata. La gestione delle eccezioni non è specificata dettagliatamente.


	  # -*- coding: utf-8 -*-
	  from __future__ import unicode_literals
	      
	  def Print(*args):
	      """Restituisce le stringhe specificate o le espressioni numeriche in un riquadro di dialogo."""
	      xScript = getBasicScript("Print", "Scripting", embedded=True)
	      xScript.invoke((args), (), ())
	      
	  def SUM(*args):
	      """SUM l'espressione numerica specificata."""
	      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,)
	  

Le routine LibreOffice Basic Print e SUM basate su documenti accettano un numero variabile di argomenti. Gli attributi Private o Public sono privi di effetto. Il controllo del tipo di argomento viene tralasciato per chiarezza.


	  Option Compatible ' "Standard.Scripting" module
	  Option Explicit
	      
	  Private Sub Print(ParamArray args() As Variant, Optional sep As String = " ")
	      ''' Stampa elenco di voci in numero variabile'''
	      ' si accettano tutti gli argomenti convertibili di 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 un elenco variabile di numeri '''
	      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()
	  

Sosteneteci!