Version 6.0
Projektmethoden werden je nach Situation benannt. Sie sind im Gegensatz zu Formular- und Objektmethoden überall verfügbar. Sie sind nicht an spezifische Objekte in der Datenbank gebunden. Je nach Ausführung und Verwendung kann eine Projektmethode folgende Rolle haben:
Menümethode
Unterroutine und Funktion
Prozessmethode
Ereignisbezogene Methode
Fehlerbezogene Methode
Projektmethoden sind an keine vordefinierte Situation gebunden. Es bleibt Ihnen als Programmierer überlassen, die notwendigen Elemente zu bestimmen:
Eine Menümethode wird in einem eigenen Menü aufgerufen. Sie steuert den Ablauf Ihrer Anwendung und nimmt bei Bedarf eine bestimmte Richtung. Die Menümethode zeigt Formulare an, erstellt Berichte und verwaltet ganz allgemein Ihre Datenbank.
Eine Unterroutine dient als Diener. Sie führt die Tasks aus, die ihr von anderen Methoden aufgetragen werden. Eine Funktion ist eine Unterroutine, die der Methode, die sie aufruft, einen Wert zurückgibt.
Eine Prozessmethode wird aufgerufen, wenn ein Prozess startet. Der Prozess dauert nur solange, wie die Prozessmethode ausgeführt wird. Weitere Informationen zu Prozessen finden Sie im Abschnitt Prozesse. Eine Menümethode, die einem Menübefehl mit der Eigenschaft Starte neuen Prozeß zugeordnet ist, ist gleichzeitig die Prozessmethode für den neu gestarteten Prozess.
Eine ereignisbezogene Methode läuft in einem eigenen Prozess, der nach Ereignissen sucht. Normalerweise verwaltet 4D die meisten Ereignisse automatisch für Sie. Beispielsweise bei der Dateneingabe nimmt 4D Tastaturkürzel und Klicks wahr, ruft die entsprechenden Objekt- und Formularmethoden auf, so dass Sie von diesen Methoden aus auf die Ereignisse entsprechend antworten können. Unter bestimmten Voraussetzungen möchten Sie jedoch Ereignisse direkt verwalten. Sie möchten bei länger andauernden Operationen (wie die Schleife For...End for zum Durchlaufen von Datensätzen) z.B. die Möglichkeit haben, die Operation zu unterbrechen, und zwar unter Windows mit der Tastenkombination Ctrl-Punkt, auf Macintosh mit der Tastenkombination Befehl-Punkt. Dafür verwenden Sie eine ereignisbezogene Methode. Weitere Informationen dazu finden Sie in der Beschreibung des Befehls ON EVENT CALL.
Eine fehlerbezogene Methode ist eine unterbrechende Projektmethode. Immer wenn ein Fehler oder eine Ausnahme auftreten, läuft diese Methode in dem Prozess ab, in welchem sie installiert ist. Weitere Informationen dazu finden Sie in der Beschreibung des Befehls ON ERR CALL.
Menümethoden
Eine Menümethode wird in der Runtime Umgebung aufgerufen, wenn Sie den dazugehörigen Menübefehl auswählen. Sie weisen die Methode dem Menübefehl im Methodeneditor zu. Dies ist einer der Hauptaspekte bei der eigenen Gestaltung von Datenbanken. Durch Einrichten eigener Menüs mit dazugehörigen Menümethoden, die bestimmte Aktionen ausführen, personalisieren Sie Ihre Datenbank. Weitere Informationen dazu finden Sie im Handbuch 4D Designmodus.
Mit eigenen Menübefehlen können eine oder mehrere Aktivitäten ausgelöst werden. Ein Menübefehl für die Eingabe von Datensätzen kann beispielsweise zwei Tasks ausführen: Das entsprechende Eingabeformular anzeigen und den Befehl ADD RECORD aufrufen, bis der Benutzer die Eingabe von Daten beendet.
Das automatische Ablaufen von mehreren Aktivitäten ist eine Leistungsstärke der Programmiersprache. Über eigene Menüs automatisieren Sie mehrere Tasks, die sonst manuell in der Benutzerumgebung durchgeführt werden müssten. Benutzer der Datenbank werden so besser geführt, sie müssen sich keine Gedanken über die nächste Aktion machen.
Unterroutinen
Eine Projektmethode wird Teil der Programmiersprache für die Datenbank, in der Sie diese erstellt haben. Sie können die Projektmethode dann wie einen der in 4D integrierten Befehle aufrufen. Eine so verwendete Projektmethode heißt Unterroutine.
Sie verwenden Unterroutinen, um:
Sich wiederholendes Programmieren zu reduzieren
Ihre Methoden klarer zu gliedern
Ihre Methoden schnellerzu ändern
Ihren Code modular aufzuteilen.
Wir gehen beispielsweise von einer Datenbank Kunden aus. Bei der individuellen Gestaltung stellen Sie fest, dass sich einige Vorgänge wiederholen, wie einen Kunden finden oder einen Datensatz ändern. Der Code dafür könnte folgendermaßen aussehen:
` Suche nach Kunde QUERY BY EXAMPLE([Customers]) ` Wähle das Eingabeformular INPUT FORM([Customers];"Data Entry") ` Ändere den Kundendatensatz MODIFY RECORD([Customers])
Arbeiten Sie ohne Unterroutinen, müssen Sie den Code immer schreiben, wenn Sie einen Kundendatensatz ändern wollen. Passiert das in Ihrer Datenbank an zehn Stellen, müssen Sie den Code zehnmal schreiben. Mit Unterroutinen schreiben Sie den Code nur einmal, sie können dadurch Programmierzeilen einsparen.
Wir legen den oben beschriebenen Code in einer Methode mit Namen MODIFY CUSTOMER an. Soll diese Methode in einer anderen Methode ausgeführt werden, müssen Sie nur den Namen einsetzen. Wollen Sie beispielsweise einen Kundendatensatz ändern und dann den Datensatz drucken, schreiben Sie folgende Methode:
MODIFY CUSTOMER PRINT SELECTION([Customers])
Ihre Methode vereinfacht sich entscheidend. Sie müssen nicht wissen, wie die Methode MODIFY CUSTOMER arbeitet, sondern nur was sie tut. Dies ist ein Vorteil von Unterroutinen: Ihre Methoden werden klarer. Sie erweitern sozusagen die 4th Dimension Programmiersprache.
Wollen Sie in dieser Beispieldatenbank die Methode zum Auffinden von Kunden ändern, müssen Sie nur eine und nicht zehn Methoden ändern. Ein weiterer Vorteil von Unterroutinen: Methoden sind schnell geändert.
Mit Unterroutinen bauen Sie Ihren Code modular auf. Das bedeutet, sie unterteilen Ihren Code in Module (Unterroutinen), die jeweil ein logisches Task ausführen. Betrachten Sie folgenden Code aus einer Datenbank für Kontoführung:
FIND CLEARED CHECKS ` Finde alle bezahlten Schecks RECONCILE ACCOUNT ` Gleiche Konto aus PRINT CHECK BOOK REPORT ` Drucke Scheckbuch Bericht
Auch für jemanden, der die Datenbank nicht kennt, ist klar, was der Code ausführt. Er muss nicht jede Unterroutine prüfen, die evtl. aus vielen Zeilen besteht und komplexe Operationen ausführt. Wichtig ist, dass die Tasks ausgeführt werden.
Wir empfehlen, den Code, immer wenn möglich, in logische Tasks oder Module aufzuteilen.
Parameter in Methoden
Bei größeren Programmen müssen Sie in Ihren Methoden oft auch Daten übergeben. Dazu setzen Sie Parameter ein.
Eine Methode benötigt Parameter (oder Argumente) zum Ausführen der Tasks. Dieses Handbuch verwendet beide Begriffe. Parameter werden in den 4th Dimension Befehlen übergeben. In diesem Beispiel ist die Zeichenkette "Hello" ein Argument des Befehls ALERT:
ALERT("Hello")
Auf dieselbe Weise werden auch Parameter in Methoden übergeben. Die Methode DO SOMETHING lässt drei Parameter zu:
DO SOMETHING(WithThis;AndThat;ThisWay)
Parameter sind durch Strichpunkt voneinander getrennt (;).
In der Unterroutine (die aufgerufene Methode) wird der Wert jedes Parameters automatisch in durchnumerierte lokale Variablen kopiert: $1, $2, $3, etc.. Diese geben die Reihenfolge der Parameter an.
Die lokalen Variablen/Parameter sind nicht die aktuellen Datenfelder, Variablen oder Ausdrücke, die von der aufrufenden Methode übergeben werden; sie enthalten nur die übergebenen Werte.
Sie können die Parameter $1, $2... in der Unterroutine genauso wie jede andere lokale Variable verwenden.
Als lokale Variablen sind sie nur innerhalb der Unterroutine verfügbar, sie werden am Ende der Unterroutine gelöscht. Von daher kann eine Unterroutine nicht den Wert der aktuellen Datenfelder oder Variablen ändern, die auf Methodenebene als Parameter übergeben werden. Beispiel:
` Ausschnitt aus dem Code der Methode MY METHOD ` ... DO SOMETHING ([People]Last Name) ` [People]Last Name sei gleich "weber" ALERT([People]Last Name) ` Code der Methode DO SOMETHING $1:=Uppercase($1) ALERT($1)
Die von DO SOMETHING angezeigte Meldung liest "WEBER", die von MY METHOD angezeigte Meldung liest "weber". Die Methode hat den Wert des Parameters $1 lokal geändert, das beeinträchtigt jedoch nicht den Wert des Datenfeldes [People]Last Name, der von der Methode MY METHOD als Parameter übergeben wurde.
Es gibt zwei Möglichkeiten, den Wert des Datenfeldes in der Methode DO SOMETHING zu ändern:
1. Sie übergeben in der Methode nicht das Datenfeld, sondern einen Zeiger darauf:
` Ausschnitt aus dem Code der Methode MY METHOD ` ... DO SOMETHING (->[People]Last Name) ` [People]Last Name sei gleich "weber" ALERT([People]Last Name) ` Code der Methode DO SOMETHING $1->:=Uppercase($1->) ALERT($1->)
Der Parameter ist hier nicht das Datenfeld selbst, sondern ein Zeiger darauf. Das von $1 referenzierte Objekt ($1->) ist das aktuelle Datenfeld. Wird nun das referenzierte Objekt geändert, geht das über den Bereich der Unterroutine hinaus, folglich wird das aktuelle Datenfeld geändert. In diesem Beispiel lesen beide Meldedialoge "WEBER".
Weitere Informationen dazu finden Sie im Abschnitt Zeiger.
2. Sie können die Methode DO SOMETHING so umschreiben, dass sie nicht etwas ausführt, sondern einen Wert zurückgibt:
` Ausschnitt aus dem Code der Methode MY METHOD ` ... [People]Last Name:=DO SOMETHING ([People]Last Name) ` [People]Last Name sei gleich "weber" ALERT([People]Last Name) ` Code der Methode DO SOMETHING $0:=Uppercase($1) ALERT($0)
Diese Technik heißt auch "eine Funktion verwenden". Sie wird im nächsten Abschnitt beschrieben.
Weiterer Hinweis: Sie können auf Parameter in der Unterroutine über die lokalen Variablen $1, $2... zugreifen. Parameter können außerdem optional sein und sind über die Syntax ${...} erreichbar. Weitere Informationen dazu finden Sie in der Beschreibung des Befehls Count Parameters.
Funktionen: Projektmethoden können einen Wert zurückgeben
Daten können auch von Methoden zurückgeben werden. Eine Methode, die einen Wert zurückgibt, heißt Funktion.
4D oder 4D Plug-in Befehle, die einen Wert zurückgeben, heißen ebenfalls Funktionen.
Folgende Programmierzeile verwendet die vordefinierte Funktion Length, sie gibt die Länge einer Zeichenkette zurück. Der von Length zurückgegebene Wert wird in eine Variable mit Namen MyLength gesetzt:
MyLength:=Length("How did I get here?")
Jede Unterroutine kann einen Wert zurückgeben. Der zurückzugebende Wert wird in die lokale Variable $0 gesetzt.
Folgende Funktion mit Namen Uppercase4 gibt eine Zeichenkette mit den ersten vier Zeichen in Großbuchstaben zurück:
$0:=Uppercase(Substring($1; 1; 4))+Substring($1; 5)
Dieses Beispiel verwendet die Funktion Uppercase4:
NewPhrase:=Uppercase4 ("This is good.")
Die Variable NewPhrase erhält "THIS is good."
Das Ergebnis der Funktion $0 ist eine lokale Variable in der Unterroutine. Sie kann als solche in der Unterroutine verwendet werden. Im vorigen Beispiel DO SOMETHING wurde $0 zuerst der Wert von $1 zugewiesen, dann war sie Parameter für den Befehl ALERT. Sie können $0 in der Unterroutine genauso wie jede andere lokale Variable verwenden. 4D übergibt der aufgerufenen Methode den Wert von $0 (so als ob die Unterroutine endet).
Rekursive Projektmethoden
Projektmethoden können sich auch selbst aufrufen, d.h. sie sind rekursiv. Beispiel:
Die Methode A ruft die Methode B auf, die A aufruft, so ruft A wieder B auf, usw..
Eine Methode kann sich selbst aufrufen.
Die 4D Programmiersprache unterstützt Rekursivität.
Hier ein Beispiel. Wir haben eine Tabelle [Friends and Relatives], die extrem vereinfacht, so aussieht:
- [Friends and Relatives]Name
- [Friends and Relatives]Children'Name
Wir gehen davon aus, dass die Werte der Datenfelder einmalig sind, d.h. es gibt nicht zwei Personen mit demselben Namen. Sie wollen für einen gegebenen Namen folgenden Satz erstellen: "Hans, mein Freund, der das Kind ist von Paul, der das Kind ist von Susi, die das Kind ist von Robert, der das Kind ist von Elisabeth, tut dies für sein Leben gern!":
1. Sie können den Satz folgendermaßen anlegen:
$vsName:=Request("Gib den Namen ein:";"Hans") If (OK=1) QUERY([Friends and Relatives];[Friends and Relatives]Name=$vsName) If (Records in selection([Friends and Relatives])>0) $vtTheWholeStory:="Mein Freund, "+$vsName Repeat QUERY([Friends and Relatives];[Friends and Relatives]Children'Name=$vsName) $vlQueryResult:=Records in selection([Friends and Relatives]) If ($vlQueryResult>0) $vtTheWholeStory:=$vtTheWholeStory+" der das Kind ist von "+[Friends and Relatives]Name $vsName:=[Friends and Relatives]Name End if Until ($vlQueryResult=0) $vtTheWholeStory:=$vtTheWholeStory+", tut dies für sein Leben gern!" ALERT($vtTheWholeStory) End if End if
2. oder folgendermaßen:
$vsName:=Request("Gib den Namen ein:";"Hans") If (OK=1) QUERY([Friends and Relatives];[Friends and Relatives]Name=$vsName) If (Records in selection([Friends and Relatives])>0) ALERT("Mein Freund, "+Genealogy of ($vsName)+", tut dies für sein Leben gern!") End if End if
mit der rekursiven Funktion Genealogy of:
` Projektmethode Genealogy of ` Genealogy of ( String ) -> Text ` Genealogy of ( Name ) -> Satzteil $0:=$1 QUERY([Friends and Relatives];[Friends and Relatives]Children'Name=$1) If (Records in selection([Friends and Relatives])>0) $0:=$0+" der das Kind ist von "+Genealogy of ([Friends and Relatives]Name) End if
Beachten Sie die Methode Genealogy of, die sich selbst aufruft.
Die erste Möglichkeit ist ein iterativer Algorithmus, die zweite ein rekursiver Algorithmus.
Hinweis: Sie können bei Programmierungen wie im oben aufgeführten Beispiel sowohl iterative als auch rekursive Methoden schreiben. Rekursivität macht die Programmierung im allgemeinen präziser, leichter zu lesen und zu warten, sie ist jedoch nicht zwingend.
Einige typische Verwendungen für Rekursivität in 4D sind:
Datensätze in Tabellen bearbeiten, die wie im obigen Beispiel miteinander verknüpft sind.
Dokumente und Ordner auf Ihrer Festplatte mit den Befehlen FOLDER LIST und DOCUMENT LIST durchlaufen. Ein Ordner kann Ordner und Dokumente enthalten, die Unterordner selbst können Ordner und Dokumente enthalten, usw..
Wichtig: Rekursive Abfragen sollten immer an einem bestimmten Punkt enden. Im Beispiel ruft sich die Methode Genealogy of nicht mehr selbst auf, wenn die Suche keinen Datensatz zurückgibt. Ohne Abfragen dieser Bedingung würde sich die Methode endlos aufrufen; 4D gibt dann evtl. eine Fehlermeldung "Speicher voll" zurück, da es keinen Platze mehr hat zum Stapeln der Aufrufe (so wie bei Parametern und lokalen Variablen in den Methoden).
Referenz
Ablaufsteuerung, Datenbankmethoden, Methoden.