How can I call a Python macro in a cell formula in OpenOffice.Org Calc?

前端 未结 2 1249
南旧
南旧 2020-12-29 14:22

To extend OpenOffice\'s capabilities, I\'ve defined some Python macros in a file in the user script directory (~/Library/Application Support/OpenOffice.org/3/user/Scripts/py

2条回答
  •  被撕碎了的回忆
    2020-12-29 14:44

    On the old OO.org forums, (super)user Villeroy posted an illustration of how to call Python functions from OO.org Basic, which can then be used in formulae. The key is to use the com.sun.star.script.provider.MasterScriptProviderFactory service as a bridge. Here is an adaptation of his solution, generalized to call arbitrary functions in arbitrary modules:

    REM Keep a global reference to the ScriptProvider, since this stuff may be called many times: 
    Global g_MasterScriptProvider as Object
    REM Specify location of Python script, providing cell functions: 
    Const URL_Main as String = "vnd.sun.star.script:" 
    Const URL_Args as String = "?language=Python&location=user" 
    
    Function invokePyFunc(file AS String, func As String, args As Array, outIdxs As Array, outArgs As Array)
       sURL = URL_Main & file & ".py$" & func & URL_Args
       oMSP = getMasterScriptProvider()
       On Local Error GoTo ErrorHandler
          oScript = oMSP.getScript(sURL)
          invokePyFunc = oScript.invoke(args, outIdxs, outArgs)
          Exit Function
       ErrorHandler:
          Dim msg As String, toFix As String
          msg = Error$
          toFix = ""
          If 1 = Err AND InStr(Error$, "an error occurred during file opening") Then
             msg = "Couldn' open the script file."
             toFix = "Make sure the 'python' folder exists in the user's Scripts folder, and that the former contains " & file & ".py."
          End If
          MsgBox msg & chr(13) & toFix, 16, "Error " & Err & " calling " & func
    end Function
    
    Function getMasterScriptProvider() 
       if isNull(g_MasterScriptProvider) then 
          oMasterScriptProviderFactory = createUnoService("com.sun.star.script.provider.MasterScriptProviderFactory") 
          g_MasterScriptProvider = oMasterScriptProviderFactory.createScriptProvider("") 
       endif 
       getMasterScriptProvider = g_MasterScriptProvider
    End Function
    

    This can then be used to create a OO.org Basic function callable in a formula. Using the example pytype:

    Const libfile as String = "util"    REM functions live in util.py
    
    Function pytype(value)
        pytype = invokePyFunc(libfile, "pytype", Array(value), Array(), Array())
    End Function
    

    Another potential implementation is to create a Python add-in. However, this is a much heavier option as it requires installing the OpenOffice SDK, and it isn't obvious to me whether this approach would work for free functions or only works for classes.

提交回复
热议问题