How can I catch edited worksheet cell in python macro

Hi there. A Libre Worksheet has event “Content changed” and it works, but how can I catch which cells or range (maybe copied or inserted) has been modified?

Inspect the parameter that is passed over to your routine.

As @Villeroy already said…
https://ask.libreoffice.org/t/how-can-i-reach-dialog-elements-from-python-macro/125933/6?u=karolus

This is for just one cell.

from Dialogos import MBInfo
def EndCelAtualizada2(evt):
    doc = XSCRIPTCONTEXT.getDocument()
    if evt.ImplementationName == "ScCellObj":
        # make "A1" form of updated cell:
        A1 = chr(65 + evt.CellAddress.Column) + str(evt.CellAddress.Row + 1)         
        MBInfo(XSCRIPTCONTEXT.getComponentContext(), f'Updated cell is {A1}')
    return None

evt.AbsoluteName will do.

  • could be written as:
A1 = f"{65+evt.CellAddress.Column:c}{evt.CellAddress.Row + 1}"
  • »A1« is a bad name, may you should use »cell_name« instead!
  • but anyway it will return nonsense for any Cell beyond Column Z

so you should simply use:

cell_name = evt.AbsoluteName.split('.')[-1].replace('$','')

This was adapted from a code I have here.
For Range I think it’s it:

def EndRangeAtualizado(evt):
    MBInfo(XSCRIPTCONTEXT.getComponentContext(), str(evt.ImplementationName))
    if evt.ImplementationName == "ScCellRangeObj":
        MBInfo(XSCRIPTCONTEXT.getComponentContext(), str(evt.AbsoluteName))
        sc = evt.RangeAddress.StartColumn
        sr = evt.RangeAddress.StartRow
        ec = evt.RangeAddress.EndColumn
        er = evt.RangeAddress.EndRow
        area = f'(COLUMN, ROW)\n({sc}, {sr})\n({ec}, {er})'         
        MBInfo(XSCRIPTCONTEXT.getComponentContext(), area)
    return None    
   
1 Like

I saw it somewhere to (of course) differentiate from R1C1 notation.

Its the very same as in my comment above https://ask.libreoffice.org/t/how-can-i-catch-edited-worksheet-cell-in-python-macro/126119/6?u=karolus

:+1:
So this is the code for both Cell and Range:

import uno
from Dialogos import MBInfo
def EndRangeAtualizado(evt):
    cell_name = evt.AbsoluteName.split('.')[-1].replace('$','')
    MBInfo(XSCRIPTCONTEXT.getComponentContext(), cell_name)        
    return None   

no need for explizit »return None« in the last line,

Yes, I know: habit of mine.
But thank you anyway :+1:

Thanks, now I can use the modified range. But I can’t clearly understand, how to inspect evt object and debug the process fired with event? (It’s clear If I start a sub). For example now I need to highlight modified rows with some color. Of course I can take getActiveSheet() and get rows by index

def changed(event):
    event.Rows.CellBackColor = int("FF0000", 16)# yes, its red

Yeah … thats rocket science - isnt it? :rofl: :rofl:

1 Like

?

???
2025-09-03-130552_663x173_scrot

Color is mine.
But yes, now are requested the rows, not the range.
Sorry!

An alternative for the modified Range, with explicit function:

import uno
from Dialogos import MBInfo
def HUR(celulas, hcolor):
    doc = XSCRIPTCONTEXT.getDocument()
    p = doc.getCurrentController().getActiveSheet()
    rg = p.getCellRangeByName(celulas)
    rg.CellBackColor = hcolor
    return None
def EndRangeAtualizado(evt):
    an = evt.AbsoluteName
    cell_name = an.split('.')[-1].replace('$','')
    MBInfo(XSCRIPTCONTEXT.getComponentContext(), f'Event Absolute Name {an}\nRange {cell_name}')
    HUR(cell_name, 0xF5E162)
    return None
g_exportedScripts = EndRangeAtualizado,
1 Like

yes explicit function, but why not simply:

def HUR( celulas, hcolor):
    celulas.CellBackColor = hcolor
### and call it like:
…
…
   HUR(evt ,   0xF5E162 )
1 Like

Sure, as of course celulas is already the object, so no need to set references :+1: