Quantcast
Channel: Apache OpenOffice Community Forum
Viewing all articles
Browse latest Browse all 1281

Macros and UNO API • Error trying to call a Python function in a script from LO Portable Calc Basic

$
0
0
Hi all, first post here. I'm in the process of translating an Excel spreadsheet with VBA macros to LibreOffice Calc. It's a circuit modeller (see https://www.diyaudio.com/community/thre ... el.420920/ if you're interested), a fellow Diyaudio forum member requested a LibreOffice version and, although I'd never used LibreOffice, I thought I'd give it a try, so I installed LibreOffice Portable and I managed to make it work. It was too slow to be usable though, so assuming it was a matter of the Calc interpreter having to translate everything from VBA to LO Basic on the fly, I did the translation myself with the help of ChatGPT. Again it works, but:

The problem: it's so slow compared to the Excel version as to be almost unusable. Clearly the issue is that there are lots of mathematical calculations performed each time the plots need to be updated, and the Basic interpreter, even in native form, is too slow. Access to cells and ranges is performed only once but the calculations are in a loop with ~200 elements. I've tried changing the loop size and, sure enough, the time it takes to update seems to be pretty much proportional to it.

A possible solution: to put the functions that perform the mathematical calculations in a Python script.

Note that all the functions that I want to put in Python will simply receive numerical arguments from Basic and return results to Basic, they don't need to access cells or ranges in the spreadsheet or anything else, I deal with all that in Basic.

Following ChatGPT's advice (which I'm fully aware some times is plain wrong, although so far for the VBA -> LO Basic translation it has been spot on), I've done the following:

1 - Just to try, I put one of the simplest functions (called CPar) in a Python script called MyCalculations.py and saved it to:
C:\Users\<myusername>\Documents\LibreOffice\App\libreoffice\share\Scripts\python
Where other Python scripts are stored, such as HelloWorld.py, which I've run and it works fine.

2 - Tried running CPar from Tools>Macros>Organize macros>Python. The function is found no problem and when I run it, as expected, I get the error "CPar() missing 2 required positional arguments: 'A' and 'B'", since CPar is expecting arguments and this test Run doesn't provide any.

3 - To see if I could call the function from within Basic passing the required arguments to it, I included this code generated by ChatGPT in my Basic module:

Function CallPythonFunction(funcName As String, args() As Variant) As Variant
Dim scriptProvider As Object
Dim script As Object

scriptProvider = ThisComponent.getScriptProvider()
script = scriptProvider.getScript("vnd.sun.star.script:MyCalculations." & funcName & "?language=Python&location=user")

' Pass arguments to the Python function
CallPythonFunction = script.invoke(Array(args), Array(), Array())
End Function

Sub TestCPar()
Dim WD1a(1) As Double, WD2a(1) As Double
Dim Zin As Variant

' Define example input data
WD1a(0) = 1: WD1a(1) = 2 ' Complex number: 1 + 2i
WD2a(0) = 3: WD2a(1) = 4 ' Complex number: 3 + 4i

' Call Python function
Zin = CallPythonFunction("CPar", Array(WD1a, WD2a))

' Display the result
MsgBox "Zin: " & Zin(0) & " + " & Zin(1) & "i"
End Sub

When I run TestCPar(), I get this error:

BASIC runtime error.
An exception occurred
Type: com.sun.star.script.provider.ScriptFrameworkErrorException
Message: <class 'pythonscript.com.sun.star.ucb.InteractiveAugmentedIOException'>: an error occurred during file opening
File "C:\Users\<username>\Documents\LibreOffice\App\libreoffice\program\pythonscript.py", line 1055, in getScript
mod = self.provCtx.getModuleByUrl( fileUri )
File "C:\Users\CC4\Documents\LibreOffice\App\libreoffice\program\pythonscript.py", line 469, in getModuleByUrl
lastRead = self.sfa.getDateTimeModified( url )
.

Since then I've been back and forth with ChatGPT to no avail. Aside from re-checking everything multiple times, the only alternative it proposed and I tried was to put location=shared instead of location=user in the call to scriptProvider.getScript, but I get exactly the same error. For the record, the file C:\Users\<username>\Documents\LibreOffice\App\libreoffice\program\pythonscript.py does exist, it was installed by LibreOffice so I assume it is as it should be. I can attach it if required.

If anyone can help, I'd be eternally grateful.

Cheers,

Cabirio

Statistics: Posted by Cabirio — Thu Dec 19, 2024 2:20 pm



Viewing all articles
Browse latest Browse all 1281

Trending Articles