venerdì 3 settembre 2010
API - primi passi
martedì 31 agosto 2010
Lavorare con le tabelle di Calc
sUrl = "private:factory/scalc"
oDoc = StarDesktop.loadComponentFromURL(sUrl,"_default",0, Array())
Se si intende lavorare con il documento corrente invece:
oCalcDocument = StarDesktop.getCurrentComponent()
oCalcDocument = ThisComponent
oSheets = oCalcDocument.getSheets()
Come recuperare le singole tabelle:
Medante indice:
oCalcSheet = oSheets.getByIndex(0) ' forma equivalente abbreviata: oCalcSheet = oSheets(0)
- Mediante il nome:
oCalcSheet = oSheets.getByName("Tabella2") ' anche in questo caso esiste una forma equivalente abbreviata: oCalcSheet = oSheets("Tabella2")
Rinominare una tabella
oSheets("Tabella1").Name = "Nuovo nome"
Spostare una tabella:
'spostiamola dopo la terza tabella (all'ultima posizione) oSheets.moveByName( "Tabella1", 3)
Aggiungere una tabella:
Il metodo insertNewByName provvede a creare una nuova tabella e inserirla nella posizione specificata. Il metodo prende 2 argomenti: il nome della tabella da creare e la posizione di inserimento.oSheets.insertNewByName("Nuova Tabella",3)
Eliminare una tabella:
Questo metodo richiede un solo parametro: il nome della tabella da eliminare.oSheets.removeByName("Nuova Tabella")
Proteggere / sproteggere una tabella:
oSheets("Tabella1").protect("Password")
oSheets("Tabella1").unprotect("Password")Print "la tabella: " & oCalcSheet.Name & " è protetta!"
End If
Nascondere/mostrare una tabella:
Occorre ricordare che almeno una tabella deve essere sempre visibile, ovvero non è possibile nascondere tutte le tabelle' nasconde la tabella oSheets("Tabella1").IsVisible = False ' mostra la tabella oSheets("Tabella1").IsVisible = True
Contare le tabelle:
Print oSheets.getCount()
Enumerare le tabelle:
For I = 0 to oSheets.Count -1 oCalcSheet = oSheets.getByIndex(I) print oCalcSheet.Name Next I
For Each oCalcSheet In oSheets Print oCalcSheet.Name Next
Rendere attiva una tabella:
oView = oCalcDocument.getCurrentController() oCalcSheet = oSheets("Tabella2") oView.setActiveSheet(oCalcSheet)
venerdì 27 agosto 2010
OOoCon 2010 (remider!)
Quest'anno l'evento avrà luogo avrà luogo a Budapest in Ungheria, dal 31 Agosto al 3 Settembre.
Il PLIO sarà ben rappresentato, infatti tra i relatori figurano:
Italo Vignoli, presidente, con ben tre presentazioni:
- "Selling" the migration concept
- Marketing OOo in 2011 and beyond
- The state of the Italian National Language Project
| Wrap up of the latest Extensions infra structure features | di Juergen Schmidt |
| Using UNO AWT for creating GUIs in extensions | di Mihaela Kedikova |
| New Extensions in EuroOffice 2010 | di Kazmer Koleszar, Gergely Farkas |
| Extension Development for Non-programmers | di Dmitri Popov |
| VBA, can you hack it, yes you can!! | di Noel Thomas Power, Hui Li |
Bene, concludo con un in bocca al lupo ad Italo e Andrea e buon divertimento a chi ci sarà!!
a presto
Paolo
Scoprire il tipo del documento attivo
Dato che, a differenza di MS Office, OpenOffice.org è un'applicazione monolitica, il documento attivo può essere di qualunque tipo: un foglio elettronico, un database, un documento di testo e altro ancora.
Per questo motivo, sviluppando macro, capita abbastanza spesso di avere la necessità di sapere il tipo di documento attivo per poter applicare i metodi appropriati.
In MS Office esiste un programma eseguibile associato a ciascun tipo di documento, in OpenOffice.org invece esiste un componente specifico associato a ciascun tipo di documento, perciò la questione si riduce a conoscere il componente attivo piuttosto che il documento attivo.
I componenti sono dei servizi UNOi che hanno particolari caratteristiche. Senza volerci addentrare in dettagli, diciamo solo che i servizi UNO più complessi solitamente mettono a disposizione dei metodi specifici che permettono di identificare il servizio stesso e ottenere informazioni sulle caratteristiche supportate.
Vediamo ora i metodi più interessanti per il nostro utilizzo:
| Nome | Descrizione |
|---|---|
| getSupportedServiceNames() | Restituisce un array con i nomi di tutti i servizi UNO supportati dall'oggetto, incluso il servizio UNO principale. Questo metodo non prende argomenti |
| supportsService( String: ServiceName) | Controlla se un particolare servizio è supportato dall'oggetto. Il metodo prende in argomento il nome del servizio che si vuole testare e restituisce Vero (True) se il servizio è supportato, Falso (False) se il servizio non è supportato dall'oggetto. |
Vediamo ora come utilizzare quanto osservato fino ad ora per risolvere il problema iniziale, ovvero determinare il tipo di documento attivo.
Prima di tutto otteniamo un riferimento al documento attivo:
oDoc = StarDesktop.getCurrentComponent()Ora dobbiamo controllare se il componente attivo supporta alcuni servizi specifici che identificano univocamente il tipo di documento.
Per effettuare il test useremo il metodo supportsService
Ecco l'elenco dei nomi dei servizi UNO con il tipo di documento associato:
| Servizio UNO | Tipo di documento |
|---|---|
| com.sun.star.text.TextDocument | Documento di testo (Writer) |
| com.sun.star.text.WebDocument | Documento HTML (Writer) |
| com.sun.star.text.GlobalDocument | Documento Master (Writer) |
| com.sun.star.sheet.SpreadsheetDocument | Foglio elettronico (Calc) |
| com.sun.star.presentation.PresentationDocument | Presentazione (Impress) |
| com.sun.star.drawing.DrawingDocument | Disegno (Draw) |
| com.sun.star.formula.FormularProperties | Formula matematica (Math) |
| com.sun.star.sdb.OfficeDatabaseDocument | Documento database (Base) |
Non rimane altro che scrivere il codice che esegue materialmente il test:
REM ***** BASIC ***** Sub TestDocumentType()
oDoc = StarDesktop.getCurrentComponent() If oDoc.supportsService("com.sun.star.text.TextDocument") Then MsgBox "Documento di testo OOo Writer" ElseIf oDoc.supportsService("com.sun.star.text.WebDocument") Then MsgBox "Documento HTML di OOo Writer" ElseIf oDoc.supportsService("com.sun.star.text.GlobalDocument") Then MsgBox "Documento Master di OOo Writer" ElseIf oDoc.supportsService("com.sun.star.sheet.SpreadsheetDocument") Then MsgBox "Foglio elettronico di OOo Calc" ElseIf oDoc.supportsService("com.sun.star.drawing.DrawingDocument") Then MsgBox "Disegno di OOo Draw" ElseIf oDoc.supportsService("com.sun.star.presentation.PresentationDocument") Then MsgBox "Presentazione di OOo Impress" ElseIf oDoc.supportsService("com.sun.star.formula.FormulaProperties") Then MsgBox "Formula matematica di OOo Math" ElseIf oDoc.supportsService("com.sun.star.sdb.OfficeDatabaseDocument") Then MsgBox "Documento database di OOo Base" End If End Sub
Per testare il codice è sufficiente copiarlo in nuovo modulo nella libreria Standard del proprio utente, creare un nuovo documento di qualsiasi tipo, tornare nell ambiente di sviluppo (IDE) di StarBasic e lanciare la macro mediante l'apposito pulanste della barra degli strumenti oppure mediante il tasto Per un uso più generalizzato sarebbe opportuno trasformare la routine dell'esempio in una funzione.
Effettivamente esiste già una funzione simile nella libreria Tools, modulo Misc:
Si tratta della funzione GetDocumentType().
Ecco come utilizzarla:
REM ***** BASIC ***** Sub TestToolsFunction() oDoc = StarDesktop.getCurrentComponent() 'prima di utilizzar el efunzioi della libreria 'condivisa Tools occorre caricarla: BasicLibraries.loadLibrary.Tools 'ora è possibile richiamare la funzione sDocType = GetDocumentType(oDoc) MsgBox sDocType End Sub
La funzione inclusa nella libreria Tools purtroppo non è molto aggiornata e non è in grado di riconoscere i documenti OOo Base, i documenti HTML e i documenti MasterAlla luce di quanto illustrato fino ad ora dovrebbe essere piuttosto facile modificare la funzione della libreria Tools aggiungendo i tipi di documento mancanti.
A presto
Paolo
sabato 21 agosto 2010
Ecco il sito di un vero appassionato di MACRO e API !!
Vi prego non fatemela spiegare ;-)
Comunque posso assicurare che Luca Mazzocchi, autore del sito, non solo è un grande esperto di macrofotografia e profondo conoscitore del mondo dell'apicoltura ma è anche un programmatore di Macro e API di OpenOffice.org. :-)
sabato 10 ottobre 2009
Conta cellule
Ma vediamo in dettaglio cosa dice l'amico Torakiki78:
Sto cercando di fare un file con openoffice calc che mi serve per
contare delle cellule... ecco come dovrebbe essere:
la conta è di 100 cellule in tutto e di ciascuna devo segnalare se
è mobile, poco mobile o immobile. Premendo 1, la cellula è mobile.
Premendo 2 la cellula è poco mobile. Premendo 3 la cellula è
immobile.
Ho fatto un file (che se volete posto...) con openoffice calc in
cui segno per ogni cella (dalla A4 alla A104) premendo 1,2 oppure 3 e
poi invio per passare alla cella successiva (cioè quella sotto).
Le mie richieste sono:
Vorrei poter premere 1, 2 o 3 e SENZA dover premere invio poter
passare alla cella sotto. In più vorrei che quando arrivo alla
cella A54 poter sentire un suono che mi avvisa che sono arrivato a
contare 50 cellule.
Vorrei anche che, se premo 4 o 5 o 9 (o comunque un numero diverso
da 1,2,3), che non venisse segnalato....
Non so usare le macro, e un pochino le funzioni....
Mi potete aiutare?
E come no! Siamo qui per questo :-)
Dunque, prima di procedere però, cito la risposta di Roberto Montaruli:
Il tuo e' un problema di interfaccia, non di applicazione.
Tu vuoi una interfaccia utente su misura.
Richiesta rispettabilissima.
Ma Calc non e' una applicazione di interfaccia, e' un gestore di
foglio elettronico.
Gestisce i dati, non l'input degli stessi.
In effetti la risposta di Roberto è molto sensata, probabilmente con un piccolo programma standalone si potrebbe raccogliere l'input per poi salvarlo ad esempio in un file CSV.
In ogni caso, OpenOffice.org dispone di tutti i mezzi per costruire la piccola interfaccia di cui abbiamo bisogno in modo abbastanza pulito.
Per cominciare ci serve almeno una rudimentale specifica:
Specifica di progetto
L'idea a grandi linee è la seguente:
una finestra di dialogo modale con un campo di testo che riceverà l'input
ogni volta che l'utente premerà un tasto, se il tasto corrisponde a 1 o 2 o 3 il valore verrà “appeso” ad un vettore, diversamente il valore verrà rigettato
Una variabile numerica terrà il conto di quanti inserimenti sono stati fatti, il valore attuale verrà mostrato nel dialogo mediante un controllo “testo fisso”
Al cinquantesimo inserimento verrà emesso un beep mentre al centesimo, doppio beep e uscita dal dialogo.
All'uscita provvederemo a creare un nuovo documento Calc e a trasferire i valori conservati nel vettore.
Naturalmente tutto il progetto sarà impacchettato come extension. Nell extension verrà inserita anche una piccola barra degli strumenti con un solo pulsante che servirà per lanciare il dialogo.
Preparazione ambiente
Per prima cosa occorre creare una nuova libreria macro condivisa che chiameremo “ContaCellule”
Design del dialogo
Ora passiamo a disegnare il dialogo come segue:
Il dialogo si chiamerà DlgContaCellule
Il controllo in alto è un fixed text che ho chiamato lblCount, mentre quello sottostante è un text edit che ho chiamato txtInput
Per essere sicuri che all'apertura del dialogo il focus (e quindi l'input dell'utente) sia immediatamente dirottato su txtInput occorre impostare la proprietà sequenza = 0
Come ulteriore precauzione, tutti i rimanenti controlli avranno la proprietà Tabstop = No
Questo impedirà loro di ricevere il focus quando si preme il tasto tabulazione.
Altri accorgimenti:
Pulsante OK : impostare la proprietà Abilitato = No e la proprietà Tipo di pulsante = OK
Pulsante Annulla : impostare la proprietà Tipo di pulsante = Annulla
Eventi
Ora dobbiamo creare la procedura che verrà usata per intercettare l'input dell'utente.
Sub txtInput_KeyPressed(oEvt)
End Sub
Questa procedura dovrà essere collegata all'evento Tasto premuto del controllo txtInput
Mostrare il dialogo
Ora aggiungiamo il codice per mostrare il dialogo:
REM ***** BASIC *****
Private oDlg As Object
'_____________________________________________________________________________
Sub ShowDialog
DialogLibraries.loadLibrary("ContaCellule")
oDlg = CreateUnoDialog(DialogLibraries.ContaCellule.DlgContaCellule)
'initialize controls
oDlg.Model.txtInput.Text = ""
oDlg.Model.lblCount.Label = ""
IDlgResult = oDlg.execute()
If iDlgResult = 1 Then
'user pressed OK
'
'
'
'
End If
End Sub
Ovviamente il codice è ancora incompleto.
Manca infatti la gestione dell'evento key pressed ed inoltre occorre conservare i dati inseriti per poi riversarli opportunamente in un documento Calc
Codice completo
Ecco il codice completo:
REM ***** BASIC *****
Private oDlg As Object
Private iCount As Integer
Private mValues()
'_____________________________________________________________________________
Sub ShowDialog
DialogLibraries.loadLibrary("ContaCellule")
oDlg = CreateUnoDialog(DialogLibraries.ContaCellule.DlgContaCellule)
'initialize controls
oDlg.Model.txtInput.Text = ""
oDlg.Model.lblCount.Label = ""
IDlgResult = oDlg.execute()
If iDlgResult = 1 Then
'user pressed OK
'create a new Calc doc
sUrl = "private:factory/scalc"
oDoc = StarDesktop.LoadComponentFromURL(sUrl,"_default",0, Array())
oSheet = oDoc.Sheets(0)
'put the data in the column A starting from row 4
For I = LBound(mValues()) To UBound(mValues())
iRow = I + 3
oCell = oSheet.getCellByPosition(0, iRow)
oCell.FormulaLocal = mValues(I)
Next I
End If
End Sub
'_____________________________________________________________________________
Sub txtInput_KeyPressed(oEvt)
Dim sChar As String
sChar = oEvt.KeyChar
If (sChar = "1") Or (sChar = "2") Or (sChar = "3") Then
If iCount < 100 Then
'store the data
AppendItem(mValues(), sChar)
'update the control content
Select Case sChar
Case "1" : oEvt.Source.Text = "Mobile"
Case "2" : oEvt.Source.Text = "Poco mobile"
Case "3" : oEvt.Source.Text = "Immobile"
End Select
'beep when 50th data has been inserted
If iCount = 49 Then
Beep
End If
iCount = iCount + 1
oDlg.Model.lblCount.Label = iCount
Else
oEvt.Source.Text = "Fine!!"
'enable the OK button and alert the user that the end is reached
oDlg.Model.cmdOk.Enabled = True
Beep
Wait 200
Beep
Wait 200
Beep
End If
Else
'invalid input
oEvt.Source.Text = "-N/A-"
End If
End Sub
'_____________________________________________________________________________
Sub AppendItem(mList(), vItem)
Dim iMax As Long
iMax = UBound(mList())
iMax = iMax + 1
Redim Preserve mList(iMax)
mList(iMax) = vItem
End Sub
Impacchettamento e distribuzione
Non rimane altro che confezionare la nostra mini applicazione.
Usando l'extension BasicAddonBuilder , in pochi passaggi è possibile esportare la libreria appena creata come extension:
Passaggio 1: Selezione libreria
Passaggio 2: Opzioni generali
Passaggio 3: Definizione della barra degli strumenti
Aggiungendo un nuovo pulsante nella barra, nel dialogo delle proprietà sarà possibile definire il comando assegnato (che nel nostro caso sarà la macro ShowDialog ) e altre caratteristiche come ad esempio l'icona, o il contesto che indica semplicemente in quali componenti di OpenOffice.org sarà visibile il nuovo pulsante.
Passaggi conclusivi
Nei passaggi successivi è possibile indicare ulteriori caratteristiche come ad esempio la licenza, il numero di versione, un testo descrittivo. Ecc.
In ultimo verrà chiesto di indicare un percorso per salvare la nuova extension nel proprio disco fisso.
L'extension così creata sarà installabile in qualsiasi PC ove sia presente OpenOffice.org
Per i più pigri, l'extension già assemblata è disponibile qui:
http://www.paolo-mantovani.org/downloads/ContaCellule/
A presto!
martedì 9 giugno 2009
BasicAddonBuilder: problemi con OOo3.1 su Mac OS X
Pare che BasicAddonBuilder abbia un problema con OpenOffice.org 3.1 su Mac OS X 10.5.7 (Intel)
Un utente tedesco mi segnala infatti che da quando ha aggiornato OpenOffice.org all'ultima versione 3.1, non riesce più ad utilizzare BasicAddonBuilder, ottenendo strani errori.
L'extension peraltro aveva sempre funzionato bene fino alla penultima 3.0
L'errore avviene in corrispondenza di questo codice:
Modulo: DlgWizard_mainL'ultima linea è quella che solleva l'errore.
-----------------------
Sub Dialog_Initialize
Dim oBasicProvider As Object
Dim oBasicLibrary As Object
Dim mNameList()
Dim sPkgDesc As String
'setup the objects in the dialog
'general controls (step 0)
'setup the Roadmap control
'(the "navigation panel" on the left of the dialog)
InitializeRoadmap
'step 01 controls
With g_oDlgWizardModel
.lstBasicLibraryContainers.StringItemList = GetProviderUINames()
.lstBasicLibraryContainers.SelectedItems = (Array(0))
oBasicProvider = g_mBasicProviders(0).Provider
Ecco uno screenshot che mostra il messaggio di errore:
Beh, ora il difficile è scoprire il motivo. Purtroppo non ho a disposizione un Mac per fare delle prove, perciò si accettano idee :-)
Alla prossima.














