Ask Your Question
1

Execute a Python Macro (Function) From Base and Return Value to Base

asked 2015-06-20 18:43:07 +0100

Steve R. gravatar image

updated 2015-08-23 07:43:04 +0100

Alex Kemp gravatar image

Is it possible to have a python script return a value to LibreOffice Basic function when executed from Base? I am using Ubuntu 14.04 with LibreOffice 4.4.3.2.

For Example- In Base I call the function below with: " If TableExists(strUSBTableName) Then ..."

Function TableExists(strTableName As String) As Boolean
    rem http://www.access2base.com/access2base.html
    Dim odbDatabase As Object    
    Set odbDatabase = Application.CurrentDb()         
    Dim i As Integer   
    docmd.runCommand("DBRefreshTables")            
        TableExists = False  
        With odbDatabase    
            For i = 0 To .TableDefs().Count - 1         
                If strTableName = .TableDefs(i).Name Then               
                    TableExists = True
                    Exit For
                End If
            Next i      
        End With    
        Exit Function
    End Function

Can a Python script be used in the code above instead of Basic? I suspect that it won't really be a direct substitution.

Function TableExists(strTableName As String) As Boolean
            *** Some python script in here ***
            *** Return Some Value to Base (basic) ***
 End Function
edit retag flag offensive close merge delete

Comments

Hi - Just a complement to the very good response from @doug (as usual). Your question is broader, but you can replace this particular procedure by:

Function TableExists(strTableName As String) As Boolean

TableExists = ThisDataBaseDocument.DataSource.Tables.hasByName(strTableName)

End function

Regards

pierre-yves samyn gravatar imagepierre-yves samyn ( 2015-07-26 08:02:17 +0100 )edit

Thanks for contributing. My knowledge of uno Basic is minimal at best. In this particular case, it appears that I have to use Python to retrieve available disk space since uno Basic can't do that. The response by @doug appears to do that.

Steve R. gravatar imageSteve R. ( 2015-07-27 02:28:45 +0100 )edit

2 Answers

Sort by » oldest newest most voted
1

answered 2015-07-26 02:49:50 +0100

doug gravatar image

The way to do this is to call a macro using the UNO construct getScript(sScriptURI) and then call the invoke method for the object. That is the easy part. The hard part is figuring out the sScriptURI, which is a universal location for the script. There is a paucity of documentation about what, exactly, this is.

By trial and error you may find that a sScriptURI for a Basic macro looks like this:

"vnd.sun.star.script:Standard.Module1.SubName?language=Basic&location=application"

You can see the different elements. By further trial and error, you may find that a Python macro call_me.py with a method of the same name (call_me) saved in the following location:

/home/user/.config/libreoffice/{LOversionnumber}/user/Scripts/python/

Is accessible as follows:

"vnd.sun.star.script:call_me.py$call_me?language=Python&location=user"

Thus, if I have the following Python macro at the above location saved as call_me.py:

def call_me(*args ):
    return "call me"

Then if I invoke the following in Basic, it will return to the Basic macro the value set forth in the Python macro ("call me"):

Dim a(0),b(0),c(0) As Variant
scpr = ThisComponent.getScriptProvider
scmod = scpr.getScript("vnd.sun.star.script:call_me.py$call_me?language=Python&location=user")

returnFromPython = scmod.invoke(a,b,c)
MsgBox returnFromPython

location=share also is a valid location, I think, depending on where, exactly, the script is saved. For documentation of what are the arrays a, b, c, see the API reference. To make your Python macro work, you may need to redefine those.

(if this answers your question, please accept the answer by clicking the check mark (image description) to the left)

edit flag offensive delete link more

Comments

This appears to answer the question. The logic looks correct. My knowledge of uno Basic is minimal. It's going to take me a while to parse through this. I hope that others will find your solution useful too. Thanks

Steve R. gravatar imageSteve R. ( 2015-07-27 02:21:50 +0100 )edit
2

answered 2015-07-31 17:32:16 +0100

Steve R. gravatar image

updated 2015-08-11 19:21:55 +0100

The "real" answer is the answer posted by Doug above. The purpose of this response is to show rudimentary code that functions based on the advice provided by Doug. While the code below works, modifications to the basic code structure have tended to fail. As the rudimentary minimally altered code works, these shortcomings can eventually be overcome through further research and trial and error. For now, this is usable code for conducting further experimentation.

Uno Basic function below:

Function dblTestPython(dblValue) As Double
        On Error Goto HandleError1001 
        dim a(0), b(0), c(0) as variant 
        a(0)= Forms("MainForm").Controls("Field1").value
        scpr = ThisComponent.getScriptProvider
        scmod = scpr.getScript("vnd.sun.star.script:call_me.py$call_me?language=Python&location=user")
        returnFromPython = scmod.invoke(a,b,c)
        print returnFromPython      
        Exit Function
    HandleError1001:
        resume next
End Function

Python script invoked by the Basic function above:

import os
def call_me(a):
    z = int(a) * 5 
    return z
edit flag offensive delete link more

Comments

Since posting, I ran across this web-page: Transfer from Basic to Python.

Steve R. gravatar imageSteve R. ( 2015-08-09 00:04:33 +0100 )edit
Login/Signup to Answer

Question Tools

1 follower

Stats

Asked: 2015-06-20 18:43:07 +0100

Seen: 3,343 times

Last updated: Aug 11 '15