patricia
patricia

Reputation: 1103

Running Libreoffice BASIC macro from python

I've a macro in LibreOffice BASIC and I want to run it from my python program. I've found some threads in which they use this code:

import os
import win32com.client

if os.path.exists("excelsheet.xlsm"):
    xl=win32com.client.Dispatch("Excel.Application")
    xl.Workbooks.Open(Filename="C:\Full Location\To\excelsheet.xlsm", ReadOnly=1)
    xl.Application.Run("excelsheet.xlsm!modulename.macroname")
##    xl.Application.Save() # if you want to save then uncomment this line and change delete the ", ReadOnly=1" part from the open function.
    xl.Application.Quit() # Comment this out if your excel script closes
    del xl

But this is for windows Excell program and I want for the LibreOffice program. Is it possible to do this?

Thanks :)

Upvotes: 1

Views: 2755

Answers (1)

Jim K
Jim K

Reputation: 13790

My preferred way is to put the python script in the Scripts/python subfolder of your LibreOffice user directory. Then add this function at the bottom:

def call_basic_macro():
    document = XSCRIPTCONTEXT.getDocument()
    frame = document.getCurrentController().getFrame()
    ctx = XSCRIPTCONTEXT.getComponentContext()
    dispatcher = ctx.ServiceManager.createInstanceWithContext(
        'com.sun.star.frame.DispatchHelper', ctx)
    url = document.getURL()
    macro_call = ('macro:///Standard.Module1.Macro1("%s")' % url)
    dispatcher.executeDispatch(frame, macro_call, "", 0, ())

g_exported_scripts=call_basic_macro,

Now run the python script from Writer by going to Tools -> Macros -> Run Macro. Expand My Macros and select the name of the script.

Another way which seems closer to your Excel example is to start a listening instance of LibreOffice with a system call:

start soffice -accept=socket,host=0,port=2002;urp;

I typically do that part in a shell script (batch file on Windows) rather than python. Then in python, get the document context from the instance:

import uno
localContext = uno.getComponentContext()

After that, the code would look similar to what is above. Note that with this approach on Windows, the python.exe included with LibreOffice must be used in order to load the uno module.

A third way is to simply do a system call:

soffice "macro:///Standard.Module1.Macro1()"

For more on this third approach, see https://forum.openoffice.org/en/forum/viewtopic.php?f=20&t=8232.

Upvotes: 2

Related Questions