⟳ Automazione

Macro in LibreOffice: Basic, registratore e primi script

Macro in LibreOffice Calc e Writer: attivare il registratore, scrivere codice Basic leggibile, accedere a fogli e celle e gestire la sicurezza macro.

LibreOffice è molto diffuso in enti pubblici, scuole e piccole aziende che preferiscono un pacchetto libero e gratuito. Chi arriva da Excel cerca spesso le macro e scopre che esistono, ma funzionano in modo diverso: il linguaggio si chiama LibreOffice Basic e, pur somigliando a VBA, parla con il programma attraverso un'interfaccia propria chiamata UNO. Capire questa differenza evita molte frustrazioni.

Dove si trovano le macro

Tutto passa dal menu Strumenti > Macro. La voce Organizza macro > Basic apre l'elenco delle librerie, organizzate in tre luoghi:

  • Macro personali: salvate nel profilo utente, disponibili in qualunque documento aperto sul proprio computer;
  • Macro di LibreOffice: quelle fornite con il programma, in sola lettura;
  • singolo documento: la macro viaggia dentro il file .ods o .odt e funziona anche su altri computer.

Per uno strumento personale, come la formattazione di un report ricorrente, le macro personali sono la scelta più comoda. Per un modulo da distribuire ai colleghi conviene incorporarle nel documento.

Il registratore e i suoi limiti

Il registratore esiste, ma va attivato in Strumenti > Opzioni > LibreOffice > Avanzate, spuntando l'abilitazione della registrazione delle macro. Funziona solo in Calc e Writer. Dopo l'attivazione compare Strumenti > Macro > Registra macro.

Il codice prodotto, però, è poco leggibile. Ogni azione diventa una chiamata al «dispatcher» con un elenco di proprietà:

dispatcher.executeDispatch(document, ".uno:Bold", "", 0, Array())

È l'equivalente di premere un pulsante dell'interfaccia. Va bene per automazioni brevi, ma diventa difficile da modificare. Per qualsiasi macro che dovrà durare nel tempo conviene scrivere il codice usando direttamente gli oggetti del documento.

Accedere a fogli e celle in Calc

Il punto di partenza è ThisComponent, che rappresenta il documento attivo. Da lì si raggiungono i fogli e le celle:

Sub CompilaIntestazione
    Dim foglio As Object
    foglio = ThisComponent.Sheets.getByIndex(0)

    foglio.getCellRangeByName("A1").setString("Cliente")
    foglio.getCellRangeByName("B1").setString("Importo")
    foglio.getCellByPosition(2, 0).setString("Scadenza")
End Sub

Due dettagli da ricordare. getCellByPosition vuole prima la colonna e poi la riga, entrambe contate da zero: (2, 0) è la cella C1. E le celle distinguono tra tipi di contenuto: setString scrive testo, setValue scrive numeri, setFormula scrive formule in notazione inglese, per esempio =SUM(B2:B20) anche in una installazione italiana.

Un esempio completo: evidenziare le scadenze

Supponiamo di avere un elenco di fatture con la scadenza in colonna C e di voler colorare di rosso quelle già scadute.

Sub EvidenziaScadute
    Dim foglio As Object, cella As Object
    Dim riga As Long
    foglio = ThisComponent.Sheets.getByName("Fatture")
    riga = 1
    Do While foglio.getCellByPosition(0, riga).getString() <> ""
        cella = foglio.getCellByPosition(2, riga)
        If cella.getValue() < CDbl(Date) Then
            foglio.getCellRangeByPosition(0, riga, 2, riga).CellBackColor = RGB(255, 200, 200)
        End If
        riga = riga + 1
    Loop
End Sub

Il ciclo scorre le righe finché trova un nome cliente, quindi si adatta da solo alla lunghezza dell'elenco. Le date in Calc sono numeri, perciò il confronto con la data odierna convertita in numero funziona direttamente. Per un risultato del genere esiste anche la formattazione condizionale, che non richiede codice: la macro diventa preferibile quando la regola è più complessa o quando si vogliono svolgere più azioni insieme, come colorare, ordinare ed esportare in PDF.

Lavorare con Writer

In Writer il modello a oggetti è diverso: il documento ha un testo, il testo ha paragrafi e un cursore permette di muoversi e inserire contenuti. Un uso tipico è la sostituzione di segnaposto in un modello:

Sub SostituisciSegnaposto
    Dim cerca As Object
    cerca = ThisComponent.createReplaceDescriptor()
    cerca.SearchString = "{CLIENTE}"
    cerca.ReplaceString = "Rossi S.r.l."
    ThisComponent.replaceAll(cerca)
End Sub

Sicurezza delle macro

Come in ogni suite d'ufficio, le macro possono eseguire operazioni potenti. In Strumenti > Opzioni > LibreOffice > Sicurezza > Sicurezza macro si sceglie il livello. L'impostazione consigliata è quella che esegue senza chiedere solo le macro presenti in percorsi attendibili e chiede conferma per le altre. Le macro personali, conservate nel profilo, non sono soggette a questi avvisi. Un documento ricevuto da sconosciuti che contiene macro va aperto con le macro disattivate.

Basic, Python o altro?

LibreOffice supporta anche macro in Python, che usano la stessa interfaccia UNO. Per chi conosce già Python sono una buona alternativa, anche se l'editor integrato esiste solo per Basic e i file Python vanno messi a mano nella cartella del profilo. Nel mio lavoro uso Basic per piccole automazioni dentro il documento e Python esterno quando bisogna elaborare molti file insieme.

Esigenza Strumento consigliato
Ripetere pochi clic Registratore
Macro da mantenere nel tempo Basic con oggetti del documento
Elaborare decine di file Python esterno

In sintesi

  • Le macro di LibreOffice si gestiscono da Strumenti > Macro e possono stare nel profilo o nel documento.
  • Il registratore va abilitato nelle opzioni avanzate e produce codice basato sul dispatcher.
  • ThisComponent, getCellByPosition e getCellRangeByName sono la base per lavorare in Calc.
  • Righe e colonne si contano da zero, e la colonna viene prima della riga.
  • Impostate la sicurezza in modo da eseguire solo macro da percorsi attendibili.
MM
Marco Marzaduri

Marco Marzaduri si occupa di cybersecurity, informatica forense e sviluppo web. Laureato in informatica, unisce il rigore dell'analisi tecnica all'attenzione per le persone che usano la tecnologia.

Leggi anche