Basic-Skripte in LibreOffice Calc

Aus EasyLinux 03/2013

Basic-Skripte in LibreOffice Calc

Tabellen programmieren

Die Tabellenkalkulation LibreOffice Calc eignet sich besonders gut für den Einstieg ins Programmieren, denn wer schon mit Formeln in Tabellen umgehen kann, hat bereits den halben Weg zum Programmierer zurückgelegt. Hier zeigen wir Ihnen den Rest des Wegs.

Manche Anwender verwenden Calc (oder Excel unter Windows) nur dazu, Text und Zahlen in einem praktischen Zeilen- und Spaltenschema einzugeben – das ist aber nicht Sinn und Zweck einer Tabellenkalkulation (und eine Tabelle im Textprogramm Writer würde die Aufgabe genauso gut erfüllen). Der Name “Kalkulation” sagt es schon: Dieses Programm kann rechnen, und zwar mit den Daten, die Sie in die Tabellenfelder eintragen.

Das einfachste Beispiel, mit dem sich Calc-Benutzer oft zuerst vertraut machen, ist die Summenberechnung. Wenn Sie die Felder A1 bis A5 mit fünf Zahlen (z. B. Euro-Beträgen) gefüllt haben und nun die Summe dieser fünf Zahlen herausfinden möchten, gibt es zwei Wege:

  • Sie markieren einfach die fünf Zellen mit der Maus – in der Statusleiste zeigt Calc dann den Hinweis Summe = an.
  • Soll die Summe auch in der Tabelle (dauerhaft) auftauchen, verwenden Sie dazu eine Summenformel: Sie springen z. B. ins Feld A7 und geben darin =SUMME(A1:A5) ein. Sobald Sie [Eingabe] drücken, ersetzt Calc die Formel durch das Ergebnis der Berechnung. Springen Sie wieder in das Feld mit der Formel zurück, steht dort weiterhin der ausgerechnete Wert, aber in der Eingabezeile (unterhalb der Symbolleiste) erscheint die verwendete Formel.

Was hat das mit Programmieren zu tun? Auf den ersten Blick wenig, aber SUMME ist eine Funktion, die Calc Ihnen zur Verfügung stellt. Es gibt neben SUMME noch zahlreiche weitere eingebaute Funktionen, etwa MITTELWERT für die Durchschnittsberechnung oder MAX und MIN, um den größten bzw. kleinsten Wert (Maximum und Minimum) einer Reihe von Zahlen zu bestimmen.

Ergänzend zu den eingebauten Funktionen wie SUMME können Sie auch eigene Funktionen programmieren und dann in der Tabelle benutzen. Interessiert Sie z. B. der Mittelwert von Maximum und Minimum, dann könnten Sie mit Hilfe der eingebauten Funktionen

=(MAX(A1:A5)+MIN(A1:A5)) / 2

schreiben. Brauchen Sie diese Berechnung häufiger in Ihrer Tabelle, ist es lästig, diesen langen Ausdruck immer wieder einzugeben, zumal vielleicht die Anzahl der Werte abweicht, so dass Sie die Formel nicht einfach von Zelle zu Zelle kopieren können.

– oder Sie basteln sich eine eigene Funktion MeinWert.

Rufen Sie den ein wenig versteckten Menüeintrag Extras / Makros / Makros verwalten / LibreOffice Basic auf – es öffnet sich dann ein neues Fenster (Abbildung 1), das links in einer Baumstruktur auch Ihr aktuelles Dokument anzeigt (im Beispiel: easylinux01.ods). Der Eintrag Meine Makros sollte einen Untereintrag Standard haben, und darunter finden Sie Module1. Im rechten Bereich steht unter Vorhandene Makros in Module1 nur Main: Klicken Sie auf diesen Eintrag und dann auf Bearbeiten.

Abbildung 1: Aus Calc heraus rufen Sie die Verwaltung der Makros auf. Über "Bearbeiten" aktivieren Sie den Editor.

Abbildung 1: Aus Calc heraus rufen Sie die Verwaltung der Makros auf. Über “Bearbeiten” aktivieren Sie den Editor.

Der Dialog verschwindet, und stattdessen erscheint ein Editor-Fenster, in dem Sie programmieren können (Abbildung 2). Zunächst stehen dort nur ein Kommentar und eine leere Prozedur namens Main.

Abbildung 2: Im Editor können Sie Funktionen und Prozeduren eingeben, die Sie dann in Calc-Tabellen nutzen.

Abbildung 2: Im Editor können Sie Funktionen und Prozeduren eingeben, die Sie dann in Calc-Tabellen nutzen.

Wechseln Sie in dieses Fenster und springen Sie im rechten Editor-Bereich ans Ende. Fügen Sie dort eine Leerzeile und dann den Code aus Listing 1 ein. Das ist noch nicht die Lösung, sondern ein Teil des Wegs dorthin: Wenn Sie nun in die Tabelle zurück wechseln und in eine freie Zelle die Formel

=MeinWert(A1:A5)

eingeben, erscheint darin ein Text, der aus den fünf Zellinhalten (von A1 bis A5) besteht; die Werte sind darin durch Leerzeichen voneinander getrennt. Der Sinn dieses ersten Listings ist, dass Sie erkennen, wie Sie auf die Zellen zugreifen können, die Sie über die Formel =MeinWert(A1:A5) an die Funktion übergeben.

Listing 1

MeinWert

Function MeinWert (Zellen)
  Ausgabe = ""
  For Zeile = LBound(Zellen, 1) To UBound(Zellen, 1)
    For Spalte = LBound(Zellen, 2) To UBound(Zellen, 2)
      Ausgabe = Ausgabe + Str( Zellen(Zeile, Spalte) )
    Next
  Next
  MeinWert = Ausgabe
End Function

Da die BASIC-Funktion nicht wissen kann, wie viele Zellen zu bearbeiten sind, nutzt sie die Funktionen LBound (Lower Bound) und UBound (Upper Bound), die für einen rechteckigen Bereich jeweils den kleinsten und größten Zeilen- oder Spalten-Index zurück geben: Wenn das zweite Argument 1 ist, geht es um Zeilen, beim Wert 2 um Spalten.

Damit die Funktion alle Zelleninhalte auswerten kann, verwendet sie eine geschachtelte Schleife: Die äußere Schleife läuft über alle Zeilennummern, die innere über alle Spaltennummern, und der Zugriff auf die Zellen ist dann über Zellen (Zeile, Spalte) möglich – Zellen hat die Funktion als Argument erhalten.

Wichtig ist hier zu verstehen, dass Sie zwar in der Tabelle die Formel =MeinWert(A1:A5) verwenden können, dass aber A1:A5 nicht das Argument ist, das die Funktion erhält. Auf dem Weg von der Tabelle in die Funktion wird A1:A5 in ein zweidimensionales Array umgewandelt, dessen Elemente die Funktion über die Indizes (Spalte, Zelle) anspricht.

BASIC-Funktionen in LibreOffice geben einen Wert immer durch eine Zuweisung zurück, im Beispiel MeinWert = Ausgabe. Was wie das Setzen einer Variable aussieht, ist tatsächlich die Festlegung des Rückgabewerts; Sie erkennen das nur daran, dass hier der Name der Funktion verwendet wird.

Maximum und Minimum

Zurück zur Aufgabenstellung: Das Ziel war, in der Tabelle anstelle von

=(MAX(A1:A5)+MIN(A1:A5)) / 2

die Formel

=MeinWert(A1:A5)

verwenden zu können. In Listing 1 sind im Prinzip schon die wichtigsten Features enthalten, um das zu erreichen – nämlich der Zugriff auf alle Zellen. Auf den ersten Blick könnte man hoffen, dass die Aufgabe viel leichter ist: Wenn Sie in die MeinWert-Funktion nur MeinWert = (Max(Zellen)+Min(Zellen))/2 schreiben, funktioniert das nicht: Es gibt im BASIC keine Max– und Min-Funktionen, also müssen wir deren Funktionalität nachbauen.

Die Lösung der Aufgabe sehen Sie in Listing 2. Das Kernstück bildet auch hier die geschachtelte Schleife, die Sie schon aus Listing 1 kennen. Innerhalb der Schleife berechnet die Funktion nun das Maximum und das Minimum. Das funktioniert so:

  • Vor der Schleife ermittelt die Funktion die Indizes der ersten betroffenen Zelle und speichert diese in den Variablen StartX und StartY.
  • Über Zellen (StartX, StartY) liest sie den Wert in der ersten Zelle aus und speichert ihn sowohl in Max als auch Min – das sind die provisorischen Maximums- und Minimumswerte.
  • In der Schleife vergleicht die Funktion nun nacheinander alle Zelleninhalte mit den jeweils aktuellen Werten von Max und Min. Ist der neue Wert größer bzw. kleiner, wird Max oder Min aktualisiert.
  • Nach der Schleife enthalten Max und Min wirklich den größten und den kleinsten Wert; damit kann die Funktion über MeinWert = (Max+Min)/2 das Ergebnis berechnen und zurückgeben.

Listing 2

Maximum ermitteln

Function MeinWert (Zellen)
  StartX = LBound (Zellen, 1)
  StartY = LBound (Zellen, 2)
  Min = Zellen (StartX, StartY)
  Max = Min
  For Zeile = LBound(Zellen, 1) To UBound(Zellen, 1)
    For Spalte = LBound(Zellen, 2) To UBound(Zellen, 2)
      If Zellen (Zeile, Spalte) < Min Then
        Min = Zellen (Zeile, Spalte)
      End If
      If Zellen (Zeile, Spalte) > Max Then
        Max = Zellen (Zeile, Spalte)
      End If
    Next
  Next
  ' Jetzt stehen in Min und Max die Extremwerte
  MeinWert = (Max + Min) / 2
End Function

In der Tabelle steht noch der alte Wert (den die Funktion MeinWert in der Fassung aus Listing 1 berechnet hat). Um den Wert zu aktualisieren, können Sie überraschenderweise nicht den Menüpunkt Extras / Zellinhalte / Neuberechnen oder [F9] verwenden – es gibt stattdessen zwei Möglichkeiten, wie Sie Calc mitteilen können, die Funktion neu aufzurufen:

  • Der leichteste Weg ist, eine der Zellen, die an der Berechnung beteiligt sind, zu markieren und dann mit [Strg]+[C] und [Strg]+[V] ihren Inhalt erst in die Zwischenablage zu kopieren und dann direkt wieder an derselben Position einzufügen. Das ist eine sinnlose Aktion, die aber schnell erledigt ist und den gewünschten Nebeneffekt hat, dass der Funktionswert neu berechnet wird.
  • Alternativ klicken Sie in die Zelle, in der die Formel steht, drücken [F2] und “bearbeiten” die Formel, indem Sie ein Leerzeichen einfügen und wieder löschen. Auch das führt zum gewünschten Ergebnis.

Sprachelemente

Die zwei Beispiele enthalten schon vier wichtige Elemente von Programmiersprachen:

  • Die Arbeit mit Variablen: In LibreOffice Basic können Sie Variablen einfach einführen, indem Sie damit arbeiten – es ist nicht nötig, sie vorab zu deklarieren. In größeren Programmierprojekten ist das aber sinnvoll und darum auch möglich. In Abbildung 3 sehen Sie eine Variante der Funktion, in der die verwendeten Variablen vorab mit dem Befehl Dim deklariert werden; der klassische BASIC-Befehl heißt Dim, weil er früher nur dazu verwendet wurde, Arrays zu erstellen – dabei musste man die Anzahl der Einträge des Arrays angeben, also seine Dimension festlegen.
Abbildung 3: Diese Version der Funktion "MeinWert" deklariert die verwendeten Variablen mit "Dim".

Abbildung 3: Diese Version der Funktion “MeinWert” deklariert die verwendeten Variablen mit “Dim”.

  • Schleifen: Das Programm enthält zwei For-Schleifen, die einfache Zählschleifen sind. Es gibt noch weitere Schleifen, z. B. While- und For-Each-Schleifen.
  • Fallunterscheidung: Über die Schlüsselworte If, Then, Else und End If prüfen Sie eine Bedingung und legen fest, was in den beiden möglichen Fällen passiert. Ein Beispiel mit Else ist bisher nicht vorgekommen – im Listing in Abbildung 3 haben wir darum einen (sinnlosen) Else-Fall hinzugefügt, damit Sie die Syntax erkennen.
  • Funktionsaufrufe: Die Funktion MeinWert ruft zwei weitere Funktionen auf: LBound und UBound. Genauso wird es auch aussehen, wenn Sie weitere Funktionen schreiben, die einander aufrufen können.

Prozeduren

Anders als Funktionen definieren Sie Prozeduren über das Schlüsselwort Sub. Diese sind eher geeignet, um z. B. auf Tastendruck Aufgaben automatisch auszuführen. Auch wenn Sie den Makrorekorder verwenden, entstehen solche Prozeduren.

Als kleines Beispiel zeigen wir Ihnen eine Prozedur, welche nur die Zelle C7 untersucht und eine kleine Dialogbox öffnet, in der sie mitteilt, ob die Zelle eine Zahl, einen Text oder eine Formel enthält.

Um auf das erste Tabellenblatt zuzugreifen, benötigen Sie den Code

Blatt = thisComponent.getSheets.getByIndex(0)

(thisComponent ist das geöffnete Dokument, und über getSheets.getByIndex(0) sprechen Sie das erste Tabellenblatt an: Die Nummerierung beginnt bei 0.) Danach enthält die Variable Blatt den Verweis auf das erste Tabellenblatt. Jetzt sind Sie fast am Ziel: Einzelne Zellen in diesem Blatt sprechen Sie über getCellByPosition() an und müssen zwei Argumente (Spalte und Zeile) verwenden. Die Nummerierung der Spalten und Zeilen beginnt auch hier intern bei 0 – Vorsicht: Calc beginnt in der normalen Tabellenansicht mit Zeile 1 und Spalte A; die Zelle C7 wird also in LibreOffice-Basic-Notation zu (2,6) – dritte Spalte, siebte Zeile. Sie erreichen diese Beispielzelle über

Zelle = Blatt.getCellByPosition(2,6)

Auf den Inhalt dieser Zelle können Sie nun mit drei unterschiedlichen Objektfunktionen zugreifen:

  • getValue() gibt einen Zahlenwert des Zellinhalts zurück – egal, ob die Zelle eine Zahl oder eine Formel enthält: im Fall einer Formel berechnet Basic diese und gibt das Ergebnis zurück. Wenn die Zelle Text enthält, ist der Rückgabewert 0.
  • getString() gibt den Text zurück, der in der Tabelle steht. Das ist der Wert, den Sie in der normalen Tabellenansicht sehen können, egal ob dem ein Wert, eine Formel oder wirklich einfacher Text zugrundeliegt.
  • getFormula() schließlich gibt bei einer Formelzelle die enthaltene Formel zurück. Steht in der Zelle keine Formel, ist der Rückgabewert derselbe String, den auch getString() zurückgeben würde.

Um herauszufinden, von welchem Typ eine Zelle ist (Wert, Text, Formel), verwenden Sie die Funktion getType(), die vier mögliche Rückgabewerte hat: 0 (leere Zelle), 1 (Wert), 2 (Text) und 3 (Formel). Die Beispielzelle C7 könnten Sie also wie folgt auswerten:

t = Zelle.getType()
Select Case t
  Case 0
    print "C7 ist leer"
  Case 1
    print "C7 enthält Wert " + Zelle.getValue()
  Case 2
    print "C7 enthält Text " + Zelle.getString()
  Case 3
    print "C7 enthält Formel " + Zelle.getFormula() + " mit Wert " + Zelle.getValue()
  Case Else
    print "Fehler"
End Select

Anstelle mehrerer IfThen-Blöcke haben wir hier den Befehl Select verwendet: Er vergleicht die Variable t mit den Werten 0, 1, 2 und 3 und gibt dann passende Informationen aus. Der letzte Fall (Case Else) sollte nicht auftreten, deswegen gibt das Programm in dem Fall eine Fehlermeldung aus. Abbildung 4 zeigt die komplette Prozedur.

Abbildung 4: Eine Prozedur, die eine bestimmte Zelle untersucht, ist schnell geschrieben.

Abbildung 4: Eine Prozedur, die eine bestimmte Zelle untersucht, ist schnell geschrieben.

Prozedur ausführen

Wenn Sie nun zur Tabellenansicht zurückschalten, können Sie das Makro Main ausführen: Tragen Sie zunächst etwas in Zelle C7 ein, damit das Makro passendes Futter findet. Dann rufen Sie den Menüpunkt Extras / Makros / Makro ausführen auf. Wenn jetzt eine Fehlermeldung über eine fehlende Java-Laufzeitumgebung auftaucht, klicken Sie diese einfach weg; sie ist nicht wichtig.

Es erscheint der Dialog Makro-Selektor, in dem Sie links unter Bibliothek zunächst die Baumstruktur unter Meine Makros vollständig öffnen, bis Sie (wie in der Abbildung) den Unterpunkt Meine Makros / Standard / Module1 sehen können. Klicken Sie dann auf den Eintrag Module1, erscheint rechts unter Name des Makros eine Liste aller von Ihnen erstellten Makros – im Beispiel also nur das Makro Main. Markieren Sie es und klicken Sie auf Ausführen. Dann schließt sich das Dialogfenster, und das Makro startet. Es präsentiert eine Infobox mit der gewünschten Beschreibung von Zelle C7.

Der Weg über den Makro-Selektor ist allerdings sehr umständlich – einfacher ist es, wenn Sie einen Menüeintrag dafür anlegen oder eine Tastenkombination vergeben, die das Makro aufruft. Klicken Sie ins Calc-Fenster und rufen Sie den Menüpunkt Extras / Anpassen auf. Es öffnet sich ein neues Fenster, das die Menüstruktur von Calc anzeigt. Unter LibreOffice Calc Menüs wählen Sie Extras aus und klicken dann rechts auf Hinzufügen. Ein weiteres Fenster erscheint (Abbildung 5). Scrollen Sie hier die linke Liste (Bereich) ganz nach unten und klappen Sie den Eintag LibreOffice Makros auf, so dass Sie den schon bekannten Punkt Meine Makros / Standard / Module1 sehen. Klicken Sie auf Module1; rechts stehen dann wieder Ihre selbst erstellten Makros. Wählen Sie das Makro Main aus und klicken Sie auf Hinzufügen und Schließen.

Abbildung 5: Makros aufzurufen ist umständlich. Erzeugen Sie dafür einfach neue Menüpunkte.

Abbildung 5: Makros aufzurufen ist umständlich. Erzeugen Sie dafür einfach neue Menüpunkte.

Bei den Menüeinträgen im Anpassen-Fenster ist ein neuer Punkt Main hinzugekommen. Da der Name nicht sehr ausdrucksstark ist, ändern Sie den Namen: Wählen Sie aus dem Drop-down-Menü Ändern den Eintrag Umbenennen aus und geben Sie im sich öffnenden Dialog einen sinnvollen Text ein, z. B. Testmakro ausführen. Dann schließen Sie den Anpassen-Dialog mit einem Klick auf OK – jetzt sollten Sie den neuen Menüpunkt Extras / Testmakro ausführen im Calc-Menü finden – und damit lässt sich schon komfortabler arbeiten.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDF
EasyLinux 03/2013 KAUFEN
EINZELNE AUSGABE
ABONNEMENTS
TABLET & SMARTPHONE APPS
E-Mail Benachrichtigung
Benachrichtige mich zu:

Hinweis: Dieser Artikel ist älter als ein Jahr, enthaltene Informationen sind möglicherweise veraltet.

0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben