Search code examples
pythonpython-3.xlibreoffice-calclibreoffice-basic

How to assign a 2d libreoffice calc named range to a python variable. Can do it in Libreoffice Basic


I can't seem to find a simple answer to the question. I have this successfully working in Libreoffice Basic:

NamedRange = ThisComponent.NamedRanges.getByName("transactions_detail")

RefCells = NamedRange.getReferredCells()

Set MainRange = RefCells.getDataArray()

Then I iterate over MainRange and pull out the rows I am interested in.

Can I do something similar in a python macro? Can I assign a 2d named range to a python variable or do I have to iterate over the range to assign the individual cells?

I am new to python but hope to convert my iteration intensive macro function to python in hopes of making it faster.

Any help would be much appreciated.

Thanks.


Solution

  • LibreOffice can be manipulated from Python with the library pyuno. The documentation of pyuno is unfortunately incomplete but going through this tutorial may help.

    To get started:

    Python-Uno, the library to communicate via Uno, is already in the LibreOffice Python’s path. To initialize your context, type the following lines in your python shell :

    import socket  # only needed on win32-OOo3.0.0
    import uno
    
    # get the uno component context from the PyUNO runtime
    localContext = uno.getComponentContext()
    
    # create the UnoUrlResolver
    resolver = localContext.ServiceManager.createInstanceWithContext(
                    "com.sun.star.bridge.UnoUrlResolver", localContext )
    
    # connect to the running office
    ctx = resolver.resolve( "uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext" )
    smgr = ctx.ServiceManager
    
    # get the central desktop object
    desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",ctx)
    
    # access the current writer document
    model = desktop.getCurrentComponent()
    

    Then to get a named range and access the data as an array, you can use the following methods:

    NamedRange = model.NamedRanges.getByName(“Test Name”)
    MainRange = NamedRange.getDataArray()
    

    However I am unsure that this will result in a noticeable preformance gain.