Aus Linux-Magazin 05/2002

Tipps zur Programmierung von Star Office 6, die wirklich helfen

Die Entwicklung von leistungsfähigen Star-Office-6-Makros droht an Suns unzureichender Programm- Dokumentation zu scheitern. Unsere Tipps für VBA- und andere an Objekten orientierten Basic-Aktivisten erleichtern den Ein- und Umstieg.

Wer als VBA-Entwickler beispielsweise Makros für Microsoft Word entwickelt, sieht sich mit einem geschlossenen Objektmodell konfrontiert. Es besteht aus zahlreichen Objekten, die jeweils ein bestimmtes Element der Anwendung repräsentieren. So gibt es das »Selection«-Objekt, das die aktuelle Textmarkierung darstellt, oder das »Documents«-Objekt, eine Auflistung aller geöffneten Dokumente. Diese Objekte lassen sich direkt aus dem Quelltext heraus ansprechen, im unmittelbaren Zugriff auf ihre Eigenschaften und Methoden.

In Star Office 6 gibt es keine geschlossene Objektwelt (mehr). An deren Stelle ist das Star-Office-API getreten, eine an Komponenten reiche und in Modulen geordnete Bibliothek, die dem Entwickler keine Objekte, sondern Services anbietet (Abbildungen 1 und 2). Jeder dieser Dienste stellt ein Interface (eine Schnittstelle) sowie Properties (Eigenschaften) zur Verfügung, über die man jeweils auf ein bestimmtes Programmfeature zugreifen kann. Der wesentliche Unterschied zu Objekten ist, dass ein Service nicht direkt abrufbar ist. Stattdessen muss der Programmierer ein Objekt anlegen und diesem dann einen Verweis auf den gewünschten Service zuweisen.

Das im folgenden Tipp beschriebene Verfahren dürfte vom Grundsatz her auch VBA-Entwicklern bekannt sein, die schon mal ein ActiveX-Control oder eine andere COM-Komponente in ihre Makros eingebunden haben.

Abbildung 1: Das Star-Office-API bietet seine Funktionen in Form von Services an, auf die man über selbst erstellte Objektvariablen zugreift. (Quelle: Sun Microsystems)

Abbildung 1: Das Star-Office-API bietet seine Funktionen in Form von Services an, auf die man über selbst erstellte Objektvariablen zugreift. (Quelle: Sun Microsystems)

Abbildung 2: Die zahlreichen Services des Star-Office-API sind in Modulen untergebracht, deren Namen man für den Aufruf eines Service kennen muss. (Quelle: Sun Microsystems)

Abbildung 2: Die zahlreichen Services des Star-Office-API sind in Modulen untergebracht, deren Namen man für den Aufruf eines Service kennen muss. (Quelle: Sun Microsystems)

Tabelle 1: Wichtige Module und Services des Star-Office-API

Tabelle 1: Wichtige Module und Services des Star-Office-API

Tipp 1: Dienste einbinden I

Zum Einbinden eines Services ist immer eine Objektvariable erforderlich, die wie folgt zu deklarieren ist:

Dim objIrgendEinService As Object

Das weitere Vorgehen unterscheidet sich je nachdem, ob ein kontextabhängiger oder -unabhängiger Service vorliegt. Zum Einrichten eines Verweises auf einen unabhängigen Service dient die Funktion »createUnoService«, der der Name des gewünschten Dienstes übergeben wird. Der setzt sich aus drei Bestandteilen zusammen: dem stets gleichen Pfad »com.sun.star«, dem Namen des API-Moduls, das den Service bereitstellt (Tabelle 1), sowie dem Namen des Services selbst.

Das Modul »drawing« etwa enthält einen Service namens »ColorTable«, der den Zugang zur Star-Office-eigenen Farbpalette freimacht. Der vollständige Service-Name lautet »com.sun.star.drawing.ColorTable«. Die folgende Zeile richtet einen Verweis auf den Service ein und speichert ihn in der zuvor deklarierten Objektvariablen »objColorTable«:

objColorTable = createUnoService
("com.sun.star.drawing.ColorTable")

Tipp 2: Dienste einbinden II

Kontextabhängige Services stehen nur in Verbindung mit Dokumenten zur Verfügung, genauer: Sie werden von diesen bereitgestellt. Um etwa den »Text«-Service zu nutzen, der Zugriff auf die Inhalte eines Star-Writer-Dokuments erlaubt, ist zunächst ein Verweis auf das Dokument nötig. Den erhält man über das Öffnen eines vorhandenen (siehe Tipp 3) oder das Anlegen eines neuen Dokuments (Tipp 4). Am einfachsten ist es, einen Verweis auf das aktuelle Star-Office-Dokument zu bekommen. Dazu genügt in Star Basic die Zuweisung des Schlüsselworts »ThisComponent« an eine zuvor deklarierte Objektvariable:

objDokument = ThisComponent

Die Objektvariable »objDokument« liefert den kontextabhängigen Service »Text«, der nur noch einer weiteren (natürlich ebenfalls zuvor angemeldeten) Objektvariablen zugewiesen sein will:

objText = objDokument.Text

Tipp 3: Ein vorhandenes Dokument öffnen

Der kontextunabhängige Service »Desktop« liefert dem Entwickler die Funktionen des (virtuellen) Star-Office-Desktops. Unter anderem verfügt er über die Methode »loadComponentFromURL«, die ein vorhandenes Star-Office-Dokument öffnet. Die Methode benötigt einen Verweis (siehe Tipp 2) auf den Service, der wie folgt beschaffbar ist:

Dim objDesktop As Object
objDesktop = createUnoService 
("com.sun.star.frame.Desktop")

Beim Aufruf ist der Methode die URL (siehe Tabelle 2) der zu öffnenden Datei – zum Beispiel »file:///home/ralf/Artikel.sxw« – zu übergeben. Weitere Argumente sind der Text »_blank«, eine Null sowie ein leeres Variant-Array. Im Erfolgsfall liefert die Methode einen Verweis auf das geöffnete Dokument zurück, der in einer Objektvariablen zu speichern ist:

Dim objDokument As Object
objDokument = objDesktop 
.loadComponentFromURL( 
"file:///home/ralf/Test.sxw", 
"_blank", 0, vntNoArgs())
Tabele 2: Vom Star-Office-API verwendete URL-Typen

Tabele 2: Vom Star-Office-API verwendete URL-Typen

Tipp 4: Ein neues Dokument anlegen

Die »loadComponentFromURL«-Methode des »Desktop«-Service ermöglicht nicht nur das Öffnen eines vorhandenen (siehe Tipp 3), sondern auch das Anlegen eines neuen Dokuments (siehe Abbildung 3). Dazu ist ihr eine besondere URL zu übergeben, die mit »private:factory/« beginnt und mit einem der folgenden Bezeichner für die Art des anzulegenden Dokuments endet:

  • »swriter«: Textdokument
  • »scalc«: Tabellendokument
  • »draw«: Zeichnung

Die folgende Befehlszeile ermöglicht demnach das Anlegen eines neuen Star-Writer-Dokuments:

objTextDokument = objDesktop 
.loadComponentFromURL( 
"private:factory/swriter", 
"_blank", 0, vntNoArgs())

Über die entsprechende Objektvariable »objTextDokument« ist anschließend der Zugriff auf das neu angelegte Dokument möglich.

Abbildung 3: Die »loadComponentFromURL«-Methode des »Desktop«-Service erlaubt das Öffnen eines vorhandenen und das Anlegen eines neuen Dokuments.

Abbildung 3: Die »loadComponentFromURL«-Methode des »Desktop«-Service erlaubt das Öffnen eines vorhandenen und das Anlegen eines neuen Dokuments.

Tipp 5: Den Wert einer Objektvariablen prüfen

Einer der häufigsten Fehler in Star-Office-Makros ist der, dass die Zuweisung eines Service oder Verweises an eine Objektvariable scheitert. Wenn die »loadComponentFromURL«-Methode etwa das in der URL angegebene Dokument nicht finden kann, weil es beispielsweise nicht (mehr) existiert, kann sie auch keinen gültigen Verweis darauf zurückliefern.

Zwangsläufig bekommt das Makro dann auch Probleme, wenn es über die Objektvariable auf das vermeintlich vorhandene Dokument zugreifen will. Damit keine Fehlermeldung die Ausführung des Makros unterbricht, sollte man noch die Gültigkeit der Objektvariablen mit Hilfe der Basic-Funktion »IsNull« überprüfen. Sie liefert den logischen Wert »True« zurück, wenn die Objektvariable keinen gültigen Wert besitzt. Das Beispiel

Dim objDokument As Object
objDokument = ThisComponent
If Not IsNull(objDokument) Then
   MsgBox objDokument.URL
End If

prüft, ob die Objektvariable »objDokument«, die auf das aktuelle Dokument (hier »ThisComponent«) verweist, einen gültigen Wert besitzt. Nur wenn das der Fall ist, zeigt die darauf folgende »MsgBox«-Anweisung die URL der betreffenden Datei an. Sollte aktuell kein Dokument geöffnet sein, wird das Makro ohne Fehlermeldung beendet.

Tipp 6: Eigenschaften von Services festlegen

Eigenschaften (Properties) sind Werte, die Charakteristika von Services festlegen. Einige Services besitzen eine feste Anzahl von Eigenschaften, auf die man direkt über die zugewiesene Objektvariable zugreifen darf. Ein Beispiel ist die »FillColor«-Eigenschaft, die Füllfarben von Zeichnungsobjekten (»Shapes«) bestimmt. Das Shape-Objekt »objRechteck« beispielsweise wird über

objRechteck.FillColor = 
RGB(0, 0, 255)

mit rein blauer Füllung versehen. Anders sieht es aus, wenn ein Service optionale Eigenschaften besitzt, die mal angegeben werden und mal nicht. Dann müssen diese in einem Array vom Datentyp »PropertyValue« übergeben werden. Das ist etwa beim »Desktop«-Service so, dem man über optionale Eigenschaften mitteilen kann, welche Datei- Art er mit seiner »loadComponentFromURL«-Methode öffnen soll. Das beginnt mit der Dimensionierung des »PropertyValue«-Arrays, das so viele Elemente haben muss, wie Eigenschaften festzulegen sind. Bei zwei Eigenschaften ist das Array also auf »1« zu dimensionieren, so dass Star Basic zwei Elemente mit den Indexzahlen »0« und »1« reserviert:

Dim prvFileProperties(1) As New 
com.sun.star.beans.PropertyValue

Anschließend weist man jedem Element über »Name« und »Value« den Namen sowie den zugehörigen Wert der festzulegenden Eigenschaft zu. Das folgende Beispiel legt die »FilterName«-Eigenschaft auf »MS Word 97« und die »AsTemplate«-Eigenschaft auf »False« fest:

prvFileProperties(0).Name= 
"FilterName"
prvFileProperties(0).Value= 
"MS Word 97"
prvFileProperties(1).Name= 
"AsTemplate"
prvFileProperties(1).Value=False

Zur Übermittlung an den »Desktop«-Service folgt das gefüllte Array der »loadComponentFromURL«-Methode als Parameter:

objDokument = objDesktop 
.loadComponentFromURL( 
"file:///home/ralf/Finanz.doc", 
"_blank", 0, prvFileProperties())

Im Klartext veranlasst diese Anweisung den »Desktop«-Service dazu, die Datei »Finanz.doc« als Microsoft-Word-Dokument zu öffnen.

Tipp 7: Word-Dokumente bequem öffnen

Die benutzerdefinierte Funktion »WordDokOeffnen« in Listing 1 vereinfacht das Öffnen von Microsoft-Word-Dokumenten erheblich. Zum Aufruf ist der Funktion nur die URL des zu öffnenden Word-Dokuments zu übergeben sowie eine Objektvariable zur Aufnahme des Rückgabewerts zuzuweisen:

Dim objDokument As Object
objDokument = WordDokOeffnen 
("file:///home/ralf/Muster.doc")

Die Funktion definiert ein »PropertyValue«-Array (siehe Tipp 6) zum Festlegen der Dateifilter-Eigenschaften und übergibt es der »loadComponentFromURL«-Methode des »Desktop«-Service, der das Dokument zu öffnen versucht. Wenn das gelingt, liefert die Funktion einen Verweis auf das geöffnete Word-Dokument zurück, der in der Objektvariablen gespeichert wird. Das aufrufende Makro sollte den Variablenwert prüfen, um seinerseits zu erfahren, dass die Arbeit der Funktion erfolgreich war:

If Not IsNull(objDokument) Then
   'Beliebige Anweisungen
   '...
End If
Abbildung 4: Die Services des Star-Office-API erlauben auch eine automatisierte Übernahme von Microsoft-Office-Dokumenten.

Abbildung 4: Die Services des Star-Office-API erlauben auch eine automatisierte Übernahme von Microsoft-Office-Dokumenten.

Listing 1: Öffnen eines Word-Dokuments

Listing 1: Öffnen eines Word-Dokuments

Tipp 8: Mit Collections arbeiten I

Das Star-Office-API enthält viele Komponenten, die zu so genannten Kollektionen (Collections) zusammengefasst sind. So bilden etwa sämtliche Tabellen (Sheets) eines Tabellendokuments eine Kollektion, ebenso die Absätze eines Textdokuments. Je nach Typ der Kollektion gibt es mehrere Möglichkeiten, auf einzelne Elemente zuzugreifen. Bei benannten Kollektionen wie »Sheets« hat jedes Element einen individuellen Namen, über den es mit der »getByName«-Methode adressierbar ist.

Das folgende Beispiel richtet einen Verweis auf die Tabelle »Tabelle1« ein, der in der Objektvariablen »objTabelle« gespeichert wird:

Dim objSheets As Object
Dim objTabelle As Object
objSheets = ThisComponent.Sheets
objTabelle = objSheets 
.getByName("Tabelle1")

Jede benannte Kollektion besitzt eine »getElementNames«-Methode, die die Namen aller Elemente als Array zurückliefert. Zur Aufnahme des Arrays ist eine Variant-Variable nötig. Das Beispiel liest die Namen aller Tabellen des aktuellen Tabellendokuments in die Variant-Variable »strNamen« ein und gibt deren Inhalt per »For-Next«-Schleife aus:

Dim strNamen As Variant
Dim intI As Integer
objSheets = ThisComponent.Sheets
strNamen = objSheets.getElementNames
For intI = LBound(strNamen) To 
UBound(strNamen)
   MsgBox strNamen(intI)
Next

Um festzustellen, ob ein bestimmtes Element in einer benannten Kollektion enthalten ist, tritt die »hasByName«-Methode der Kollektion in Aktion. Das Beispiel prüft die Existenz der Tabelle »Tabelle1« und zeigt das Ergebnis (»True« beziehungsweise »False«) per »MsgBox«-Dialog an:

objSheets = ThisComponent.Sheets
MsgBox objSheets.hasByName 
("Tabelle1")

Tipp 9: Mit Collections arbeiten II

Bei indizierten Kollektionen besitzt jedes Element eine Indexzahl, die seine Position innerhalb der Kollektion angibt. Die Zählung der Kollektionselemente beginnt stets bei null. Den Zugriff auf ein Element ermöglicht die »getByIndex«-Methode, die die Indexzahl des gewünschten Elements erwartet. Das folgende Beispiel

Dim objSheets As Object
Dim objTabelle As Object
objSheets = ThisComponent.Sheets
objTabelle = objSheets.getByIndex(1)

erzeugt einen in »objTabelle« gespeicherten Verweis auf die zweite Tabelle des aktuellen Tabellendokuments. Alternativ erlaubt Star Basic einen verkürzten Zugriff, der ohne die »getByIndex«-Methode auskommt:

objTabelle = 
objSheets(1)

Wer jedoch eine indizierte Kollektion vollständig durchlaufen will, sollte dazu eine For-Next-Schleife verwenden. Über deren automatisch erhöhte Zählvariable ist der Zugriff auf jedes einzelne Element der Kollektion möglich. Den Zähler-Endwert liefert die »getCount«-Methode, die die Anzahl der Elemente benennt. Das Beispiel zeigt die Namen (»Name«-Eigenschaften) aller Tabellen des aktuellen Tabellendokuments an:

Dim objSheets As Object
Dim intI As Integer
objSheets = ThisComponent.Sheets
For intI = 0 To objSheets 
.getCount() - 1
   MsgBox objSheets(intI).Name
Next

Tipp 10: Mit Collections arbeiten III

Es gibt Kollektionen, deren Elemente weder Namen noch Indizes besitzen. Das ist etwa bei den Absätzen eines Textdokuments der Fall. Bei solchen Kollektionen ist kein direkter Zugriff auf die einzelnen Elemente möglich. Stattdessen gilt es, mit der »createEnumeration«-Methode ein Aufzählungsobjekt zu erzeugen, auf dessen Elemente man sequenziell zugreifen kann.

Das Beispiel erzeugt das Aufzählungsobjekt »objAufzaehlung«, das alle Absätze des aktuellen Textdokuments enthält. Der Kopf der While-Wend-Schleife prüft bei jedem Durchlauf mit der »hasMoreElements«-Methode, ob die Aufzählung weitere Elemente enthält. Wenn das der Fall ist, speichert die Schleife den von »nextElement« gelieferten Verweis auf den nächsten Absatz in der Objektvariablen »objAbsatz« und zeigt dessen Inhalt per »MsgBox«-Meldung:

01 Dim objAufzaehlung As Object
02 Dim objAbsatz As Object
03 
04 objAufzaehlung = ThisComponent 
05 .Text.createEnumeration
06 
07 While objAufzaehlung 
08 .hasMoreElements
09    objAbsatz = objAufzaehlung 
10    .nextElement
11    MsgBox objAbsatz.getString
12 Wend

Tipp 11: Verfügbare Services dokumentieren

Das zurzeit größte Problem bei der Entwicklung von Star-Office-Makros ist die unzureichende Dokumentation. Es gibt bislang nur ein Gesamtverzeichnis sämtlicher API-Bestandteile, das ausschließlich online einsehbar ist [3] und kaum Orientierung bietet.

Eine Besserung dieser Situation kann die nützliche Prozedur aus Listing 2 bringen, das online auf dem Linux-Magazin-Server zur Verfügung steht [4]. Sie trägt die Namen aller verfügbaren Services einer bestimmten API-Komponente zusammen und schreibt sie in ein neues Textdokument. Beim Aufruf ist der Prozedur ein Star-Basic-Bezeichner respektive eine Objektvariable zu übergeben, der/die auf die gewünschte Komponente verweist. Die Anweisungszeile:

Call ServicesDokumentieren 
(ThisComponent)

beispielsweise erstellt eine Referenz aller Services des aktuellen Dokuments. Als Lieferant der Service-Namen dient die Methode »getAvailableServiceNames« der jeweiligen API-Komponente. (jk)

 

Infos

[1] Star Office: [www.sun.de/staroffice]

[2] Newsgroup zu Star Basic: [news:staroffice.de.support.starbasic]

[3] Verzeichnis der API-Teile: [http://api.openoffice.org/common/ref/com/sun/star/module-ix.html]

[4] Listings zum Artikel: [ftp://ftp. linux-magazin.de/pub/listings/magazin/2002/05/StarBasic]

LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Nach oben