Reputation: 31
Is there a way to add / delete subroutines or functions by code at runtime in libreoffice basic?
I would very like to be able to create, delete and run subroutines or functions by code at runtime. I am considering this is as a way to bypass the lack of interfaces (inability of dependency inversion) in libreoffice-basic.
Upvotes: 0
Views: 97
Reputation: 31
Thanks to JohnSUN. So it seems you can run a macro using a string name (although its hard). Just examine the following code.
Here is example code (too long, it is up to you to clean)
REM CALL A USER-DEFINED FUNCTION FROM AN ARBITRARY LIBRARY
REM Parameters:
REM funcName - string - name of the user-defined function
REM inpParams - an array of parameters passed to the function (can be empty)
REM libName - string - library Name (default "Standard")
REM In case of an error (no library, no function found, error in the function itself)
REM returns Nothing. Otherwise, the result of execution
REM custom function with the specified parameters.
REM Author: Vladyslav Orlov aka JohnSUN, Ukraine, Kyiv, 2011
REM mailto: [email protected]
Function runMacro(funcName As String, Optional inpParams As Variant, Optional libName)
Dim oScriptProvider As Object
Dim oLib As Object
Dim oScript As Object
Dim oModuleNames As Object
Dim i%
Dim aOutParamIndex(), aOutParam() ' Dummy arrays, read https://wiki.openoffice.org/wiki/Documentation/DevGuide/Scripting/Scripting_Framework_URI_Specification
Dim macroName As String
Const prefix="vnd.sun.star.script:"
Const suffix="?language=Basic&location=document"
runMacro = Nothing
If IsMissing(inpParams) Then inpParams = Array()
If Not IsArray(inpParams) Then inpParams = Array(inpParams)
If IsMissing(libName) Then libName = "Standard"
BasicLibraries.LoadLibrary(libName)
If NOT BasicLibraries.isLibraryLoaded(LibName) Then Exit Function
oLib = BasicLibraries.getByName(libName)
oScriptProvider = ThisComponent.ScriptProvider
oModuleNames = oLib.getElementNames()
On Local Error GOTO NextIteration
For i = LBound(oModuleNames) To UBound(oModuleNames)
macroName = prefix & libName & "." & oModuleNames(i) & "." & funcName & suffix
oScript = oScriptProvider.getScript(macroName)
runMacro = oScript.invoke(inpParams, aOutParamIndex, aOutParam)
Exit Function
NextIteration:
Next i
End Function
And below are the functions called:
REM Macros available for running:
Sub Main
display("dum", "Fn0")
display("dum", "Fn1")
End Sub
' FUNCTION USED
Sub display(sFuncName As String, Optional param)
msgbox (runMacro(sFuncName, param))
End Sub
Function dum(sFuncName As String) As String
dum = "This is DUM(" & sFuncName & "(0)) = " & runMacro(sFuncName, 0) & Chr(10) & _
"and is DUM(" & sFuncName & "(1)) = " & runMacro(sFuncName, 1)
End Function
Function Fn0(iVal As Integer) As String
Fn0 = "From Fn0 (" & iVal & ") "
End Function
Function Fn1(iVal As Integer) As Integer
Static add As Long
add = add + 5
Fn1 = iVal + add
End Function
Upvotes: 0