提问人:mutercim 提问时间:9/14/2023 更新时间:9/14/2023 访问量:35
一种在 libreoffice basic 中通过运行时代码添加子例程的方法
A way to add subroutines by code at runtime in libreoffice basic
问:
有没有办法在 libreoffice basic 中通过运行时通过代码添加/删除子例程或函数?
我非常希望能够在运行时通过代码创建、删除和运行子例程或函数。我正在考虑这是绕过 libreoffice-basic 中缺少接口(无法进行依赖关系反转)的一种方式。
答:
0赞
mutercim
9/14/2023
#1
感谢 JohnSUN。因此,似乎您可以使用字符串名称运行宏(尽管很难)。只需检查以下代码即可。
这是示例代码(太长,由您自行清理)
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 sufix="?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 & sufix
oScript = oScriptProvider.getScript(macroName)
runMacro = oScript.invoke(inpParams, aOutParamIndex, aOutParam)
Exit Function
NextIteration:
Next i
End Function
下面是调用的函数:
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
评论
0赞
JohnSUN
9/14/2023
不,我建议使用不同的代码。正如您所写的,如果所有函数都在一个模块中,程序将工作,否则将抛出错误。这就是为什么原始解决方案中的调用被移动到具有自己的本地错误处理程序的单独函数的原因。oScriptProvider.getScript(macroName)
评论