Domino: Formelsprache und Feldwerte

01.01.2007 von Elmar Fuchs
Für die meisten Notes-Programmierer ist die Formelsprache die Basis für den Einstieg in die Entwicklung. Seit jeher hat sie ihre Stärken in der Manipulation offener Dokumente und in der Steuerung und Unterstützung der Benutzerdialoge. Sie bietet verschiedene Funktionen, um Feldwerte in Dokumenten zu lesen und zu schreiben. Mit der Version 6 wurde die Formelsprache komplett neu implementiert.

Aufgrund ihrer internen Umsetzung in den frühen Versionen von Lotus Notes Domino war die Formelsprache für ihrer Überarbeitung nicht sonderlich performant. Gängige, aus anderen Programmiersprachen bekannte Techniken, wie beispielsweise die wiederholte Ausführung von Anweisungen durch eine bedingte Schleife, waren nicht möglich. Von vielen Entwicklern wurde die Formelsprache deshalb als minderwertige Möglichkeit angesehen, mit der zu beschäftigen sich nicht lohnt.

Mit der nun schon einige Jahre zur Verfügung stehenden Version 6 hat sich diese Situation grundlegend geändert. Die Formelsprache wurde komplett neu implementiert. Im Ergebnis ist sie nicht nur wesentlich schneller, sondern es sind jetzt auch viele der bereits angesprochenen gängigen Techniken verfügbar. Damit steht dem Entwickler ein leistungsstarkes Werkzeug zur Verfügung, das seine Stärken bei allen Fragen der Frontend-Entwicklung voll ausspielt. Häufig ist es wesentlich einfacher (und schneller), Aktionen und Befehlsfolgen in der Formelsprache zu realisieren, als LotusScript-Code zu schreiben.

Dazu kommt, dass die Stärken von LotusScript eindeutig im Backend liegen. Kann ein Ereignis oder eine Aktion im Frontend sowohl mit der Formelsprache als auch mit LotusScript realisiert werden, sollte man zumindest überlegen, ob es an dieser Stelle wirklich LotusScript bedarf. Daneben gibt es natürlich nach wie vor Bereiche, für die ohnehin nur die Formelsprache zur Verfügung steht.

Funktionen und Feldwerte

In diesem Artikel wollen wir uns mit einigen Funktionen beschäftigen, die es ermöglichen, Feldwerte innerhalb des aktuellen Dokuments oder in anderen Dokumenten zu lesen oder zu schreiben. Darüber hinaus betrachten wir noch Funktionen, welche in diesem Kontext häufig Verwendung finden. Im Einzelnen sind dies die folgenden @Funktionen:

Die Tabelle auf der nächsten Seite bietet einen Überblick über die einzelnen Funktionen.

Funktionsüberblick

Tabelle 1: Die verschiedenen Funktionen der Formelsprache zum Auslesen von Feldwerten.

Funktion

Beschreibung

FIELD

Das reservierte Wort FIELD setzt einen Feldwert in einem Dokument, der Wert wird in jedem Fall gespeichert

Default

Default kann temporäre Feldwerte setzen, sodass diese in Formeln genutzt werden kann.

@SetField

Die Funktion schreibt den Wert in ein Feld des aktuellen Dokuments. Im Unterschied zu FIELD kann @SetField innerhalb anderer @Funktionen verwendet werden.

@Set

@Set erstellt einen temporären Wert in einem Dokument.

@GetField

Die Funktion liest den Wert eines Feldes im aktuellen Dokument aus.

@DocumentUnidID

Mit der Funktion @DocumentUnidID können Sie die UNID des aktuellen Dokuments ermitteln.

@GetDocField

Verwenden Sie diese Funktion zum Auslesen eines Feldwertes eines nicht aktiven Dokuments. Als Parameter wird unter anderen die UNID des Zieldokuments benötigt.

@SetDocField

Das Gegenstück zu @GetDocField schreibt einen Feldwert in ein nichtaktives Dokument. Die Funktion benötigt ebenfalls die UNID des Zieldokuments.

@GetProfileField

Die Funktion liest den Wert eines Feldes in einem Profildokument aus.

@SetProfileField

Mit dieser Funktion schreiben Sie einen Wert in ein Profildokument.

@UpdateFormulaContext

Durch die Verwendung der Funktion @UpdateFormulaContext ist es möglich, den Kontext während der Ausführung einer Formel zu wechseln.

Felder im aktuellen Dokument

Das Schlüsselwort FIELD wird genutzt, um einem Feld in einem Dokument einen Wert zuzuweisen. Das Feld wird in jedem Fall im Dokument gespeichert. Ein vorhandener Wert wird dabei überschrieben. Ist das Feld noch nicht

vorhanden, wird es erstellt. Im Unterschied dazu können Sie mit dem reservierten Wort Default ein temporäres Feld für den Zeitraum einer Berechnung in einem Dokument erstellen.

Im folgenden Beispiel wird dem Feld Status der Textwert Erledigt zugewiesen.

FIELD Status := "Erledigt";

Der Einsatz des reservierten Wortes Field unterliegt der Einschränkung, dass es nicht innerhalb von @Funktionen eingesetzt werden kann. Für derartige Anwendungsfälle steht Ihnen die Funktion @SetField zur Verfügung, deren Funktionsumfang ansonsten dem von Field entspricht. Die Funktion im Beispiel:

Temp := @Prompt([YesNo];"Reservierung"; "Wollen Sie das Zimmer reservieren?");
@If(Temp=1; @SetField("Reserviert"; "Reserviert");
@SetField("Reserviert"; "Zimmer frei"));

Die Formel wird beim Betätigen einer Schaltfläche ausgeführt. Der Anwender kann in einem Ja/Nein-Dialog entscheiden, ob er ein Zimmer reservieren möchte. Klickt er auf Ja (Rückgabewert 1), wird über die Funktion @SetField die Zeichenfolge Reserviert eingetragen, andernfalls Zimmer frei.

Mit der Funktion @Set besitzt @SetField ebenfalls ein Pendant zum Zuweisen temporärer Werte.

Neu seit der Version 6 ist die Funktion @Get-Field. Sie ermöglicht das Auslesen eines Feldwerts im aktuellen Dokument. Besonders praktisch ist dabei der Umstand, dass Sie als Feldname eine berechnete Zeichenkette übergeben können. Somit ist es möglich, die Werte mehrerer Felder, welche über einen gemeinsamen Wortstamm verfügen, innerhalb einer Schleife auszuwerten.

Existieren beispielsweise in einer Maske die Felder Monat_1, Monat_2 bis Monat_12, können Sie die Gesamtsumme der einzelnen Felder über eine Schaltfläche mit folgender Formel in das Feld Jahreswert eintragen lassen:

temp := 0;
@For(
n := 1;
n < 13;
n := n + 1;
temp := temp + @GetField("Monat_"+@Text(n)));
@SetField("Jahreswert"; temp);

Bei der Anwendung der Funktion sind zwei Besonderheiten zu beachten: Zum einen gibt die @Funktion für den Fall, dass das angegebene Feld nicht vorhanden ist, eine leere Zeichenfolge zurück. Zum zweiten liefert sie für Felder mit der aktivierten Eigenschaft Mehrfachwerte zulassen nur den ersten Wert.

Zugriff auf andere Dokumente

Sowohl Field und Default als auch @SetField, @Set und @GetField ist gemeinsam, dass sie nur Zugriff auf (temporäre) Felder im aktuellen Dokument erlauben.

Wollen Sie Feldwerte in einem nicht aktiven Dokument lesen bzw. schreiben, nutzen Sie dafür die Funktionen @GetDocField und @SetDoc-Field. Das Dokument muss sich jedoch unbedingt in der aktuellen Datenbank befinden. Beide benötigen als ersten Parameter die universelle Dokument-ID (UNID) des Dokuments, auf welches zugegriffen wird. Dabei handelt es sich um eine zweiunddreißigstellige Zeichenfolge aus hexadezimaler Ziffern, das heißt, die einzelnen Zeichen umfassen die Wertebereiche 0..9 und A..Z.

Bild 1: Die UNID eines Dokuments kann über eine Formel abgefragt werden.

Die UNID kennzeichnet jedes Dokument innerhalb einer Datenbank auch beim Vorhandensein mehrerer Repliken eindeutig. Zur Angabe der UNID stehen Ihnen drei Möglichkeiten offen:

Bild 2: Sie können die UNID auch bei den Dokumenteigenschaften ermitteln.

Zugriff auf andere Dokumente II

Eine mögliche Anwendung der Funktion @GetDocField zeigt der Befehl

FIELD Projektleiter := @GetDocField($Ref; "Projektleiter");

Der Befehl ermittelt für das Feld Projektleiter in einem Antwortdokument den Feldinhalt aus dem gleichnamigen Feld im zugehörigen Hauptdokument. Eine mögliche Anwendung wäre ein periodischer Agent, welcher das Antwortdokument auf Basis eventueller Änderungen im Hauptdokument aktualisiert.

Bild 3: Der Zugriff mit der Formel @DocumentUniqueID.

Wollen Sie für den Zugriff eines anderen Dokuments mit @SetDocField oder @GetDocField die UNID eines Dokuments bereitstellen, erstellen Sie dafür eine verborgene Ansicht. Die UNID können Sie in einer Spalte als berechneten Wert mit der Formel

@Text(@DocumentUniqueID)

(Bild 3) oder besser im Dokument als berechnetes verborgenes Feld hinterlegen, welches Sie in der Ansicht unter Angabe des Feldnamens auslesen. Die Angabe der UNID in der zugreifenden Funktion erfolgt dann unter Verwendung der Funktion @DBLookup.

Zugriff auf andere Dokumente III

Im Beispiel wird in einer Ansicht über eine Aktionsschaltfläche der Name eines Referenten in das Feld Referent des ausgewählten Seminardokuments eingetragen. Dazu wird die UNID mittels einer Abfrage an die verborgene Ansicht unter Verwendung der im Dokument hinterlegten Seminarnummer ermittelt. Den Namen des Referenten kann der Anwender über eine Dialogbox eingeben, als Standardwert wird Schneider vorgeschlagen:

@SetDocField(
@DbLookup("":""; "":""; "(Dok-IDs)"; @GetField("SeminarNr");2);
"Referent";
@Prompt([OkCancelEdit];"Referent"; "Geben Sie den Namen des Referenten ein";"Schneider"))

Seit der Version 6 können Sie @SetDocField auch verwenden, um Feldwerte innerhalb des aktuellen Dokuments zu verändern. In diesem Fall verwenden Sie einfach die Funktion @DocumentUniqueID zur Angabe der UNID:

@SetDocField(@DocumentUniqueID; "Status"; "Erledigt");

Profildokumente

Profildokumente können für eine Datenbank insgesamt oder für jeden einzelnen Benutzer der Datenbank erstellt werden. In diesen Dokumenten werden auf Basis einer Maske spezifische Werte gespeichert, welche permanent während der Verwendung der Datenbank zur Verfügung stehen sollen. Zu diesem Zweck werden die Dokumente im Cache zwischengespeichert. Weitere Besonderheiten sind, dass Profildokumente nicht in Ansichten angezeigt und auch nicht bei Dokumentzählungen in der Datenbank erfasst werden.

Für den Zugriff auf Profildokumente stehen verschiedene Möglichkeiten offen. Im Befehlsvorrat der Formelsprache ist die Funktion @CommandEditProfile enthalten, welche unter Angabe des Maskennamens ein neues Profildokument erstellt bzw. ein vorhandenes öffnet.

Zum Lesen und Schreiben von Feldwerten in Profildokumenten aus anderen Dokumenten oder Aktionen heraus dienen die zwei speziellen @Funktionen @GetProfileField und @SetProfile-Field.

Der folgende Befehl liest das Feld Kategorien des Datenbankprofildokuments DBProfil:

@GetProfileField("DBProfil"; "Kategorien")

Das Ergebnis kann beispielsweise in einer Maske im Feld Auswahl eines Feldes vom Typ Kombinationsfeld bei der Einstellung Formel für Auswahl verwenden genutzt werden. Alle im Feld Kategorien enthalten, Werte würden dem Anwender damit als Elemente des Kombinationsfeldes angeboten.

Umgekehrt können Sie die in einem Feld eines Profildokuments gespeicherten Werte mit der Funktion @SetProfileField festlegen:

@SetProfileField("DBProfil"; "Kategorien"; Katwahl)

Der obige Programmcode schreibt beim Klick auf die zugehörige Schaltfläche in einer Maske die im Feld Katwahl festgelegten Werte in das Feld Kategorien des Profildokuments DBProfil.

Den Formelkontext wechseln

Abschließend werfen wir noch einen Blick auf die seit Version 6 neue Funktion @UpdateFormula-Context. Sie ermöglicht es, während der Abarbeitung einer Formel den Kontext, in dem sie ausgeführt wird, zu wechseln. Normalerweise wird eine Formel immer in dem Kontext ausgeführt, in dem sie gestartet wird. Ist der Auslöser der Klick auf eine Schaltfläche in einer Maske, wird die Formel für diese aktive Maske ausgeführt.

Sollen Teile der Formel in einem anderen Dokument ausgeführt werden, können Sie dafür die Funktion @UpdateFormulaContext nutzen. Damit ist es beispielsweise möglich, zuerst Felder eines Dokuments auszulesen, dann ein neues Antwortdokument zu erstellen und in dessen Kontext die zuvor ausgelesenen Werte zu verwenden:

tempThema := Thema;
tempAutor := Autor;
@Command([Compose];"Antwort");
@UpdateFormulaContext;
FIELD Thema := tempThema;
FIELD Autor := tempAutor

Zu beachten ist, dass Sie die Funktion @Update-FormulaContext nur im Notes-Client und nur in Benutzeraktionen, wie zum Beispiel einer Hotspot-Schaltfläche, verwenden können.

Zusammenfassung

Die Formelsprache bietet eine Vielzahl von interessanten Funktionen, mit denen das Lesen und Schreiben von Feldwerten im aktuellen und in anderen Dokumenten einer Datenbank ermöglicht wird.

Wollen Sie auf Dokumente anderer Datenbanken direkt zugreifen, also nicht nur über das Auslesen einer Ansicht, kommen Sie jedoch nicht um LotusScript herum.

Autor

Elmar Fuchs ist freier Autor und IT-Berater (www.elmar-fuchs.de). Nach mehreren Jahren als Mitarbeiter der Sektion Informatik der Handelshochschule Leipzig machte er sich 1992 als IT-Autor, -Trainer und -Berater selbstständig. Thematische Schwerpunkte seiner Arbeit sind Lotus Notes Domino und IBM Workplace. Seit 2000 ist er verantwortlicher Autor für die Trainingsserie Lotus Notes Domino des HERDT-Verlags. Sie erreichen ihn über ef@elmar-fuchs.de.