DE/Makro Basic Tutorial

From Apache OpenOffice Wiki
< DE
Jump to: navigation, search


Achtung, work in progress

Dieses Dokument wird gerade übersetzt, wer mag, darf auch gerne helfen.

Arbeitstitel: "Einführung: Basic für OOo-Erweiterungen"
Originaldokument: Extensions_development_basic
Ursprünglicher Autor: Ian Laurenson
offene Fragen: sind mit ??? gekennzeichnet

Diese Seite soll Ihnen eine Einführung in das Schreiben von Makros mit OpenOffice.org Basic geben. Grundkenntnisse im Programmieren werden vorausgesetzt. Bitte fühlen Sie sich frei, diese Seite zu editieren, um sie lesbarer zu machen. Ich hoffe, dass sie Ihnen von Nutzen sein wird.

Wenn Sie bereits mit den Grundlagen vertraut sind, können Sie sich auch direkt im KochBuch (CookBook) Wrapper (-> dt. Entwurfsmuster aus objektorientierter Programmierung; Schnittstelle zwischen aufrufendem und eingeschlossenen Programm, z.B. wenn unterschiedliche Programmiersprachen zum Einsatz kommen) und Beispiele anschauen.


Wohin schreibe ich den Code?

Der Basic-Code wird bei OpenOffice.org in Modulen gespeichert, die in Bibliotheken zusammengefasst sind.

Eine Bibliothek kann

  • allgemein, also für die gesamte (Netzwerk-) Installation verfügbar sein ("OOo Makros und Dialoge")
  • nur für den aktuellen Benutzer verfügbar sein ("Meine Makros und Dialoge")
  • in einem Dokument oder in einer Vorlage abgelegt sein, so dass ihr Code nur zur Verfügung steht, wenn das Dokument geöffnet ist.

Bibliotheken, die in einem Dokument abgelegt sind, können mit dem Dokument auf einfache Weise kopiert, transportiert und verteilt werden.

Bibliotheken, die nicht in einem Dokument abgelegt sind (also allgemein oder für den aktuellen Benutzer verfügbare Bibliotheken) werden im Folgenden als OpenOffice.org Bibliotheken zusammengefasst.

Der physische Speicherort für diese OpenOffice.org Bibliotheken wird unter
Extras > Optionen… > OpenOffice.org > Pfade > BASIC festgelegt.

Anmerkung: Hüten Sie sich, Bibliotheken auf Dateisystem-Ebene zu verschieben oder zu kopieren. Benutzen Sie stattdessen den Dialog "Makros verwalten" oder den Paket-Manager

Module in Bibliotheken können maximal 64kb groß sein. Eine Bibliothek kann bis zu 16 000 Module enthalten. Weitere Infos finden Sie in der Online-Hilfe unter "Module und Bibliotheken" (???).

Die Entwicklungsumgebung (IDE)

Öffnen Sie die Entwicklungsumgebung:

  • in OOo 1.1.x unter Extras > Makros > Makro ...
  • in OOo 1.9.x und höher unter Extras > Makros > Makros verwalten > OpenOffice.org Basic...

Zum Einstieg benutzen wir das "Modul1" aus der Bibliothek "Standard" des aktuellen Benutzers:

Geben Sie einen Namen für das neue Makro ein: "HelloWorld"

Wählen Sie die Option Standard im Auswahlfeld "Makro aus:"

Klicken Sie auf Neu

Jetzt sollten Sie etwa folgendes sehen:

REM  *****  BASIC  *****
 
Sub Main
 
End Sub
 
Sub HelloWorld
 
End Sub

Der Cursor sollte am Anfang der Zeile Sub HelloWorld stehen.


Achtung: Das geöffnete IDE-Fenster ist sowohl über das Menü im OpenOffice.org-Fenster als auch über die Programmleiste des Betriebssystems erreichbar.


Eingeben von Programm-Code

Löschen Sie folgende Zeilen:

REM  *****  BASIC  *****
 
Sub Main
 
End Sub

Schreiben Sie unterhalb der Zeile "Sub HelloWorld": msgbox "Hello World!", so dass es in etwa so aussieht:

Sub HelloWorld
  msgbox "Hello World!"
End Sub
Achtung: Die IDE beherrscht zwar keine "code completion"(->dt.Auto-Vervollständigung), also die Fähigkeit eines Editors, den Text automatisch zu vervollständigen, um den Schreibprozess während der Eingabe zu beschleunigen, verfügt aber über eine kontext-sensitive Hilfe, wenn Sie während der Eingabe F1 oder "Hilfe" drücken oder der Cursor in einem Befehl steht.
Bei OpenOffice.org Basic-Befehlen wird die Groß- und Kleinschreibung nicht unterschieden. So sind die Eingaben msgbox, MSGBOX oder Msgbox äquivalent.
Strings (Textvariablen) werden in doppelte Anführungszeichen eingeschlossen.

Den Code ausführen

Hierfür gibt es mehrere Möglichkeiten:

  • direkt aus der IDE: das Symbol Ausführen (das 3. Symbol in der 2. Leiste) ruft das ERSTE Makro des aktuellen Moduls auf.
  • aus dem Menü "Extras":
    • (Version 1.1.x) Extras > Makros > Makro…
    • (Version 1.9.x und höher) Extras > Makro > Makro auführen…
  • Dem Makro ein Tastaturkürzel zuweisen.
    • (Version 1.1.x) ???
    • (Version 1.9.x und höher) Ansicht > Symbolleisten > Anpassen... Tab Tastatur
  • Dem Makro einen Menüeintrag zuweisen.
    • (Version 1.1.x) ???
    • (Version 1.9.x und höher) Ansicht > Symbolleisten > Anpassen... Tab Menüs
  • Dem Makro ein Symbolleisten-Symbol zuweisen.
    • (Version 1.1.x) ???
    • (Version 1.9.x und höher) Ansicht > Symbolleisten > Anpassen... Tab Symbolleisten
  • Ein Kontroll-Element in einem Dokument erstellen.
    • (Version 1.1.x) ???
    • (Version 1.9.x und höher) Ansicht > Symbolleisten > Anpassen... Tab Symbolleisten (bei Speichern in das aktuelle Dokument wählen)
  • Das Makro einem Ereignis zuweisen.
    • (Version 1.1.x) ???
    • (Version 1.9.x und höher) Ansicht > Symbolleisten > Anpassen... Tab Ereignisse

Führen Sie für den Anfang die "HelloWorld"-Subroutine aus, indem Sie auf das Ausführen-Symbol klicken. Ein kleiner Dialog mit dem Titel "soffice" und dem Text "Hello World" sollte aufpoppen.

Speichern des Codes

Der Code wird immer automatisch gespeichert, wenn sein Container gespeichert wird. Wenn das Modul also in einer (allgemeinen oder benutzerspezifischen) OpenOffice.org-Bibliothek enthalten ist, wird es beim Schließen der Anwendung OpenOffice.org gespeichert. Entsprechend werden Dokument-interne Bibliotheken beim Speichern des Dokuments mitgesichert.

Auf der Standard-Symbolleiste der IDE (normalerweise die oberste Symbolleiste) finden Sie ein Symbol "Speichern". Befindet sich der Code in einem Dokument oder einer Vorlage, dann speichert der Klick auf dieses Symbol das gesamte Dokument. Handelt es sich dagegen um eine OpenOffice.org-Bibliothek, wird nur die aktuelle Bibliothek gespeichert.

Variablen

Bei Variablen kann durch Option Explicit zu Beginn des Moduls die explizite Deklaration erzwungen werden. Zu Sinn und Unsinn des Deklarierens von Variablen lesen Sie diese Diskussion.

In dieser Diskussion vertritt der ursprüngliche Autor dieses Wiki-Beitrags die Position, dass Variablen immer deklariert werden sollten. Mittlerweile hat er seine Meinung geändert. Kurz: es ist eine Frage des persönlichen Geschmacks. Unabhängig davon sollten nach Auffassung des ursprünglichen Autors Variablen nach folgender Konvention benannt werden, die auch bei den Beispielen aus diesem Wiki verwendet wurde:

Der erste Buchstabe der Variable steht für den Typ des in der Variable gespeicherten Wertes. Dabei bezeichnen folgende Buchstaben die entsprechenden Datentypen (in Anlehung an das Tutorial.pdf von Sun):

Buchstabe Bedeutung
a Struktur (Structure)
b Bool'sch (WAHR oder FALSCH)
e Aufzählung (Enumeration). Diese Variable kann nur einen begrenzten Satz von Werten enthalten.
f Fließkomma-Zahl (3.402823 x 1038 bis 1.401298 x 10-45. Eine einzelne Variable kann bis zu 4 Bytes umfassen)
"Double" (doppelte Genauigkeit, 1.79769313486232 x 10308 bis 4.94065645841247 x 10-324. Eine Double-Variable kann bis zu 8 Bytes umfassen)
Währung (-922337203685477.5808 bis +922337203685477.5807 ebenfalls 8 Byte umfassend)
m Feld (Array) (aka Sequenz aka Matrix)
n Integer (-32768 to 32767.) oder
Long (-2147483648 and 2147483647).
o Objekt, Service oder Interface
s Text (String) (Eine String-Variable kann bis zu 65535 Unicode-Zeichen enthalten).
x Schnittstelle (Interface), um anzuzeigen, dass nur Methoden einer bstimmten Schnittstelle eines Objekts verwendet werden.
v Variant, irgend ein Typ

Benutzen Sie lange, beschreibende Variablennamen unter Verwendung von CamelCase (Groß-Klein-Schreibung).

Achtung: Bei benutzerdefinierten OpenOffice.org Basic-Variablen spielt die Groß-/Kleinschreibunge keine Rolle. Bei UNO-API-Konstanten aber sehr wohl!

Ausnahmen von der Regel, lange Namen zu verwenden, sind Index-Variablen (meist i, j oder k), sowie Strings (meist als s bezeichnet).

Bearbeiten Sie nun die sub HelloWorld, so dass der Code ungefähr wie im folgenden aussieht und führen Sie sie aus:

sub HelloWorld
dim i as integer 'This line is optional
  for i = 0 to 2
    'These lines are indented for ease of reading only
    'all your code should be like this for long time survival
    msgbox "Hello World " & i
  next i
end sub

Mehr Infos zur Verwendung von Variablen erhalten Sie in der Online-Hilfe unter "Variablen benutzen" (???)

Die OpenOffice.org API

Dieser Abschnitt beginnt mit einem Beispiel. Anschließend wird das Beispiel erläutert.

Versuchen Sie den folgenden Code in Dokumenten unterschiedlichen Typs auszuführen:

sub main
'basicLibraries.loadLibrary("XrayTool")
'xray thisComponent
msgbox fnWhichComponent(thisComponent)
end sub
 
 
function fnWhichComponent(oDoc) as string
if HasUnoInterfaces(oDoc, "com.sun.star.lang.XServiceInfo") then 
   if thisComponent.supportsService ("com.sun.star.text.GenericTextDocument") then
      fnWhichComponent = "Text"
   elseif thisComponent.supportsService("com.sun.star.sheet.SpreadsheetDocument") then
      fnWhichComponent = "Spreadsheet"
   elseif thisComponent.supportsService("com.sun.star.presentation.PresentationDocument") then
      fnWhichComponent = "Presentation"
   elseif thisComponent.supportsService("com.sun.star.drawing.GenericDrawingDocument") then
      fnWhichComponent = "Drawing"
   else
      fnWhichComponent = "Oops current document something else"
   end if
else
   fnWhichComponent = "Not a document"
end if
End function


Namenskonventionen für Subroutinen

Im obigen Beispiel beginnt die benutzerdefinierte Funktion mit den Buchstaben "fn". Diese Konvention (an die sich der ursprüngliche Autor hält) kennzeichnet eine Funktion als benutzerdefiniert. Entsprechend beginnt eine benutzerdefinierte Subroutine mit "sub". Diese im Folgenden benutzten Konventionen sollen Ihnen als Anfängern helfen, benutzerdefinierte von eingebauten Routinen/Funktionen zu unterscheiden.

Einführung in die OpenOffice.org API

In diesem Abschnitt werden folgende Begriffe erläutert:

  • Interface (Schnittstelle)
  • Modul
  • Service (Dienst)
  • Methode
  • Property (Eigenschaft)

Den Unterschied zwischen einer Schnittstelle und einem Service zu kennen, ist zwar nicht unbedingt Voraussetzung zum Programmieren unter OpenOffice.org, aber es hilft, die Dokumentation zu verstehen, und auch bei der Introspektion. Möglicherweise werden Sie den folgenden Abschnitt mindestens zwei mal lesen müssen!

Eine Schnittstelle ist eine Definition eines Satzes von Methoden (und ihren Argumenten), die ein Dienst, der diese Schnittstelle implementiert, enthalten muss.

Schnittstellen werden aus Gründen der Namensgebung zu Modulen gruppiert. Alle Schnittstellen (und Dienste) beginnen mit com.sun.star, gefolgt vom Modul-Namen, dann kommt der Name der Schnittstelle (oder des Dienstes).

Beispielsweise bieten die meisten Dienste die Schnittstelle com.sun.star.beans.XPropertySet. Diese Schnittstelle ist im Modul beans gespeichert und ermöglicht Zugriff auf die Eigenschaften (Properties) eines Dienstes. Eine Eigenschaft ist ein Wert, eine Methode ist dagegen eine Aktion.

Ein OpenOffice.org-Objekt kann viele Dienste enthalten.

Ein OpenOffice.org-Objekt kann einen Dienst enthalten, der eine Schnittstelle implementiert, in welcher eine Methode beschreibt, dass ein anderes OpenOffice.org-Objekt zurückgegeben wird.

Introspektion

HasUnoInterfaces ist eine OpenOffice.org-Basic-Funktion zur Introspektion. Informieren Sie sich über Introspektion in anderen Sprachen.

HasUnoInterfaces gibt true zurück, wenn beim spezifizierten Objekt alle spezifizierten Schnittstellen verfügbar sind.

Die meisten OpenOffice.org-Objekte enthalten die Methode supportsService, weil sie die Schnittstelle com.sun.star.lang.XServiceInfo enthalten.

Im obigen Beispiel prüft HasUnoInterfaces, ob das aktuelle Dokument die Schnittstelle com.sun.star.lang.XServiceInfo implementiert, da andernfalls die Methode supportsService fehlen würde. Der Aufruf dieser Methode würde in diesem Fall einen Laufzeitfehler verursachen.

supportsService ist eine Methode, die den Wert true zurückgibt, wenn der spezifizierte Service verfügbar ist. Das obige Beispiel prüft das Vorhandensein eines Service, um so den Typ des aktuell aktiven Dokuments zu bestimmen.

X-Ray tool

Die Benutzung von HasUnoInterfaces und supportsService reicht aus, um sich zur Laufzeit über ein Objekt zu informieren, aber zum Lernen eignet sich das X-Ray tool von Bernard Marcelly viel besser. Laden Sie das ZIP-File herunter, entpacken Sie es und öffnen Sie das enthaltene Dokument mit OpenOffice.org. Befolgen Sie anschließend die Installationsanweisungen.

Das X-Ray tool verlangt bei der Konfiguration eine lokale Kopie des OpenOffice.org SDK. Debian-Anwender brauchen nur das Paket "openoffice.org-dev" zu installieren. Sonst laden Sie es ggf. von hier herunter und entpacken Sie es. Unter dem Button "Configuration" auf dem Xray-Hauptdialog ist der Pfad zum lokal installierten OOo-SDK (z.B. /usr/lib/openoffice/basis3.1/sdk/ ) sowie zum gewünschten Browser (z.B. /usr/bin/konqueror ) anzugeben.

Nun können Sie die beiden auskommentierten Zeilen des obigen Beispiels entkommentieren (den Apostroph entfernen):

'basicLibraries.loadLibrary("XrayTool")
'xray thisComponent

Führen Sie das Makro dann erneut aus.

Ab Xray Version 5 heißt das Kommando einfach xray.

BasicLibraries ist ein OpenOffice.org-Basic-Befehl, der ein Objekt zurückgibt, mit dem man auf die OpenOffice.org Bibliotheken zugreifen kann. Die Methode loadLibrary macht die Routinen aus dieser Bibliothek verfügbar.

xray.xray spezifiziert die Subroutine xray im Modul xray in dieser Bibliothek, thisComponent ist das Objekt, das an xray zur Introspektion übergeben wird.

Um mit einem bestimmten Objekt zu arbeiten erfordert häufig, dieses Objekt zu finden oder zu erzeugen, indem man mit StarDesktop oder thisComponent beginnt.

Desktop, Dokumente, Selektionen

StarDesktop und ThisComponent sind OpenOffice.org-Basic-Befehle, die sich auf die Applikation bzw. das aktuell aktive Dokument beziehen.

Im Unterschied zu Microsoft Office ist OpenOffice.org eine Anwendung mit unterschiedlichen Komponenten. Beim Ausführen von Code möchte man häufig wissen, welche Komponente aktuell aktiv ist. Der obige Code zeigt eine Möglichkeit, dies zu überprüfen.

StarDesktop bezieht sich auf einen konzeptuellen Desktop (der historisch tatsächlich mal existiert hat) und meint de facto die Anwendung OpenOffice.org.

Neue Dokumente erzeugen

Um ein neues Text-Dokument zu erzeugen:

oDoc = StarDesktop.loadComponentFromURL("private:factory/swriter", "_blank", 0, Array())

Um ein neues Tabellen-Dokument zu erzeugen:

oDoc = StarDesktop.loadComponentFromURL("private:factory/scalc", "_blank", 0, Array())

Ein sinnvoller Ansatz wäre, eine einfache Funktion zu schreiben:

function fnNewDoc(sDocType as string)
fnNewDoc = StarDesktop.loadComponentFromURL("private:factory/" & sDocType , "_blank", 0, Array())
end function

Dann könnte man neue Dokumente ganz einfach erzeugen (in Sub vor der Funktion):

oDoc = fnNewDoc("swriter")
oDoc = fnNewDoc("scalc")
oDoc = fnNewDoc("simpress")
oDoc = fnNewDoc("sdraw")
oDoc = fnNewDoc("smath")

Siehe http://api.openoffice.org/docs/common/ref/com/sun/star/frame/XComponentLoader.html .

Ein bestehendes Dokument öffnen

Im folgenden Beispiel sehen Sie, wie Sie eine Datei öffnen können. OpenOffice.org URLs sind in DE/URL Grundlagen erläutert.

sFile = "C:\Documents and Settings\danny\Desktop\MyCalc.sxc" ' Windows
sFile = "/home/danny/Desktop/MyCalc.sxc" ' Linux
sURL = ConvertToURL(sFile)
oDoc = StarDesktop.loadComponentFromURL(sURL, "_blank", 0, Array())

Auch hier könnte eine einfache Funktion das Schreiben verkürzen:

function fnOpenDoc(sFile)
sURL = ConvertToURL(sFile)
fnOpenDoc = StarDesktop.loadComponentFromURL(sURL, "_blank", 0, Array())
end function

Beispiele für Aufrufe:

oDoc = fnOpenDoc("C:\Documents and Settings\danny\Desktop\MyCalc.sxc") ' Windows
oDoc = fnOpenDoc("/home/danny/Desktop/MyCalc.sxc") ' Linux

Die aktuelle Selektion

Häufig werden Sie eine Funktion schreiben wollen, die etwas mit dem aktuell selektierten Bereich anstellt. ThisComponent enthält die Methode getCurrentSelection. Da viele unterschiedliche Objekte selektiert sein könnten, werden Sie zuerst prüfen wollen, ob das selektierte Objekt über den Dienst verfügt, der die Methode enthält, mit der Sie das Objekt bearbeiten wollen.

Editieren Sie die Subroutine main im nachfolgenden Code und führen Sie sie mehrfach in einem Textdokument aus, wobei Sie unterschiedliche Objekte selektieren. (Um mehr als einen Textblock zu selektieren, betätigen Sie die Strg-Taste).

sub main
basicLibraries.loadLibrary("XrayTool")
if fnWhichComponent(thisComponent) = "Text" then
        oCurSelection = thisComponent.getCurrentSelection()
        'xray.xray oCurSelection
        if oCurSelection.supportsService("com.sun.star.text.TextRanges") then
                msgbox "There are " & oCurSelection.getCount() & _
                 " selections in the current text document."
        end if
end if
end sub

Wenn nichts selektiert ist, beträgt die Anzahl der Selektionen eins (nämlich der Einfügepunkt), wenn ein Textblock selektiert ist, beträgt die Anzahl ebenfalls eins, wenn zwei Textblöcke selektiert sind, beträgt sie drei: der Einfügepunkt sowie die beiden selektierten Textblöcke.

Übung 1: Modifizieren Sie den obigen Code so, dass er mit selektierten Zellbereichen in einem Tabellendokument funktioniert.

Frage 1: Wie hoch ist die Anzahl der Selektionen, wenn zwei Zellblöcke selektiert sind?

Properties

Wenn Sie die Zeile 'xray.xray oCurSelection entkommentieren, so dass xray läuft, sehen Sie, dass das Objekt, worauf oCurSelection zeigt, eine "Property" namens Count besitzt, mit einer Beschreibung "pseudo-prop, read only". In OpenOffice.org Basic könnten Sie oCurSelection.count schreiben, da dies aber in keiner anderen Sprache, mit der Sie auf die OpenOffice.org API zugreifen können, möglich ist, werde ich versuchen, in diesem Wiki nur über Methoden zuzugreifen. (Möglicherweise vergesse ich das auch das eine oder andere Mal).

Das nächste Beispiel zeigt, wie man einen Property-Wert für die aktuellen Selektionen ändert.

sub main
basicLibraries.loadLibrary("XrayTool")
if fnWhichComponent(thisComponent) = "Text" then
   oCurSelection = thisComponent.getCurrentSelection()
   if oCurSelection.supportsService("com.sun.star.text.TextRanges") then
      nCount = oCurSelection.Count
      'xray.xray oCurSelection.getByIndex(0)
      'Warnung: Am Einfügepunkt wird die selbe Aktion zwei mal angewandt -
      'das macht in diesem Fall nichts, kann aber durchaus problematisch werden.
      for i = 0 to nCount - 1
         oCurSelection.getByIndex(i).setPropertyValue("CharStyleName", "Strong Emphasis")
      next
   end if
end if
end sub

In OpenOffice.org Basic kann man die Zuweisung auch abkürzen:

oCurSelection(i).CharStyleName = "Strong Emphasis"

Hier in diesem Wiki versuche ich, sowohl zur Indexierung als auch zur Zuweisung von Properties die vollständigen Methoden zu verwenden. Dadurch kann der Code leichter in andere Sprachen portiert werden und es hilft Ihnen auch, zu verstehen, was vor sich geht (nochmal: Bitte um Entschuldigung, wenn ich mal von dieser Regel abweiche, weil ich es eigentlich nicht gewohnt bin)

Übung 2: Schreiben Sie den obigen Code so um, dass die Warnung entfernt werden kann.

Siehe DE/Aktuelle Selektion ( Current selection).

Iterativer Zugriff auf untergeordnete Objekte
( berechtigungsgesteuerte Auflistung )

Manchmal ist zum Zugriff auf ein gewünschtes Objekt eine Enumeration (Auflistung) nötig. Beispielsweise ein Absatz innerhalb eines Dokumentes oder innerhalb einer Auswahl.

Wenn ein OpenOffice-Writer Dokument aktiviert ist und Text ausgewählt wird, können beide Methoden thisDocument.getText() und thisComponent.getCurrentSelection().getByIndex(i) verwand werden. com.sun.star.text.TextRange ist die Schnittstelle (Interface): com.sun.star.container.XContentEnumerationAccess, wodurch es möglich ist, eine Auflistung aller Absätze des aktuellen Dokuments oder für eine einzelne Auswahl zu erhalten.

' Create enumeration object
oTextElementEnum = thisComponent.getText().createEnumeration()
'or thisComponent.getCurrentSelection().getByIndex(i).createEnumeration()
 
' loop over all text elements
while oTextElementEnum.hasMoreElements()
        oTextElement = oTextElementEnum.nextElement
        if oTextElement.supportsService("com.sun.star.text.TextTable") then
                MsgBox "The current block contains a table."
        end if
        if oTextElement.supportsService("com.sun.star.text.Paragraph") then
                MsgBox "The current block contains a paragraph."
        end if
wend

Aufgabe 3: Erweitere das obige Beispiel so, das eine MessageBox aller Worte des Schrifttyps "bold" zeigt .

Benannte Zugriffe

Einige Objekte bieten benannte Zugriffe auf einzelne Typen von untergeordneten Objekten an, einige andere indizierten Zugriff, und manche benannten und indizierten Zugriff.

Wenn zum Beispiel das aktuelle Dokument in OpenOffice.org ein Arbeitsblatt ist, dann kann der Zugriff auf ein einzelnes Blatt durch einen indizierten Zugriff erfolgen:

oSheet = thisComponent.getSheets.getByIndex(0)

oder mit benanntem Zugriff:

oSheet = thisComponent.getSheets.getByName("Sheet1")

Um zu überprüfen, ob ein Objekt mit einem einzelnen Namen schon existiert, benutzt man hasByName, zum Beispiel:

if thisComponent.getSheets.hasByName("Sheet1") then

Eine Schleife durch alle verfügbaren Objektnamen kann in der Art erfolgen:

mNames = thisComponent.getSheets.getElementnames
for i = lbound(mNames) to ubound(mNames)
        msgbox mNames(i)
next


Einige untergeordnete Objekte bieten ebenfalls eine Schnittstelle an: com.sun.star.container.XNameContainer. Diese Schnittstelle definiert, dass auf solche Objekte die folgenden Methoden angewendet werden können: insertByName, replaceByname and removeByName.

Z.B.

thisComponent.getSheets.insertByName("NewSheet")

Neue Objekte erstellen

Einige Objekte bieten Dienste, die Schnittstellen beinhalten, die spezielle Methoden für die Erstellung von einzelnen Objekt-Typen anbieten.

Wenn z.B. das aktuelle Dokument ein Writer Dokument ist, dann ist thisComponent.getText ein Objekt, das den Service com.sun.star.text.Text zur Verfügung stellt, der das Interface com.sun.star.text.XSimpleText implementiert, das wiederum die Methoden createTextCursor und createTextCursorByRange definiert. Diese beiden Methoden erstellen einen Text-Cursor um auf den Text des Dokumentes zu zu greifen. Diese Cursor sind ziemlich unabhängig vom View-Cursor. Der View-Cursor ist auf dem Bildschirm sichtbar und wird vom Benutzer gesteuert (er kann auch vom Programm gesteuert werden), wohingegen der Text-Cursor auf dem Bildschirm nicht sichtbar ist und ausschließlich vom Programm kontrolliert wird. Der folgende Code Schnippsel zeigt das Erstellen eines neuen Text-Cursors, derart dass er an der Position des View-Cursors beginnt und dann unabhängig von diesem bewegt wird.

oVC = thisComponent.getCurrentController.getViewCursor
oCursor = oVC.getText.createTextCursorByRange(oVC)
oCursor.gotoStartOfSentence(false)
oCursor.gotoEndOfSentence(true)
msgbox oCursor.getString

Einige Objekte sind kontextabhängig und werden mit der Methode createInstance erstellt, die im Interface com.sun.star.lang.XMultiServiceFactory definiert wird. Z.B. um ein Rechteck zur ersten Seite eines Zeichnungs-Dokumentes hinzu zu fügen:

dim aPoint as new com.sun.star.awt.Point
dim aSize as new com.sun.star.awt.Size
 
aPoint.x = 1000
aPoint.y = 1000
 
aSize.Width = 10000
aSize.Height = 10000
 
oRectangleShape = thisComponent.createInstance("com.sun.star.drawing.RectangleShape")
oRectangleShape.Size = aSize
oRectangleShape.Position = aPoint
 
thisComponent.getDrawPages.getByIndex(0).add(oRectangleShape)

Dieses Beispiel benutzt auch UNO Structs. Weitere Erläuterungen zu UNO Structs siehe unten.

Einige Objekte sind kontextunabhängig. Benutzen Sie zu Ihrer Erstellung den OpenOffice.org Basic Befehl createUnoService. Z.B. um die Entsprechung zum StarDesktop zu erzeugen:

oDesktop = createUnoService("com.sun.star.frame.Desktop")

Ich nutze die folgende Vorgehensweise, um zu bestimmen, wie ich ein Objekt erstellen oder darauf zu greifen kann:

Existiert das Objekt bereits? Wenn ja, so sollte ich von etwas in der Art wie thisComponent darauf zu greifen können.

Wird das neue Objekt zu einem anderen Objekt gehören? Wenn ja: Hat der Besitzer eine spezifische Methode, um das Objekt zu erstellen? Wenn ja, so benutze ich diese.

Das neue Objekt wird zu einem anderen Objekt gehören, welches keine spezifische Methode zu seiner Erstellung bereit stellt, aber es bietet createInstance an. Wenn das Objekt createInstance nicht zur Verfügung stellt, sind Sie sicher, dass Sie das richtige Objekt verwenden, oder ist es kontextunabhängig?

Nach meiner Erfahrung ist es anhand der vorhandenen Dokumentation ziemlich schwierig, heraus zu finden, wie man ein Objekt erstellt, und ich hoffe, dass dieses Dokument/Wiki dies eventuell verdeutlicht.


UNO Structs

UNO Structures können mit dem OpenOffice.org Basic Befehl dim deklariert werden:

dim aPoint as new com.sun.star.awt.Point

Oder unter Verwendung des OpenOffice.org Basic Befehls createUnoStruct:

aPoint = createUnoStruct("com.sun.star.awt.Point")
Anmerkung: Beim Deklarieren von UNO Structs ist die Groß-/Kleinschreibung wichtig. Beachten Sie, dass alles bis zum Namen des Structs in Kleinbuchstaben steht, der Name des Structs dagegen in TitleCase.



Das Erzeugen von Listenern und Handlern

Mit Hilfe der Benutzeroberfläche ist es möglich, einigen Ereignissen Makros zu zu weisen:

  • in OOo 1.1.x ???
  • in OOo 1.9.x und höher unter Extras > Anpassen… > Ereignisse.

Mit Hilfe des OpenOffice.org Basic Befehls CreateUnoListener ist es möglich, einer breiteren Auswahl von Makros Ereignisse zu zu ordnen. Dieser Befehl wird zum Erzeugen sowohl von Listenern als auch von Handlern genutzt. Ein Listener überwacht das Auftreten eines Ereignisses und erlaubt dabei anderen Listenern immer, ebenfalls auf das Ereignis zu antworten. Ein Handler überwacht das Auftreten eines Ereignisses und kann wahlweise das Ereignis verbrauchen, so dass andere Listener nicht mehr dazu kommen, darauf zu reagieren.

Das folgende Beispiel erzeugt einen keyHandler:

global IannzExampleKeyHandler
 
sub SetupKeyHandler
oController = thisComponent.currentController
IannzExampleKeyHandler = CreateUnoListener("KeyHandler_","com.sun.star.awt.XKeyHandler")
oController.addKeyHandler(IannzExampleKeyHandler) ' Register the listener
end sub
 
 
sub RemoveKeyHandler
thisComponent.currentController.removeKeyHandler(IannzExampleKeyHandler)
end sub
 
 
sub KeyHandler_disposing
end sub
 
 
function KeyHandler_keyReleased(oKeyEvent as new com.sun.star.awt.KeyHandler) as boolean
        KeyHandler_keyReleased = False    
end function
 
 
function KeyHandler_keyPressed(oKeyEvent as new com.sun.star.awt.KeyHandler) as boolean
KeyHandler_keyPressed = false   'Let other listeners handle the event
if oKeyEvent.modifiers = com.sun.star.awt.KeyModifier.MOD2 then 'Control key was pressed
        if oKeyEvent.keyCode = com.sun.star.awt.Key.Q then
                msgbox "Alt + Q was pressed"
                KeyHandler_keyPressed = true    'Don't let other listeners process this event
        end if
end if
end function

Eine als global definierte Variable behält ihren Wert auch nachdem das Makro die Subroutine verlässt. In diesem Fall wollen wir die Variable später benutzen können, um den Handler zu entfernen. Da global definierte Variablen auch in anderen Bibliotheken benutzt werden könnten, lasse ich, um Konflikte möglichst zu vermeiden, alle meine globalen Variablen mit Iannz - meinem registrierten Namen für die OpenOffice.org Webseite - anfangen.

sub SetupKeyHandler erstellt den Handler. Der erste Parameter für CreateUnoListener ist der Anfang des Namens für die Methoden, die beim Auftreten dieses Ereignisses aufgerufen werden; in diesem Beispiel "KeyHandler_".

Der zweite Parameter ist der Name des Interface für den Listener oder Handler, "com.sun.star.awt.XKeyHandler". Der Name ist case sensitive: alles bis einschließlich des Modulnamnes steht immer in Kleinbuchstaben, der Name des Interface beginnt immer mit "X" und der Rest steht in TitleCase.

Nutzen Sie das SDK, um heraus zu finden, welche Methoden das Interface bereit stellen muss. Sie müssen für alle diese Methoden Routinen zur Verfügung stellen, selbst wenn Sie nicht beabsichtigen, sie zu verwenden. Sie müssen auch eine Methode bereitstellen, die den Listener/Handler entfernt. Die Namen dieser Routinen beginnen mit dem im ersten mit CreateUnoListener übergebenen Parameter enthaltenen String, im Beispiel "KeyHandler_".

So gibt es im Beipiel die Routinen KeyHandler_disposing und KeyHandler_keyReleased, die nichts tun, aber benötigt werden. KeyHandler_keyPressed erledigt die eigentliche Aufgabe.

sub RemoveKeyHandler zeigt, wie man den Handler entfernt.

OpenOffice.org Konstanten

Das obige Beispiel benutzt OpenOffice.org Konstanten

Z.B. com.sun.star.awt.KeyModifier.MOD2

OpenOffice.org Konstanten sind case sensitive. Alles bis einschließlich des Modulnamens steht immer in Kleinbuchstaben. Die Gruppe der Konstanten steht in TitleCase. Der eigentliche Name der Konstanten steht immer in GROßBUCHSTABEN:

Programmierer, die nicht OpenOffice.org Basic benutzen, haben eventuell keinen Zugriff auf diese Konstanten.


Die Benutzung des Rekorders

Im Beitrag The OpenOffice.org recorder and UNO dispatch calls finden sie eine Diskussion über das Aufnehmen von UNO Dispatch Befehlen im Gegensatz zum Schreiben von API Aufrufen.

Personal tools