Detailed tutorial regarding LibreOffice to Python macro writing, especially for Calc

@flywire:
Some examples exactly for: NOT howto do
https://tutolibro.tech/2021/05/07/python-libreoffice-reverse-the-order-of-cells-content-from-a-cell-range/

data = (2,1,3)
output = tuple(entry for entry in reversed(data)) #no, no ,no!
# use simply:
output = tuple( reversed(data))
1 Like

@karolus Why don’t you post that comment on the blog where people will see it, and hopefully the author might fix it?

Edit: OK I understand from your comment below comments aren’t displayed until accepted.

@karolus Why don’t you post that comment on the blog where people will see it, and hopefully the author might fix it?

@flywire: thats already done!

1 Like

The AUTHOR doesnt fix, but he dont accept my comment, what an ignoramus!

Yes, my comments were ignored too. Blogs not being maintained is a common problem. LibreOffice needs basic tutorials like these in it’s own docs. At least the blogger made the source code freely available for the examples in the last half of those tutorials.

I’ve been working on docs suffering from perfection as the enemy of good. I should just make it available.

Good to see Blogger has processed comments now.

For someone who is familiar with Python, you can easily paste StarBasic code into your Python module and adjust the syntax line by line IF the code mainly consists of calls to the UNO-API. Apart from the language syntax you have to take care of:

  • declaration of constants: MyDT = com.sun.star.util.DateTime vs. from com.sun.star.util import DateTime AS MyDT
  • ThisComponent vs. XSCRIPTCONTEXT.getDocument()
  • Several other convenient Basic definitions, mainly StarDesktop and createUnoService, need to be instanciated from uno.ComponentContext.ServiceManager. def createUnoStruct can be found in the uno module.
  • Since you know Python, you will easily spot the routines where Basic code tries to manipulate strings and arrays. You can drop them alltogether and use some Python basics instead.

Macro code is stored globally or embedded in documents. In the macro organizer the global ones appear under “My Macros”, the embedded ones appear under the name of the loaded document.
A completely different thing is extension development. Extensions add new services to the office suite. Extensions do not appear in the macro organizer unless the extension distributes macros.

  • The single most important extension you need for any kind of UNO programming is MRI:
    [Tutorial] Introduction into object inspection with MRI This is also a great example for a powerfull extension which also adds a small macro library in StarBasic for convenience.
  • A convenient extension for Python macros is the "Alternative Script Organizer for Python (APSO). It allows to open macro code with your favourite editor. It can also embed code into a document without touching the document’s XML code.

Translate StarBasic as you go is about as good as the alternatives. When you look at https://pitonyak.org/OOME_3_0.pdf the offerings for the community to learn python macros are pretty pathetic. Kudos to those that have made the effort to offer what they can.

Python as an alternative macro language is an offering for those who are familiar with that language. What I tried to point out was that both macro languages are not that different in respect to UNO calls.
Whatever you prefer, a good overview on UNO concepts (frame->view->model, service, interface, types) together with MRI is vital.
StarBasic is not an option when it comes to extension development unless your extension is just a macro library.

I needed to write an excel macro and although I didn’t know VBA I didn’t need to know it to use the resources to learn it. It’s unreasonable to need to know python before you can use it to develop LO macros but that is the way it is presented to the community. That’s not the case with the StarBasic document I linked.

Agree all languages would use the same UNO calls and although the syntax varies an example from one language is useful in another, it’s just harder to understand when you have to translate it.

It depends. IIRC, XRay was a Basic extension; so is AltSearch, and I suppose that 90%+ in our extensions repo are Basic.

(A hint: I don’t know if you intended to write an answer, or just to continue comment thread, so just in case, because it’s often not convenient to find the button to post a comment: if you want to answer another’s comment, you may select some part of it, and get a “Quote” popup button, allowing you to start another comment.)

1 Like

@mikekaganski

X-ray and AltSearch are macro libraries. We can distribute macro libraries by means of extension packages. Such packages install macro code without adding new UNO services.

Interesting, I wasn’t aware of this distinction. Let me see if I understand what you are saying. For example, my extension (primarily written in python) contains lines such as the following.

class InterlinSettingsJob(JobWrapper):
    def __init__(self, ctx):
        JobWrapper.__init__(self, ctx)

    def showDialog(self):
        from lingt.ui.comp.interlinsettings import showDlg
        showDlg(self.ctx)

g_ImplementationHelper.addImplementation(
    InterlinSettingsJob,
    "name.JimK.LinguisticTools.InterlinSettings",
    ("com.sun.star.task.Job",),)

This is referenced in my Addons.xcu for a menu entry:

<value>service:name.JimK.LinguisticTools.InterlinSettings?execute</value>

Is that the kind of service you were talking about, and are you saying that this wouldn’t work for Basic?

My extension does have some Basic code as well but it gets called differently. Looking back through the code, one way that Basic gets called is by using macro:/// syntax with the dispatcher. Another way is by creating buttons dynamically that are assigned to Basic macros. In both cases, the Basic code is stored in a library in the extension, not given an implementation or service name or anything.

Yes, exactly. And no, we can’t write such services in StarBasic. There are quite powerful StarBasic extensions, most prominently XRay. They consist of macro code that is visible in the macro organizer and some UI elements calling some entry routines. Your Python class will not appear in any macro library. It constitutes an UNO service which is callable as a “Job”.
Related topic: Create APSO Toolbar Icon - #8 by flywire

Makes sense. That’s why calling Xray looks different from MRI. Again from my extension:

mspf = unoObjs.smgr.createInstanceWithContext(
    "com.sun.star.script.provider.MasterScriptProviderFactory",
    unoObjs.ctx)
scriptPro = mspf.createScriptProvider("")
try:
    xScript = scriptPro.getScript(
        "vnd.sun.star.script:XrayTool._Main.Xray?" +
        "language=Basic&location=application")
except:
    raise RuntimeException(
        "\nBasic library Xray is not installed", unoObjs.ctx)
xScript.invoke((myObject,), (), ())

...

mri_obj = unoObjs.ctx.ServiceManager.createInstanceWithContext(
    "mytools.Mri", unoObjs.ctx)
mri_obj.inspect(target)

I have started the Python tutorial series for Macros. Here’s a simple and detailed guide on how to start your Python macro journey (both Linux and Windows):

You don’t need to install Python on Windows in or der to run or write macros. LO comes with its own Python runtime C:\Program Files\LibreOffice\program\python.exe which is installed by default unless you have chosen otherwise in a custom installation.

AFAIK, there’s no way to avoid Python installation on Windows, even using custom option…

but I think you refer to the install of the python LibreOffice includes in its own installation. @Villeroy refers to the sentence in the tutorial

Windows users need to install Python in their system and LibreOffice as well.

and installing a second “external” python-interpreter is not necessary to run macros in LibreOffice.
.
In a first steps guide it is simply wrong without explanation, as it will provoke the situation where one complains of modules not found in LibreOffice-pythons after installing them in the other version…

I am not convinced that I misinterpreted the phrase :wink: