Dieses Kapitel(22) beschreibt die Programmiersprache von MUIbase, einschließlich aller verfügbaren Funktionen. Das Kapitel dient jedoch nicht als allgemeine Anleitung für Programmieren. Man sollte mit den Grundzügen der Programmierung vertraut sein und schon kleinere(23) Programme geschrieben haben(24).
Um ein Programm für ein Projekt einzugeben, öffnet man den Programmeditor über den Menüpunkt `Programm - Ändern...'. Dies öffnet das Fenster `Ändere Programm' mit:
Der Programmeditor ist ein asynchrones Fenster. Das Fenster kann offen gelassen und weiterhin mit dem Rest der Anwendung gearbeitet werden. Man kann den Editor zu jeder Zeit schließen, indem dessen Fensterschließ-Knopf gedrückt wird. Wurden Änderungen seit der letzten erfolgreichen Kompiliation vorgenommen, dann erscheint ein Sicherheitsfenster, das um Bestätigung fragt, ob das Fenster geschlossen werden darf.
Man kann das Projektprogramm auch ohne das Öffnen des Programmeditors kompilieren, indem der Menüpunkt `Programm - Kompilieren' ausgewählt wird. Dies ist nützlich, wenn Änderungen an einer Einfügedatei gemacht wurden und diese Änderungen in das Projektprogramm einfließen sollen.
MUIbase-Programme werden vorverarbeitet, wie ein C-Compiler einen C-Quellcode vorverarbeitet. Dieser Abschnitt beschreibt, wie die Vorverarbeitungs-Anweisungen verwendet werden.
Alle Anweisungen beginnen mit dem Rauten-Symbol #, welcher das erste Zeichen in einer Zeile sein muß. Leerzeichen und Tabulatoren können nach dem begonnenen # folgen.
#define
name string
Definiert ein neues Symbol mit dem gegebenen Namen und Inhalt. Das Symbol string kann jeder Text einschließlich Leerzeichen sein und endet am Zeilenende. Paßt string nicht in eine Zeile, dann können weitere Zeilen durch ein Backslash-Zeichen \ am Ende jeder Zeile (außer der letzten) verwendet werden. Taucht das Symbol name im verbleibenden Quellcode auf, dann wird es durch den Inhalt von string ersetzt.
Beispiel: `(PRINTF "X ist %i" X)' gibt `X ist 1' aus (name's in Zeichenketten werden nicht verändert.)
Das Ersetzen von definierten Symbolen geschieht syntaktisch, das bedeutet, daß Symbole durch jeden Text ersetzt werden können, z.B. man kann sich seine eigene Syntax wie im folgenden Beispiel definieren:
#define BEGIN ( #define END ) BEGIN defun test () ... END
Die zu ersetzende Zeichenkette einer Definition kann ein anderes Symbol
enthalten, das mit der #define
-Anweisung definiert wurde, um
verschachtelte Definitionen zu ermöglichen.
Es gibt jedoch eine Obergrenze von 16 verschachtelten Definitionen.
Siehe auch #undef, #ifdef, #ifndef.
#undef
name
Entfernt die Definition des Symbols name. Wurde name nicht definiert, dann passiert nichts.
Siehe auch #define, #ifdef, #ifndef.
#include
filename
Liest den Inhalt von filename (eine Zeichenkette in Anführungszeichen) an diese Stelle. MUIbase sucht im aktuellen Verzeichnis und im in den Einstellungen festgelegten Verzeichnis (siehe Einfügedateienverzeichnis(25)) nach der zu ladenden Datei.
Der Dateiinhalt wird durch den Compiler verarbeitet, als ob er Teil des momentanen Quellcodes wäre.
Eine externe Datei kann eine oder mehrere externe Dateien enthalten. Es gibt
jedoch eine Obergrenze von 16 verschachtelten #include
-Anweisungen. Um
zu vermeiden, daß Dateien mehr als einmal eingefügt werden, kann die bedingte
Kompilation verwendet werden.
Man sollte vorsichtig sein, wenn man Quellcode in externe Dateien auslagert! Die Fehlersuche und das Auffinden von Fehlern in externen Dateien wesentlich schwerer. Man verschiebe daher nur getesteten und Projekt-unabhängigen Code in externe Dateien.
#if
const-expr
Ist der gegebene konstante Ausdruck const-expr nicht NIL, dann wird der
Text bis zum zugehörigen #else
, #elif
oder #endif
zur
Kompilation verwendet, anderenfalls (der Ausdruck lieferte NIL) wird der
Text bis zum zugehörigen #else
, #elif
oder #endif
nicht
zur Kompilation herangezogen.
Momentan können nur TRUE und NIL als konstante Ausdrücke verwendet werden.
Siehe auch #ifdef, #ifndef, #elif, #else, #endif.
#ifdef
name
Ist das gegebene Symbol name mit einer #define
-Anweisung
definiert worden, dann wird der Text bis zum zugehörigen #else
,
#elif
oder #endif
zur Kompilation verwendet, anderenfalls
nicht betrachtet.
Siehe auch #if, #ifndef, #elif, #else, #endif.
#ifndef
name
Ist das gegebene Symbol name nicht mit einer #define
-Anweisung
definiert worden, dann wird der Text bis zum zugehörigen #else
,
#elif
oder #endif
zur Kompilation verwendet, anderenfalls
nicht betrachtet.
Siehe auch #if, #ifdef, #elif, #else, #endif.
#elif
const-expr
Beliebig viele #elif
-Anweisungen können zwischen einem #if
,
#ifdef
oder #ifndef
und dem zugehörigen #else
oder
#endif
auftreten. Die Zeilen, die der elif
-Anweisung folgen,
werden für eine Kompilation verwendet, aber nur dann, wenn jede der folgenden
Bedingungen erfüllt ist:
#if
-Anweisung lieferte
NIL, das Symbol name im vorherigen ifdef
war nicht definiert
oder das Symbol name in der vorherigen ifndef
-Anweisung war
definiert.
elif
-Anweisungen lieferten NIL.
Wenn die oben genannten Bedingungen stimmen, dann werden die nachfolgenden
Anweisungen #elif
und #else
bis zum zugehörigen #endif
ignoriert.
Siehe auch #if, #ifdef, #ifndef, #else, #endif.
#else
Dies kehrt den Sinn einer bedingten Anweisung um, der sonst gestimmt hätte.
Wenn die vorhergehende Bedingung anzeigen würde, daß Zeilen eingefügt werden,
dann werden die Zeilen zwischen #else
und dem zugehörigen
#endif
ignoriert. Zeigt die vorhergehende Bedingung an, daß Zeilen
ignoriert werden, dann werden nachfolgende Zeilen für die Kompilation
eingefügt.
Bedingte Anweisungen und dazugehörige #else
-Anweisungen können
verschachtelt werden. Es gibt jedoch eine maximale Verschachteltiefe von 16
verschachtelten bedingten Anweisungen.
Siehe auch #if, #ifdef, #ifndef, #elif, #endif.
#endif
Beendet einen Bereich von Zeilen, der mit einer der bedingten Anweisungen #if
,
#ifdef
oder #ifndef
beginnt. Jeder dieser Anweisungen muß
eine zugehörige #endif
-Anweisung besitzen.
Siehe auch #if, #ifdef, #ifndef, #elif, #else.
MUIbase verwendet eine Programmiersprache mit einen lisp-ähnlichen Aufbau.
Tatsächlich sind einige Konstrukte und Funktionen vom Standard-lisp entnommen
worden. MUIbase ist jedoch nicht vollständig kompatibel zu Standard-lisp.
Viele Funktionen fehlen (z.B. destruktive Befehle) und die Bedeutung einiger
Befehle unterscheiden sich (z.B. der Befehl return
).
Der Vorteil einer lisp-ähnlichen Sprache ist, daß man sowohl funktionell als auch mit Befehlen programmieren kann. Funktionelle Sprachen sind in mathematischen Anwendungen weit verbreitet. Das Grundelement von funktionellen Sprachen ist die Verwendung von Ausdrücken. Funktionen werden in mathematischer Schreibweise definiert und häufig wird Rekursion benutzt.
Befehlssprachen (wie C, Pascal, Modula) benutzen eine Befehlsvorschrift, wie etwas berechnet werden soll(26). Hier ist das Grundelement der Zustand (z.B. Variablen) und ein Programm berechnet dessen Ausgabe durch den Sprung von einem Zustand in einen anderen (z.B. durch Zuweisen von Werten an Variablen).
Lisp kombiniert beide Techniken und deshalb kann man auswählen, auf welche Art etwas implementiert werden soll. Man verwendet diejenige, die besser zum vorgegebenen Problem paßt oder die man lieber mag.
Ein lisp-Ausdruck ist entweder eine Konstante, eine Variable oder ein
Funktionsausdruck.
Beim Funktionsaufruf verwendet lisp eine
Prefix-Notation(27).
Die Funktion und seine Parameter werden von runden Klammern eingeschlossen.
Um zum Beispiel zwei Werte a
und b
zu addieren, schreibt man
(+ a b)
Alle Ausdrücke liefern einen Wert, z.B. im obigen Beispiel die Summe von
a
und b
.
Ausdrücke können verschachtelt werden, d.h. man kann Ausdrücke als
Unterausdruck in eine andere einsetzen.
Funktionen werden nach dem call-by-value-Schema(28) aufgerufen, das bedeutet, daß zuerst die Parameter berechnet werden, bevor die Funktion aufgerufen wird.
Wenn nicht anders angegeben, sind alle Funktionen strikt, d.h. alle
Parameter einer Funktion müssen zuerst ermittelt werden, bevor sie an die
Funktion übergeben und diese ausgeführt wird. Einige Funktionen sind jedoch
nicht strikt, z.B. IF
, AND
und OR
. Diese Funktionen
brauchen nicht alle Parameter ermitteln.
MUIbase kennt drei Programmarten. Die erste ist das Projektprogramm. Im Programm dieser Art können Funktionen und globale Variablen definiert werden. Die Funktionen können als Auslösefunktionen für Felder verwendet werden. Ein Projektprogramm wird im Programmeditor (siehe Programmeditor) festgelegt.
Die zweite Art ist das Abfrageprogramm. FÜr dieses können nur Ausdrücke eingegeben werden. Ein solcher Ausdruck darf globale Variablen enthalten und Funktionen aufrufen, die im Projektprogramm definiert wurden. Man kann jedoch in einem Abfrageprogramm keine neuen globalen Variablen und Funktionen festlegen. Abfrageprogramme werden im Abfrageeditor (siehe Abfrageeditor) eingegeben.
Die dritte Programmart sind Filterausdrücke. Hier lassen sich nur Ausdrücke eingeben, die vordefinierte MUIbase-Funktionen aufrufen. Es sind nicht alle vordefinierten Funktionen verfügbar und zwar nur solche die keine Seiteneffekte aufweisen, z.B. kann man keine Funktion verwenden, die Daten in eine Datei schreibt. Filterausdrücke werden im Filterfenster (siehe Filter ändern(29)) verändert.
In einem MUIbase-Programm können Symbole, wie Funktionen, lokale und globale Variablen, definiert werden. Die Namen dieser Symbole müssen folgenden Punkten genügen:
Um auf Tabellen und Felder in einem MUIbase-Programm zugreifen zu können, muß ein Pfad zu diesen angegeben werden. Ein Pfad ist eine durch Punkte getrennte Liste von Komponenten, wobei jede Komponente der Name einer Tabelle oder eines Feldes ist.
Pfade können entweder relativ oder absolut sein. Absolute Pfade beginnen mit dem Tabellennamen als erste Komponente, gefolgt von einer Liste von Feldern, die zum gewünschten Feld hinführen, auf das man zugreifen möchte. Zum Beispiel greift der absolute Pfad `Person.Name' auf das Feld `Name' im aktuellen Datensatz der Tabelle `Person' zu oder der absolute Pfad `Person.Vater.Name' auf das Feld `Name' in dem Datensatz, der durch das Feld `Vater' referenziert wird (der ein Beziehungsfeld zur Tabelle `Person' ist).
Relative Pfade haben schon eine aktuelle Tabelle, auf die sie sich beziehen. Zum Beispiel ist in einem Filterausdruck die aktuelle Tabelle diejenige, für die der Filterausdruck geschrieben wird. Der relative Pfad(31) für ein Feld in der aktuellen Tabelle ist dann nur der Feldname selbst. Auf Felder, auf die nicht direkt von der aktuellen Tabelle aus zugegriffen werden kann, sondern indirekt über eine Beziehung, dann gelten die gleichen Regeln wie für absolute Pfade.
Es ist nicht immer eindeutig, ob ein angegebener Pfad ein relativer oder ein absoluter ist, z.B. bei einem Filterausdruck für eine Tabelle `Foo'(32), das ein Feld `Bar' besitzt, wenn es auch eine Tabelle `Bar' gibt. Wird nun `Bar' eingegeben, dann ist unklar, was gemeint ist: die Tabelle oder das Feld? Daher werden alle Pfade zuerst als relative Pfade betrachtet. Wird kein Feld für den angegebenen Pfad gefunden, dann wird der Pfad global betrachtet. In unserem Beispiel würde das Feld bevorzugt.
Was aber, wenn im Beispiel oben auf die Tabelle zugegriffen werden soll? In dem Fall muß der Pfad absolut angegeben werden. Um einen Pfad als global zu kennzeichnen, müssen vor dem Pfad zwei Doppelpunkte angefügt werden. In unserem Beispiel müßte man `::Bar' eingeben, um auf die Tabelle zuzugreifen.
Um Pfade und ihre Anordnungen besser zu verstehen, betrachten wir hier als Beispiel, daß das Feld `Bar' in der Tabelle `Foo' eine Beziehung zur Tabelle `Bar' ist und die Tabelle `Bar' enthält ein Feld `Name'. Nun kann man auf das Feld `Name' zugreifen, indem man `Bar.Name' oder `::Bar.Name' eingibt. Beide Ausdrücke haben unterschiedliche Bedeutungen. `::Bar.Name' bedeutet, daß der aktuelle Datensatz der Tabelle `Bar' hergenommen wird und der Wert des Feldes `Name' in diesem Datensatz zurückgeliefert wird, wohingegen `Bar.Name' den aktuellen Datensatz von `Foo' hernimmt, die Beziehung des Feldes `Bar' ermittelt und diesen Datensatz zum Ermitteln des Wertes vom Feld `Name' verwendet.
Um ein komplexeres Beispiel anzubringen, stellen wir uns vor, daß die Tabelle `Bar' zwei Datensätze hat. Der eine enthält im Feld `Name' den Eintrag `Mats'(33) und der andere `Steffen'. Der erste Datensatz ist der momentan aktive. Des weiteren hat die Tabelle `Foo' einen Datensatz (den aktuellen), dessen Feld `Bar' auf den zweiten Datensatz der Tabelle `Bar' verweist. `::Bar.Name' liefert jetzt `Mats' und `Bar.Name' liefert `Steffen'.
Die Programmiersprache von MUIbase kennt die folgenden Datentypen:
Typ Beschreibung Bool alle Ausdrücke. Nicht-NIL-Ausdrücke werden als TRUE betrachtet. Integer lange Ganzzahl, 32 bit, Auswahlwerte werden automatisch in Integer umgewandelt Real double, 64 bit String Zeichenketten von unterschiedlicher Länge Memo wie Zeichenketten, aber zeilenorientiertes Format Date Datumswerte Time Zeitwerte Record Zeiger auf einen Datensatz File Dateideskriptor zum Lesen/Schreiben List Liste von Elementen, NIL ist eine leere Liste.
Alle Programmiertypen unterstützen den Wert NIL.
Die Programmiersprache von MUIbase kann konstante Ausdrücke handhaben, die abhängig von ihrem Typ eingegeben werden kann:
Typ Beschreibung Integer Ganzzahlkonstanten im Bereich von -2147483648 bis 2147483647 können wie üblich angegeben werden. Real Fließkommazahlen im Bereich von -3.59e308 bis 3.59e308 können wie üblich angegeben werden, sowohl im wissenschaftlichen als auch nicht-wissenschaft- lichen Format. Wird der Dezimalpunkt vergelassen, so wird die Zahl nicht als Real betrachtet, sondern als Integer. String Zeichenkettenkonstanten sind jedes Zeichen in einer Kette, umschlossen mit doppelten Anführungsstrichen, z.B."Beispielzeichenkette". Innerhalb der doppelten Anführungszeichen kann jedes Zeichen angegeben werden, mit Ausnahme von Steuerzeichen und neuen Zeilen. Es gibt jedoch besondere Escapezeichen zum Eingeben solcher Zeichen: \n neue Zeile (nl) \t horizontaler Tabulator (ht) \v vertikaler Tabulator (vt) \b Rückschritt (bs) \r Wagenrücklauf (cr) \f Seitenumbruch (ff) \\ der Backslash selbst \" doppeltes Anführungszeichen \e Escapezeichen 033 \nnn Zeichen mit dem Oktalcode nnn \xnn Zeichen mit dem Hexcode nn Memo Es gibt keine konstanten Werte, sondern stattdessen nur eine konstante Zeichenkette. Date Konstante Datumswerte können in einem der Formate `TT.MM.JJJJ', `MM/TT/JJJJ' oder `JJJJ-MM-TT' angegeben werden, wobei `TT', `MM' und `JJJJ' die zwei- und vierstelligen Werte für Tag, Monat bzw. Jahr darstellen. Time Konstante Zeitwerte werden im Format `HH:MM:SS' angegeben, wobei `HH' ein zweistelliger Wert im Bereich 0 bis 23 ist, der Stunden darstellt, `MM' ein zweistelliger Wert im Bereich 0 bis 59 ist, der Minuten repräsentiert und `SS' ein zweistelliger Wert im Bereich 0 bis 59 ist, der Sekunden anzeigt.
Für andere vordefinierte Konstanten, siehe Vordefinierte Konstanten.
Im Rest dieses Kapitels findet man die Beschreibung aller Befehle und Funktionen, die für die Programmierung von MUIbase zur Verfügung stehen. Der folgende Aufbau wird verwendet, um die Befehle zu beschreiben:
Anm.d.Übersetzers: Bei der Beschreibung der Befehle wird die englische Namensgebung der Parameter etc. beibehalten. Dies vermeidet Fehler bei der Übersetzung und bleibt dennoch verständlich.
Dieser Abschnitt listet Befehle zum Definieren von Funktionen und globalen Variablen auf. Die Befehle sind nur für Projektprogramme verfügbar.
DEFUN
definiert eine Funktion mit einem festgelegten Namen, einer
Liste von Parametern, die an die Funktion weitergereicht und eine
Liste von Ausdrücken, die abgearbeitet werden.
(DEFUN
name(
varlist)
expr ...)
Der Name der Funktion muß mit einem Kleinbuchstaben beginnen, gefolgt von weiteren Zeichen, Ziffern und Unterstrich-Zeichen. (siehe Namenskonventionen).
Der Parameter varlist legt die Parameter der Funktion fest:
varlist: var1 ...
wobei var1 ... die Namen der Parameter sind. Die Namen müssen den gleichen Regeln wie die des Funktionsnamens genügen.
Es ist auch möglich, Typdeklarierer an die Parameter zu hängen (siehe Typdeklarierer).
Die Funktion führt die Ausdrücke expr, ... der Reihe nach aus und liefert den Wert des letzten Ausdrucks. Die Funktion kann auch weitere Funktionen einschließlich sich selbst aufrufen. Eine selbstdefinierte Funktion wird wie eine vordefinierte Funktion aufgerufen.
Um zum Beispiel die Anzahl der Elemente einer Liste zu zählen, kann folgende Funktion definiert werden:
(DEFUN len (l) (IF (= l NIL) 0 (+ 1 (len (REST l))) ) )
Mit DEFUN
definierte Funktionen werden in Popuplisten von Tabellen- und
Feldfenstern aufgelistet (siehe Tabellen erstellen und Felder erstellen).
Dieser Befehl ist nur für Projektprogramme verfügbar.
DEFUN*
ist die Stern-Variante von DEFUN
und hat den selben
Effekt wie DEFUN
(siehe DEFUN).
Der einzige Unterschied ist, daß Funktionen, die mit DEFUN*
definiert
wurden, beim Erzeugen oder Ändern von Tabellen und Feldern nicht in den
Popuplisten aufgelistet werden.
Es ist jedoch möglich, den Funktionsnamen in den entsprechenden
Zeichenkettenfeldern einzugeben.
Dieser Befehl ist nur für Projektprogramme verfügbar.
(DEFVAR
var [expr])
Definiert eine globale Variable mit dem Vorgabewert aus expr oder NIL, wenn expr fehlt. Der Name der Variablen muß mit einem Kleinbuchstaben beginnen, gefolgt von weiteren Zeichen, Ziffern und Unterstrich-Zeichen. (siehe Namenskonventionen).
Man kann Typdeklarierer an den Variablennamen anhängen (siehe Typdeklarierer).
DEFVAR
ist nur verfügbar für Projektprogramme.
Alle DEFVAR
-Befehle sollten am Anfang vor allen Funktionsdefinitionen
plaziert werden.
Beispiel: `(DEFVAR x 42)' definiert eine globale Variable `x' mit dem Wert 42.
Es gibt einige vordefinierte Variablen in MUIbase (siehe Vordefinierte Variablen).
Siehe auch DEFUN, DEFUN*, LET.
Dieser Abschnitt listet Funktionen zur Programmflußkontrolle auf, z.B. Funktionen zum Definieren von lokalen Variablen, Schleifenfunktionen, bedingte Programmausführung, Schleifenkontrollfunktionen und mehr.
Um mehrere Ausdrücke der Reihe nach auszuführen, wird der
PROGN
-Aufruf(34) verwendet.
(
[expr ...])
führt expr ... der Reihe nach aus.
Liefert das Ergebnis des letzten Ausdrucks (oder NIL, wenn kein Ausdruck
angegeben wurde).
In Lisp ist dieser Aufruf als (PROGN
[expr ...])
bekannt.
Beispiel: `(1 2 3 4)' liefert 4.
Siehe auch PROG1.
Neben PROGN
gibt es mit PROG1
eine andere Möglichkeit, mehrere
Ausdrücke zu errechnen.
(PROG1
[expr ...])
führt expr ... aus und liefert den Wert des ersten Ausdrucks (oder NIL, wenn kein Ausdruck angegeben wurde).
Beispiel: `(PROG1 1 2 3 4)' liefert 1.
Siehe auch PROGN.
LET
definiert einen neuen Block von lokalen Variablen.
Dies ist nützlich, um z.B. lokale Variablen einer Funktion zu definieren.
Der Aufbau ist:
(LET (
varlist)
expr ...)
wobei varlist eine Liste von lokalen Variablen ist.
varlist: varspec ...
varspec:(
var expr)
| var
Hier ist var der Name der Variable, der mit einem Kleinbuchstaben beginnt, gefolgt von weiteren Zeichen, Ziffern und Unterstrich-Zeichen. (siehe Namenskonventionen).
Im Falle von (
var expr)
wird die neue Variable mit
dem gegebenen Ausdruck initalisiert(35).
Im anderen Fall ist die neue Variable auf NIL gesetzt.
Es ist auch möglich, Typdeklarierer an die Variablen zu hängen (siehe Typdeklarierer).
Nach dem Initialisieren aller Variablen wird die Liste der Ausdrücke expr ... ausgewertet und der Wert der letzten zurückgegeben.
Der folgende LET
-Ausdruck
(LET ((x 0) y (z (+ x 1))) (+ x z) )
liefert zum Beispiel 1.
Siehe auch DOTIMES, DOLIST, DO, DEFVAR.
Die Funktion SETQ
setzt Werte in Variablen, Feldern und Tabellen.
(SETQ
lvalue1 expr ...)
Setzt lvalue1 auf den Wert von expr. Die Punkte zeigen
weitere Zuweisungen für lvalues an. Ein lvalue ist eine Variable,
ein Feld einer Tabelle oder eine Tabelle.
Im Falle einer Variable muß diese voher definiert worden sein (z.B. mit dem
LET
-Ausdruck).
Setzen des Wertes einer Tabelle bedeutet das Setzen seines Programm- oder
Oberflächenzeigers: `(SETQ
Table expr)
' setzt
den Programm-Datensatzzeiger von Table auf den Wert von expr und
`(SETQ
Table* expr)
' setzt dessen
Oberflächen-Datensatzzeiger und aktualisiert die Anzeige. Mehr Informationen
über Programm- und Oberflächen-Datensatzzeigern, siehe Tabellen.
SETQ
liefert den Wert des letzten Ausdrucks.
Beispiel: `(SETQ a 1 b 2)' weist 1 der Variable `a' zu, 2 der Variable `b' und liefert 2.
Siehe auch SETQ*, LET, DEFVAR, Tabellen, Aufbau von Ausdrücken.
SETQ*
ist die Stern-Variante von SETQ
(siehe SETQ) und hat
ähnliche Auswirkungen. Der Unterschied ist, daß SETQ*
beim Zuweisen
eines Wertes zu einer Variable die Auslösefunktion dieses Feldes aufruft
(siehe Auslösefunktion Feld(36))
, statt den Wert direkt zuzuweisen.
Ist zum Feld keine Auslösefunktion zugewiesen, dann verhält sich SETQ*
genauso wie SETQ
und weist einfach den Wert der Variable zu.
Beispiel: `(SETQ* Table.Attr 0)' ruft die Auslösefunktion von `Table.Attr' mit dem Parameter 0 auf.
Achtung: Mit dieser Funktion ist es möglich, Endlosschleifen zu schreiben,
z.B. wenn eine Auslösefunktion für ein Feld definiert wurde und diese
Funktion SETQ*
aufruft, das sich selbst einen Wert setzt.
Siehe auch SETQ*, LET, DEFVAR.
FUNCALL
wird verwendet, um eine Funktion aufzurufen.
(FUNCALL
fun-expr [expr ...])
Ruft die Funktion fun-expr mit den gegebenen Parametern auf. Der Ausdruck fun-expr kann jeder Ausdruck sein, dessen Wert eine vor- oder benutzerdefinierte Funktion ist, z.B. eine Variable, die die Funktion enthält, die aufgerufen werden soll. Stimmt die Anzahl der Parameter nicht, dann wird eine Fehlermeldung erzeugt.
FUNCALL
liefert den Rückgabewert des Funktionsaufrufes oder NIL, wenn
fun-expr NIL ist.
Mehr Informationen über funktionelle Ausdrücke, siehe Funktionale Parameter.
IF
ist ein Bedingungsoperator.
(IF
expr1 expr2 [expr3])
Der Ausdruck expr1 wird getestet. Wenn er nicht NIL liefert, dann wird der Wert von expr2 geliefert, anderenfalls der von expr3 (oder NIL, wenn nicht vorhanden).
Diese Funktion ist nicht strikt, das bedeutet, daß entweder der eine oder der andere Ausdruck ausgewertet wird.
CASE
ähnelt der switch
-Anweisung in der Sprache C.
(CASE
expr [case ...])
Hier ist expr der Auswahlausdruck und case ... sind Paare bestehend aus:
case:(
value [expr ...])
wobei value ein einzelner Ausdruck oder eine Liste von Ausdrücken(37) ist und expr ... die Ausdrücke sind, die ausgeführt werden, wenn der Fallausdruck paßt.
Der Ausdruck CASE
wertet erst expr aus.
Dann wird jedes Fallpaar geprüft, ob es (oder einer der Ausdrücke in der
Liste) zum ausgewerten Ausdruck paßt.
Wird ein passender Fallausdruck gefunden, dann werden die dazugehörigen
Ausdrücke ausgeführt und der Wert des letzten Ausdrucks zurückgeliefert.
Paßt kein Fall, dann wird NIL zurückgeliefert.
Beispiel: `(CASE 1 ((2 3 4) 1) (1 2))' liefert 2.
COND
ist wie IF
ein Bedingungsoperator.
(COND
[(
test-expr [expr ...])
...])
COND
prüft der Reihe nach den ersten Ausdruck jeder Liste.
Für den ersten, der nicht NIL liefert, wird der dazugehörige Ausdruck
expr ... ausgeführt und der Wert des letzten Ausdrucks
zurückgeliefert.
Liefern alle geprüften Ausdrücke NIL, dann wird NIL zurückgegeben.
(COND ((> 1 2) "1 > 2") ((= 1 2) "1 = 2") ((< 1 2) "1 < 2") )
liefert "1 < 2".
Für einfache Schleifen kann der Befehl DOTIMES
verwendet werden.
(DOTIMES (
name int-expr [result-expr ...])
[loop-expr ...])
Hier ist name der name einer neuen Variable, die innerhalb der Schleife verwendet wird(38). Der Name muß mit einem Kleinbuchstaben beginnen, gefolgt von weiteren Zeichen, Ziffern und Unterstrich-Zeichen. (siehe Namenskonventionen).
Die Anzahl der Schleifendurchläufe wird über int-expr angegeben. In result-expr ... können Ausdrücke angegeben werden, die nach dem Beenden der Schleife ausgeführt werden sollen. loop-expr enthält den Körper der Schleife, darin sind die Ausdrücke, die bei jedem Schleifendurchlauf ausgewertet werden.
Bevor die Schleife ausgeführt wird, errechnet DOTIMES
den Wert von
int-expr, um die Anzahl festzustellen, wie oft die Schleife ausgeführt
werden soll.
Hier wird int-expr nur einmal zu Beginn der Schleife ausgewertet und
muß einen Ganzzahlwert liefern.
Danach setzt DOTIMES
die Schleifenvariable schrittweise in jedem
Durchlauf auf 0 bis int-expr-1. Zuerst wird die Variable auf Null
gesetzt und geprüft, ob diese schon größer oder gleich dem Wert von
expr ist. Ist int-expr ist negativ oder NIL, oder ist die
Variable größer oder gleich dem Wert von expr, dann wird die Schleife
abgebrochen und die Rückgabewerte ermittelt. Anderenfalls werden die
Ausdrücke in der Schleife abgearbeitet und die Variable um eins erhöht.
Danach kehrt die Schleife wieder zum Abbruchtest zurück und führt -wenn
möglich- weitere Schleifendurchläufe aus.
Der Ausdruck DOTIMES
liefert den Wert des letzten
Rückgabewert-Ausdrucks oder NIL, wenn kein solcher angegeben wurde.
(DOTIMES (i 50 i) (PRINT i))
Gibt die Nummern von 0 bis 49 aus und liefert den Wert 50.
Siehe auch DOLIST, DO, FOR ALL, LET.
Für Schleifen über Listen kann der Ausdruck DOLIST
verwendet werden.
(DOLIST (
name list-expr [result-expr ...])
[loop-expr ...])
Hier ist name der Name einer neuen Variable, der in der Schleife verwendet wird. Der Name muß mit einem Kleinbuchstaben beginnen, gefolgt von weiteren Zeichen, Ziffern und Unterstrich-Zeichen. (siehe Namenskonventionen).
In list-expr wird die Liste festgelegt, über diese die Schleife ausgeführt werden soll, result-expr ... sind Ausdrücke, die nach dem Beenden der Schleife ausgeführt werden und loop-expr ... bilden den Körper der Schleife.
Bevor die Schleife ausgeführt wird, berechnet DOLIST
den Wert von
list-expr. Dieser Ausdruck wird nur einmal beim Start der Schleife
ausgewertet und muß einen Listenwert liefern.
Dann setzt DOTIMES
bei jedem Schleifendurchlauf die Schleifenvariable
der Reihe nach auf jedes Element der Liste.
Zuerst wird die Schleifenvariable mit dem ersten Element der Liste
initialisiert.
Ist die Liste schon leer (NIL), dann wird die Schleife beendet und die
Rückgabewerte berechnet.
Anderenfalls werden die Schleifenausdrücke ausgeführt und die Variable auf
das nächste Element in der Liste gesetzt.
Danach kehrt die Schleife wieder zum Abbruchtest zurück und führt -wenn
möglich- weitere Schleifendurchläufe aus.
Der Ausdruck DOLIST
liefert den Wert des letzten
Rückgabewert-Ausdrucks oder NIL, wenn kein solcher angegeben wurde.
(DOLIST (i (SELECT * FROM Accounts)) (PRINT i))
Gibt alle Datensätze der Tabelle `Accounts' aus und liefert NIL.
Siehe auch DOTIMES, DO, FOR ALL, LET.
Mit dem Ausdruck DO
können beliebige Schleifen programmiert werden.
(DO (
[binding ...]) (
term-expr [result-expr ...])
[loop-expr ...])
wobei binding ... die Variablenzuweisungen sind, die jeweils wie folgt aussehen können:
(
name init [step])
mit name als Namen für eine neue Variable, init ist der Startwert
der Variable und step der Ausdruck für Zählschrittweite.
Des weiteren ist term-expr der Abbruchbedingungsausdruck, result-expr ... sind die Rückgabewertausdrücke (voreingestellt ist NIL) und loop-expr ... bilden den Körper der Schleife.
Die DO
-Schleife initialisiert zuerst alle lokalen Variablen mit den
Startwerten und testet dann die Abbruchbedingung. Liefert sie TRUE, dann wird
die Schleife unterbrochen und die Rückgabewertausdrücke ausgeführt. Der Wert
des letzten Rückgabewerts wird zurückgeliefert.
Anderenfalls werden die Schleifenausdrücke (
loopexpr
...)
ausgeführt und jede Variable wird mit dem Wert der
Schrittweite aktualisiert.
Danach kehrt die Ausführung zum Test der Abbruchbedingung zurück und so
weiter.
(DO ((i 0 (+ i 1))) ((>= i 5) i) (PRINT i))
Gibt die Werte 0, 1, 2, 4 und 4 aus und liefert den Wert 5.
Natürlich ist das ein ziemlich komplizierter Weg, eine einfache FOR-Schleife
zu bauen. Dafür gibt es mit dem Ausdruck DOTIMES
eine einfachere
Version.
Siehe auch DOTIMES, DOLIST, FOR ALL, LET.
Der Ausdruck FOR ALL wird verwendet, um eine Liste von Datensätzen abzuarbeiten.
(FOR ALL
table-list [WHERE
where-expr] [ORDER BY
order-list]DO
expr ...)
Hier ist table-list eine durch Kommas getrennte Liste von Tabellen, where-expr ein Ausdruck zum Testen einer jeden Menge von Datensätzen, order-list eine durch Kommas getrennte Liste von Ausdrücken, nach denen sortiert werden soll und expr ... sind die Ausdrücke, die für jeden Datensatz ausgeführt werden sollen.
FOR ALL
erzeugt zuerst eine Liste aller Datensätze, für die der
Schleifenkörper ausgeführt werden soll. Dies wird wie bei einem
SELECT
-Ausdruck durchgeführt. Siehe SELECT für mehr Informationen,
wie diese Liste erzeugt wird. Für jedes Element dieser Liste wird der
Schleifenkörper expr ... ausgeführt.
Zum Beispiel kann ein Aufsummieren eines Tabellenfeldes folgendermaßen durchgeführt werden:
(SETQ sum 0) (FOR ALL Accounts DO (SETQ sum (+ sum Accounts.Amount)) )
Der Ausdruck FOR ALL
liefert NIL.
Siehe auch SELECT, DOTIMES, DOLIST, DO.
NEXT
kann verwendet werden, um DOTIMES
-,
DOLIST
-, DO
- und FOR ALL
-Schleifen zu steuern.
Ein Aufruf von NEXT
im Schleifenkörper springt zum nächsten
Schleifendurchlauf. Dies kann benutzt werden, wenn uninteressante
Schleifendurchläufe übersprungen werden sollen, wie z.B. in folgendem
Beispiel:
(FOR ALL Table DO (IF nicht-interessant-im-aktuellen-Datensatz (NEXT)) ... )
Siehe auch EXIT, DOTIMES, DOLIST, DO, FOR ALL.
EXIT
kann verwendet werden, um eine Schleife zu beenden.
(EXIT
[expr ...])
EXIT
innerhalb eines Schleifenkörpers beendet die Schleife und
führen die optionalen Ausdrücke expr ... aus und liefern den Wert
des letzten Ausdrucks (oder NIL, wenn kein Ausdruck angegeben wurde) als
Rückgabewert der Schleife.
Mögliche Rückgabewerte der Schleife im Beispiel
(DOTIMES (x 10 ret-expr ...) ...)
werden nicht ausgeführt.
Man kann die Funktion EXIT
z.B. verwenden, um eine FOR
ALL
-Schleife zu beenden, wenn ein Datensatz gefunden wurde, der uns
interessiert:
(FOR ALL Table DO (IF interessanter-aktueller-Datensatz (EXIT Table)) ... )
Siehe auch NEXT, RETURN, HALT, DOTIMES, DOLIST, DO, FOR ALL.
Innerhalb einer Funktionsdefinition kann mit dem Befehl RETURN
zur
aufrufenden Funktion zurückgesprungen werden.
(RETURN
[expr ...])
beendet die Funktion, führt die optionalen Ausdrücke expr ... aus und liefert den Wert des letzten Ausdrucks (oder NIL, wenn kein Ausdruck angegeben wurde).
(DEFUN find-record (name) (FOR ALL Table DO (IF (= Name name) (RETURN Table)) ) )
Das Beispiel sucht nach einem Datensatz, dessen Feld Name zum gegebenen Namen paßt. Die Funktion liefert den ersten Datensatz, der gefunden wurde oder NIL, wenn kein Datensatz gefunden wurde.
HALT
kann verwendet werden, um die Programmausführung abzubrechen.
(HALT)
stoppt stillschweigend die Programmausführung.
Siehe auch ERROR, EXIT, RETURN.
Zum Abbrechen der Programmausführung mit einer Fehlermeldung kann die
Funktion ERROR
verwendet werden.
(ERROR
fmt [arg ...])
stoppt die Programmausführung und öffnet ein Fenster mit einer Fehlermeldung.
Die Fehlermeldung wird wie in der Funktion SPRINTF
(siehe SPRINTF)
aus fmt und den optionalen Parametern arg ... erzeugt.
Für jeden Datentyp ist eine Aussage definiert, die TRUE liefert, wenn der übergebene Ausdruck vom gegebenen Typ ist, anderenfalls NIL. Die Aussagen sind:
Aussage Beschreibung(STRP
expr)
TRUE wenn expr vom Typ Zeichenkette ist, sonst NIL.(MEMOP
expr)
TRUE wenn expr vom Typ mehrzeiliger Text ist, sonst NIL.(INTP
expr)
TRUE wenn expr vom Typ Ganzzahl ist, sonst NIL.(REALP
expr)
TRUE wenn expr vom Typ Fließkommazahl ist, sonst NIL.(DATEP
expr)
TRUE wenn expr vom Typ Datum ist, sonst NIL.(TIMEP
expr)
TRUE wenn expr vom Typ Zeit ist, sonst NIL.(NULLP
expr)
TRUE wenn expr vom Typ NIL (leere Liste) ist, sonst NIL.(CONSP
expr)
TRUE wenn expr keine leere Liste ist, sonst NIL.(LISTP
expr)
TRUE wenn expr eine Liste (die NIL sein kann) ist, sonst NIL.(RECP
table expr)
TRUE wenn expr ein Datensatzzeiger der gegebenen Tabelle ist. Wenn expr NIL ist, dann wird TRUE geliefert (Anfangsdatensatz). Wenn table NIL ist, dann wird geprüft, ob expr ein Datensatzzeiger irgendeiner Tabelle ist.
Dieser Abschnitt listet Funktionen auf, die zum Umwandeln von einem Datentyp in einen anderen verwendet werden.
STR
kann verwendet werden, um einen Ausdruck in eine
Zeichenkettendarstellung umzuwandeln.
(STR
expr)
wandelt expr in eine Zeichenkettendarstellung um. Der Typ von expr bestimmt die Umwandlung:
Typ Ergebniszeichenkette Zeichenkette Die Zeichenkette selbst. mehrzeiliger Text Der gesamte mehrzeilige Text in einer Zeichenkette. Ganzzahl Zeichenkettendarstellung einer Ganzzahl. Fließkommazahl Zeichenkettendarstellung einer Fließkommazahl. Wenn expr ein Feld ist, dann wird die Anzahl der Nachkommastellen dieses Feldes, anderenfalls zwei Ziffern verwendet. Auswahl Auswahltext des Auswahlfeldes. Datum Zeichenkettendarstellung des Datumswertes. Zeit Zeichenkettendarstellung des Zeitwertes. Bool Die Zeichenkette "TRUE" NIL Benutzerdefinierte Zeichenkette für NIL, wenn expr ein Feld ist, anderenfalls die Zeichenkette "NIL" Datensatz Zeichenkettendarstellung der Datensatznummer. Andere Zeichenkettendarstellung des internen Adreßzeigers(39)
MEMO
kann verwendet werden, um einen Ausdruck in einen mehrzeiligen
Text umzuwandeln.
(MEMO
expr)
wandelt expr in eine mehrzeilige Textdarstellung.
Es faßt den Ausdruck wie bei der Funktion STR
(siehe STR) auf,
liefert aber einen mehrzeiligen Text statt einer Zeichenkette.
Siehe auch STR.
INT
wird verwendet, um einen Ausdruck in eine Ganzzahl umzuwandeln.
(INT
expr)
wandelt expr in eine Ganzzahl. Mögliche Umwandlungen sind:
Typ Ergebniswert Zeichenkette Wenn die gesamte Zeichenkette eine Ganzzahl darstellt, dann wird die Zeichenkette in eine Ganzzahl umgewandelt. Führende und folgende Leerzeichen werden ignoriert. Stellt es keine Ganzzahl dar, wird NIL geliefert. mehrzeiliger Text Analog Zeichenkette. Ganzzahl Der Wert selbst. Fließkommazahl Wenn der Wert im Ganzzahlbereich liegt, wird der Fließkommazahlenwert gerundet und geliefert, anderenfalls NIL. Auswahltext Die interne Nummer (beginnend bei 0) des aktuellen Auswahltextes. Datum Anzahl Tage seit dem 01.01.0000. Zeit Anzahl Sekunden seit 00:00:00. Datensatz Datensatznummer. NIL NIL Andere Eine Fehlermeldung wird erzeugt und die Programmausführung abgebrochen.
REAL
wird verwendet, um einen Ausdruck in einen Wert vom Typ
Fließkommazahl umzuwandeln.
(REAL
expr)
wandelt expr in eine Fließkommazahl.
Es faßt den Ausdruck wie bei der Funktion INT
(siehe INT) auf,
liefert aber einen Wert vom Typ Fließkommazahl anstatt einer Ganzzahl.
Siehe auch INT.
DATE
wird verwendet, um einen Ausdruck in ein Datum umzuwandeln
(40).
(DATE
expr)
wandelt den gegebenen Ausdruck in ein Datum(41). Mögliche Umwandlungen sind:
Typ Rückgabewert Zeichenkette Wenn die gesamte Zeichenkette einen Datumswert darstellt, dann wird die Zeichenkette in ein Datum umgewandelt. Führende und folgende Leerzeichen werden ignoriert. Stellt es kein Datum dar, wird NIL geliefert. mehrzeiliger Text Analog Zeichenkette. Ganzzahl Ein Datumswert wird erzeugt, wenn die gegebene Ganzzahl die Anzahl der Tage seit dem 01.01.0000 darstellt. Ist die Ganzzahl zu groß (Datum würde größer als der 31.12.9999) oder negativ, dann wird NIL zurückgegeben. Fließkommazahl Analog Ganzzahl. Datum Der Wert selbst. NIL NIL Andere Eine Fehlermeldung wird erzeugt und die Programmausführung abgebrochen.
TIME
wird verwendet, um einen Ausdruck in einen Zeitwert umzuwandeln.
(TIME
expr)
wandelt den gegebenen Ausdruck in einen Zeitwert. Mögliche Umwandlungen sind:
Type Return value Zeichenkette Wenn die gesamte Zeichenkette einen Zeitwert darstellt, dann wird die Zeichenkette in eine Zeit umgewandelt. Führende und folgende Leerzeichen werden ignoriert. Stellt es keine Zeit dar, wird NIL geliefert. mehrzeiliger Text Analog Zeichenkette. Ganzzahl Ein Zeitwert wird erzeugt, wenn die gegebene Ganzzahl die Anzahl der Sekunden seit 00:00:00 darstellt. Die Ganzzahl modulo der Anzahl der Sekunden pro Tag wird hergenommen, d.h. z.B. `(TIME 86400)' liefert 00:00:00. Fließkommazahl Analog Ganzzahl. Zeit Der Wert selbst. NIL NIL Andere Eine Fehlermeldung wird erzeugt und die Programmausführung abgebrochen.
Dieser Abschnitt listet die booleschen Operatoren auf.
AND
prüft, ob alle seine Parameter TRUE sind.
(AND
[expr ...])
prüft der Reihe nach expr ..., bis ein Ausdruck zu NIL wird. Sind alle Ausdrücke zu Nicht-NIL aufgelöst worden, dann wird der Wert des letzten Ausdrucks zurückgeliefert, anderenfalls NIL.
Diese Funktion ist nicht strikt, dies bedeutet, daß nicht alle Parameter von
AND
ausgewertet werden müssen, z.B. wird in `(AND NIL (+ 1 2))'
der Ausdruck `(+ 1 2)' nicht ausgewertet, da ein NIL-Wert schon
ermittelt wurde. In `(AND (+ 1 2) NIL)' jedoch wird der Ausdruck
`(+ 1 2)' ausgewertet.
OR
prüft, ob alle seiner Parameter NIL sind.
(OR
[expr ...])
prüft der Reihe nach expr ..., bis ein Ausdruck zu Nicht-NIL wird. Liefert den Wert des ersten Ausdrucks, der zu Nicht-NIL wurde, oder NIL, wenn alle Ausdrücke zu NIL wurden.
Diese Funktion ist nicht strikt, dies bedeutet, daß nicht alle Parameter von
AND
ausgewertet werden müssen, z.B. wird in `(OR TRUE (+ 1 2))'
der Ausdruck `(+ 1 2)' nicht ausgewertet, da ein Nicht-NIL-Wert (hier
TRUE) schon ermittelt wurde. In `(OR (+ 1 2) TRUE)' jedoch wird der
Ausdruck `(+ 1 2)' ausgewertet.
NOT
wird verwendet, um den Wert eines booleschen Ausdrucks zu
invertieren.
(NOT
expr)
liefert TRUE, wenn expr NIL ist, sonst NIL.
In diesem Abschnitt findet man Funktionen zum Vergleich von Werten vor (42).
Zum Vergleichen zweier Werte in einem MUIbase-Programm verwendet man
(
op expr1 expr2)
wobei op einer aus {=
, <>
, <
, >
, >=
,
<=
, =*
, <>*
, <*
, >*
, >=*
, <=*
}
ist.
Der Stern wird für besondere Vergleiche (Zeichenkettenvergleiche ohne
Groß-/Kleinschreibung, Datensatzvergleich mit der benutzerdefinierten
Reihenfolge) verwendet.
Die folgende Tabelle zeigt alle Regeln beim Vergleich von zwei Werten in einem MUIbase-Programm.
Typ Vergleichsreihenfolge Ganzzahl NIL < MIN_INT < ... < -1 < 0 < 1 < ... < MAX_INT Fließkommazahl NIL < -HUGE_VAL < ... < -1.0 < 0.0 < 1.0 < ... < HUGE_VAL Zeichenkette NIL < "" < "Z" < "a" < "aa" < "b" < ... (mit groß/klein) NIL <* "" <* "a" <* "AA" <* "b" < ... (groß/klein egal) mehrzeiliger Text wie bei Zeichenketten Datum NIL < 1.1.0000 < ... < 31.12.9999 Zeit NIL < 00:00:00 < ... < 23:59:59 Bool NIL < TRUE Datensatz NIL < jeder_Datensatz (Datensätze selbst können nicht mit < verglichen werden) NIL <* rec1 <* rec2 (Reihenfolge festgelegt durch Benutzer)
Anm.d.Übersetzers: HUGE_VAL steht für den größtmöglichen Fließkommazahlenwert, den ein Prozessor handhaben kann. MIN_INT ist die kleinste Ganzzahl und MAX_INT ist die größte Ganzzahl (nein, man kehrt nicht nur das Vorzeichen um, um die 'andere' größte Zahl zu erhalten).
CMP
liefert eine Ganzzahl, die eine Sortierung ihrer Argumente repräsentiert.
(CMP
expr1 expr2)
liefert einen Wert kleiner als 0, wenn expr1 kleiner ist als expr2; 0, wenn expr1 gleich expr2 ist und einen Wert größer 0, wenn expr1 größer ist als expr2. Zum Erkennen der Sortierung wird die einfache (ohne Stern) Sortierrelation wie bei den Relationaloperatoren (siehe Relationsoperatoren) verwendet.
Es darf nicht angenommen werden, daß der Rückgabewert immer -1, 0 oder 1 ist!
Beispiel: `(CMP "Bike" "bIKE")' liefert -32.
Siehe auch CMP*, Relationsoperatoren.
CMP*
ist die Stern-Version von CMP
.
Der Unterschied ist, daß CMP*
eine erweiterte Sortierung
wie bei den Relationsoperatoren (siehe Relationsoperatoren)
verwendet, bei denen Zeichenketten zeichengrößenunabhängig und
Datensätze gemäß ihrer benutzerdefinierten Datensatzreihenfolge
verglichen werden.
Beispiel: `(CMP* "Bike" "bIKE")' liefert 0.
Siehe auch CMP, Relationsoperatoren.
Einige mathematische Funktionen werden hier aufgelistet.
Zum Zusammenzählen von Zahlen verwendet man
(+
expr ...)
Liefert die Summe der Parameter expr .... Wenn irgendein Parameter NIL ist, dann ist das Ergebnis NIL. Wenn die Werte vom Typ Fließkomma- oder Ganzzahl sind, dann ist das Ergebnis auch eine Fließkommazahl (oder Ganzzahl).
Es lassen sich auch Zeichenketten und mehrzeilige Texte 'addieren'. In diesem Fall ist das Ergebnis die zusammengehängten Zeichenketten bzw mehrzeiligen Texte.
Ist expr vom Typ Datum und der Rest der Parameter sind Ganz-/Fließkommazahlen, dann wird die Summe der Ganz-/Fließkommazahlen als Anzahl Tage aufgefaßt und zu expr addiert. Ist das zurückgelieferte Ergebnis außerhalb des gültigen Bereichs (vor dem 1.1.0000 oder nach dem 31.12.9999), dann ist das Ergenis NIL.
Ist expr vom Typ Zeit und der Rest der Parameter sind Ganz-/Fließkommazahlen, dann wird die Summe der Ganz-/Fließkommazahlen als Anzahl Sekunden aufgefaßt und zu expr addiert. Es können jedoch in den restlichen Parametern Ausdrücke vom Typ Zeit vorhanden sein. Das zurückgelieferte Ergebnis wird modulo 24:00:00 genommen.
Ausdruck Wert (+ 1 2 3) 6 (+ 5 1.0) 6.0 (+ "Hallo" " " "Welt!") "Hallo Welt!" (+ 28.11.1968 +365 -28 -9) 22.10.1969 (+ 07:30:00 3600) 08:30:00 (+ 03:00:00 23:59:59) 02:59:59
Siehe auch Werte subtrahieren, 1+, Werte multiplizieren (*), CONCAT, CONCAT2.
Zum Subtrahieren von Werten verwendet man
(-
expr1 expr2 ...)
Zieht die Summe expr2 ... von expr1 ab. Hier gelten die gleichen Regeln wie beim Addieren von Werten (siehe Werte addieren), außer daß Zeichenketten und mehrzeilige Texte nicht subtrahiert werden können.
(-
expr)
hat eine spezielle Bedeutung: Es liefert den
negativen Wert von expr (Ganz- oder Fließkommazahl), z.B.
`(- (+ 1 2))' liefert -3.
Siehe auch Werte addieren, 1-.
1+
erhöht den Wert einer Ganz- bzw Fließkommazahl (-ausdrucks) um
Eins.
(1+
expr)
Liefert den Wert von expr (Ganz- oder Fließkommazahl) plus Eins. Wenn expr NIL ist, dann wird NIL geliefert.
Siehe auch Werte addieren, 1-.
1-
verringert den Wert einer Ganz- bzw Fließkommazahl (-ausdrucks) um
Eins.
(1-
expr)
Liefert den Wert von expr (Ganz- oder Fließkommazahl) minus Eins. Wenn expr NIL ist, dann wird NIL geliefert.
Siehe auch Werte subtrahieren, 1+.
Zum Multiplizieren von Ganz-/Fließkommazahlen verwendet man
(*
expr ...)
Liefert die Multiplikation der Ganz-/Fließkommazahlen expr .... Wenn alle Parameter Ganzzahlen sind, dann wird eine Ganzzahl geliefert, anderenfalls ist der Wert vom Typ Fließkommazahl.
Siehe auch Werte addieren, Werte dividieren.
Zum Dividieren von Ganz-/Fließkommazahlen verwendet man
(/
expr1 [expr2 ...])
Teilt expr1 durch die Multiplikation der restlichen Parameter. Liefert eine Fließkommazahl. Bei einer Division durch 0 wird NIL geliefert.
Siehe auch Werte multiplizieren (*), DIV, MOD.
DIV
verwendet man zur Ganzzahldivision.
(DIV
int1 int2)
Liefert die Ganzzahldivision von int1 mit int2. Zum Beispiel liefert `(DIV 5 3)' den Wert 1.
Siehe auch Werte dividieren, MOD.
MOD
wird zur Modulo-Berechnung verwendet.
(MOD
int1 int2)
Liefert int1 modulo int2. Zum Beispiel liefert `(MOD 5 3)' den Wert 2.
Siehe auch DIV.
MAX
liefert den Parameter mit dem größten Wert.
(MAX
expr ...)
Liefert den größten Wert der Argumente expr ... (alles Ganz- oder Fließkommazahlen). Ist eine der Ausdrücke NIL, dann wird NIL geliefert.
Siehe auch MIN.
MIN
liefert den Parameter mit dem kleinsten Wert.
(MIN
expr ...)
Liefert den kleinsten Wert der Argumente expr ... (alles Ganz- oder Fließkommazahlen). Ist eine der Ausdrücke NIL, dann wird NIL geliefert.
Siehe auch MAX.
ABS
berechnet den absoluten Wert eines Ausdrucks.
(ABS
expr)
Liefert den absoluten Wert(43) von expr (Ganz- oder Fließkommazahl). Ist expr NIL, dann wird NIL geliefert.
TRUNC
schneidet die Nachkommastellen einer Zahl ab.
(TRUNC
real)
Liefert die größte Ganzzahl (als Fließkommazahl), die nicht größer ist als die angegebene Fließkommazahl. Ist real NIL, dann wird NIL geliefert.
Beispiele: `(TRUNC 26.1)' liefert 26, `(TRUNC -1.2)' liefert -2.
Siehe auch ROUND.
ROUND
rundet einen Fließkommawert.
(ROUND
real digits)
Liefert den angegebenen Fließkommawert aufgerundet auf digits Stellen. Ist real oder digits gleich NIL, dann wird NIL geliefert.
Beispiele: `(ROUND 70.70859 2)' liefert 70.71, `(ROUND 392.36 -1)' liefert 392.0.
Siehe auch TRUNC.
RANDOM
kann zum Generieren von Zufallszahlen verwendet werden.
(RANDOM
expr)
Liefert eine Zufallszahl. Beim ersten Aufruf wird der Zufallszahlengenerator
mit dem Wert aus der aktuellen Uhrzeit initialisiert. RANDOM
erzeugt
eine Zufallszahl im Bereich von 0 ... expr, ausgenommen expr
selbst. Der Typ von expr (Ganz- oder Fließkommazahl) ist auch der
Rückgabewert-Typ. Ist expr NIL, dann wird NIL geliefert.
Beispiel Bedeutung (RANDOM 10) liefert einen Wert von 0 bis 9, (RANDOM 10.0) liefert einen Wert von 0.0 bis 9.99999...
Dieser Abschnitt behandelt Funktionen für Zeichenketten.
LEN
berechnet die Länge der Zeichenkette.
(LEN
str)
Liefert die Länge der gegebenen Zeichenkette oder NIL wenn str NIL ist.
Siehe auch WORDS, LINES, MAXLEN.
LEFTSTR
extrahiert eine Teilzeichenkette aus einer Zeichenkette.
(LEFTSTR
str len)
Liefert den linken Teil einer gegebenen Zeichenkette mit höchstens len Zeichen. Ist str oder len gleich NIL oder ist len negativ, dann wird NIL geliefert.
Beispiel: `(LEFTSTR "Hallo Welt!" 5)' liefert "Hallo".
Siehe auch RIGHTSTR, MIDSTR, WORD, LINE.
RIGHTSTR
extrahiert eine Teilzeichenkette aus einer Zeichenkette.
(RIGHTSTR
str len)
Liefert den rechten Teil einer gegebenen Zeichenkette mit höchstens len Zeichen. Ist str oder len gleich NIL oder ist len negativ, dann wird NIL geliefert.
Beispiel: `(RIGHTSTR "Hallo Welt!" 5)' liefert "Welt!".
Siehe auch LEFTSTR, MIDSTR, WORD, LINE.
MIDSTR
extrahiert eine Teilzeichenkette aus einer Zeichenkette.
(MIDSTR
str pos len)
Liefert einen Teil einer gegebenen Zeichenkette mit höchstens len Zeichen. Ist len NIL, dann ist die Anzahl der zurückgegebenen Zeichen nicht eingeschränkt(44). Die Teilzeichenkette beginnt an der Stelle pos (beginnend bei Null). Wenn str oder len NIL sind oder wenn len negativ ist, dann wird NIL zurückgeliefert. Ist pos außerhalb des gültigen Bereichs (negativ oder größer als Zeichenkettenlänge), dann wird NIL geliefert.
Beispiel: `(MIDSTR "Hallo Welt!" 3 5)' liefert "lo We".
Siehe auch LEFTSTR, RIGHTSTR, WORD, LINE, SETMIDSTR, INSMIDSTR.
SETMIDSTR
setzt eine Teilzeichenkette in einer Zeichenkette.
(SETMIDSTR
str index set)
Liefert eine Kopie der Zeichenkette str, in dem die Zeichenkette beginnend bei index mit der Zeichenkette set überschrieben wird. Die Länge der zurückgelieferten Zeichenkette ist größer oder gleich der von str. Ist einer der Parameter NIL oder ist index außerhalb des gültigen Bereichs, dann wird NIL geliefert.
Beispiel: `(SETMIDSTR "Hallo Welt!" 6 "Melanie!")' liefert "Hallo Melanie!".
Siehe auch INSMIDSTR, REPLACESTR.
INSMIDSTR
wird verwendet, um eine Teilzeichenkette in eine
Zeichenkette einzufügen.
(INSMIDSTR
str index insert)
Liefert eine Kopie der Zeichenkette str, in der die Zeichenkette insert an der gegebenen Stelle eingefügt wurde. Ist eines der Parameter NIL oder ist index außerhalb des gültigen Bereichs, dann wird NIL zurückgeliefert.
Beispiel: `(INSMIDSTR "Hallo Welt!" 6 "MUIbase-")' liefert "Hallo MUIbase-Welt!".
Siehe auch SETMIDSTR, REPLACESTR.
INDEXSTR
sucht in einer Zeichenkette nach dem ersten Vorkommen der
Teilzeichenkette.
(INDEXSTR
str substr)
Sucht nach dem ersten Vorkommen von substr in str. Der Zeichenkettenvergleich wird mit Beachtung der Groß-/Kleinschreibung durchgeführt. Liefert die Stelle (beginnend bei 0) von der Teilzeichenkette in str oder NIL, wenn die Teilzeichenkette nicht vorhanden ist. Ist eines der Argumente NIL, dann wird NIL zurückgegeben.
Beispiel: `(INDEXSTR "Hallo Welt!" "Welt")' liefert 6.
Siehe auch INDEXSTR*, RINDEXSTR, RINDEXSTR*, INDEXBRK, INDEXBRK*.
INDEXSTR*
hat den selben Effekt als INDEXSTR
(siehe INDEXSTR), außer daß der Zeichenkettenvergleich nicht auf
Groß-/Kleinschreibung achtet.
Siehe auch INDEXSTR, RINDEXSTR, RINDEXSTR*, INDEXBRK, INDEXBRK*.
INDEXBRK
sucht nach dem ersten Vorkommen eines Zeichens in einer
Zeichenkette.
(INDEXBRK
str brkstr)
Sucht nach dem ersten Vorkommen eines Zeichens von brkstr(45) in str. Der Zeichenkettenvergleich wird mit Beachtung der Groß-/Kleinschreibung durchgeführt. Liefert die Stelle (beginnend bei 0) des ersten Zeichens, das in str gefunden wurde, anderenfalls NIL. Ist eines der Parameter NIL, dann wird NIL geliefert.
Beispiel: `(INDEXBRK "Hallo Welt!" "aeiou")' liefert 1.
Siehe auch INDEXBRK*, RINDEXBRK, RINDEXBRK*, INDEXSTR, INDEXSTR*.
INDEXBRK*
hat den selben Effekt wie INDEXBRK
(siehe INDEXBRK), außer daß der Zeichenvergleich nicht auf
Groß-/Kleinschreibung achtet.
Siehe auch INDEXBRK, RINDEXBRK, RINDEXBRK*, INDEXSTR, INDEXSTR*.
RINDEXSTR
sucht in einer Zeichenkette nach dem letzten Vorkommen der
Teilzeichenkette.
(RINDEXSTR
str substr)
Sucht nach dem letzten Vorkommen von substr in str. Der Zeichenkettenvergleich wird mit Beachtung der Groß-/Kleinschreibung durchgeführt. Liefert die Stelle (beginnend bei 0) von der Teilzeichenkette in str oder NIL, wenn die Teilzeichenkette nicht vorhanden ist. Ist eines der Argumente NIL, dann wird NIL zurückgegeben.
Beispiel: `(RINDEXSTR "Do itashimashite." "shi")' liefert 11 (46).
Siehe auch RINDEXSTR*, INDEXSTR, INDEXSTR*, RINDEXBRK, RINDEXBRK*.
RINDEXSTR*
hat den selben Effekt als RINDEXSTR
(siehe RINDEXSTR), außer daß der Zeichenkettenvergleich nicht auf
Groß-/Kleinschreibung achtet.
Siehe auch RINDEXSTR, INDEXSTR, INDEXSTR*, RINDEXBRK, RINDEXBRK*.
RINDEXBRK
sucht nach dem letzten Vorkommen eines Zeichens in einer
Zeichenkette.
(RINDEXBRK
str brkstr)
Sucht nach dem letzten Vorkommen eines Zeichens von brkstr(47) in str. Der Zeichenkettenvergleich wird mit Beachtung der Groß-/Kleinschreibung durchgeführt. Liefert die Stelle (beginnend bei 0) des letzten Zeichens, das in str gefunden wurde, anderenfalls NIL. Ist eines der Parameter NIL, dann wird NIL geliefert.
Beispiel: `(RINDEXBRK "Konnichiwa" "chk")' liefert 6.
Siehe auch RINDEXBRK*, INDEXBRK, INDEXBRK*, RINDEXSTR, RINDEXSTR*.
RINDEXBRK*
hat den selben Effekt wie RINDEXBRK
(siehe RINDEXBRK), außer daß der Zeichenvergleich nicht auf
Groß-/Kleinschreibung achtet.
Siehe auch RINDEXBRK, INDEXBRK, INDEXBRK*, RINDEXSTR, RINDEXSTR*.
REPLACESTR
ersetzt Teilzeichenketten durch andere.
(REPLACESTR
str substr replacestr)
Ersetzt alle Vorkommen von substr in str durch replacestr. Wenn eine der Zeichenketten NIL ist oder substr leer ist, dann wird NIL zurückgeliefert.
Beispiel: `(REPLACESTR "From Freiburg to San Francisco" "Fr" "X")' liefert "Xom Xeiburg to San Xancisco".
Siehe auch SETMIDSTR, INSMIDSTR, REMCHARS.
REMCHARS
entfernt Zeichen aus einer Zeichenkette.
(REMCHARS
str chars-to-remove)
Liefert eine Kopie von str, in der alle Zeichen von chars-to-remove entfernt wurden. Ist str oder chars-to-remove NIL, dann wird NIL geliefert.
Beispiel: `(REMCHARS deine-zeichenkette " \t\n")' entfernt alle Leerzeichen, Tabulatoren und Neue-Zeile-Zeichen aus deine-zeichenkette.
Siehe auch REPLACESTR, TRIMSTR.
TRIMSTR
entfernt führende und abschließende Leerzeichen von einer
Zeichenkette.
(TRIMSTR
str)
Liefert eine Kopie von str, in der alle führenden und abschließenden Leerzeichen entfernt wurden.
Beispiel: (TRIMSTR " Ich fuhr Selmas Fahrrad zu Schrott. ")
liefert
"Ich fuhr Selmas Fahrrad zu Schrott.".
Siehe auch REMCHARS.
WORD
liefert ein Wort einer Zeichenkette.
(WORD
str num)
Liefert das num-te Wort (beginnend bei Null) aus der gegebenen Zeichenkette. Wörter in einer Zeichenkette sind nicht-leere Teilzeichenketten, die durch Leerzeichen-ähnliche Zeichen (z.B. Leerzeichen, Tabulatoren und Neue-Zeile-Zeichen) getrennt werden.
Ist str oder num gleich NIL oder ist num außerhalb des gültigen Bereichs (negativ oder größer als Anzahl Wörter in der Zeichenkette), dann wird NIL zurückgeliefert.
Beispiel: `(WORD "Deshalb lieh ich Selma mein Fahrrad." 3)' liefert "Selma".
Siehe auch WORDS, LINE, LEFTSTR, RIGHTSTR, MIDSTR.
WORDS
zählt die Anzahl der Wörter in einer Zeichenkette.
(WORDS
str)
Liefert die Anzahl der Wörter in der gegebenen Zeichenkette oder NIL, wenn str NIL ist. Wörter sind Teilzeichenketten, die durch Leerzeichen-ähnliche Zeichen (z.B. Leerzeichen, Tabulatoren und Neue-Zeile-Zeichen) getrennt werden.
Beispiel: `(WORDS "In Wirklichkeit ist es aber nicht mein Fahrrad.")' liefert 8.
CONCAT
verbindet Zeichenketten.
(CONCAT
[str ...])
Liefert die Verknüpfung der gegebenen Liste von Zeichenketten, wobei einzelne Leerzeichenzwischen den Zeichenketten eingefügt werden. Ist eine der Zeichenketten NIL oder die Liste leer, dann wird NIL zurückgeliefert.
Beispiele: `(CONCAT "Ich" "dachte," "es" "war" "ein "verlassenes" "Fahrrad.")' liefert "Ich dachte, es war ein verlassenes Fahrrad.".
Siehe auch CONCAT2, Werte addieren, COPYSTR, SPRINTF.
CONCAT2
verbindet Zeichenketten.
(CONCAT2
insert [str ...])
Liefert die Verknüpfung der gegebenen Liste von Zeichenketten. Zwischen den Zeichenketten wird jeweils die gegebene Zeichenkette insert eingefügt. Ist eine der Zeichenketten NIL oder die Liste leer, dann wird NIL zurückgeliefert.
Beispiel: `(CONCAT2 "! " "Aber" "es" "war es nicht!")' liefert "Aber! es! war es nicht!".
Siehe auch CONCAT, Werte addieren, COPYSTR, SPRINTF.
COPYSTR
erzeugt Kopien einer Zeichenkette.
(COPYSTR
str num)
Liefert eine Zeichenkette, die num mal die Zeichenkette str enthält. Ist str NIL, num gleich NIL oder kleiner als NUll, dann wird NIL zurückgegeben.
Beispiel: `(COPYSTR "+-" 5)' liefert "+-+-+-+-+-"
Siehe auch CONCAT CONCAT2, Werte addieren, SPRINTF.
UPPER
wandelt eine Zeichenkette in Großbuchstaben.
(UPPER
str)
Liefert eine Kopie der gegebenen Zeichenkette, in der alle Zeichen zu Großbuchstaben umgewandelt wurden(48). Ist str NIL, dann wird NIL geliefert.
Beispiel: `(UPPER "Selma fand einen Brief, der an mein Fahrrad geheftet war.")' liefert "SELMA FAND EINEN BRIEF, DER AN MEIN FAHRRAD GEHEFTET WAR.".
Siehe auch LOWER.
LOWER
wandelt eine Zeichenkette in Kleinbuchstaben.
(LOWER
str)
Liefert eine Kopie der gegebenen Zeichenkette, in der alle Zeichen zu Kleinbuchstaben umgewandelt wurden. Ist str NIL, dann wird NIL geliefert.
Beispiel: `(LOWER "Der Brief war von Silke.")' liefert "der brief war von silke.".
Siehe auch UPPER.
ASC
wandelt ein Zeichen in ihren ASCII-Code.
(ASC str)
Liefert den ASCII-Code des ersten Zeichens von str. Ist str leer, wird 0 geliefert. Ist str NIL, dann wird NIL geliefert.
Beispiel: (ASC "A")
liefert 65.
CHR
wandelt einen ASCII-Code in ein Zeichen um.
(CHR
int)
Liefert eine Zeichenkette, die das Zeichen mit dem ASCII-Code int enthält. Ist int gleich 0, dann wird eine leere Zeichenkette geliefert. Ist int NIL oder nicht inner halb des ASCII-Zeichensatzes (0..255), dann wird NIL geliefert.
Beispiel: `(CHR 99)' liefert to "c".
LIKE
vergleicht Zeichenketten.
(LIKE
str1 str2)
Liefert TRUE, wenn str1 mit str2 übereinstimmt, anderenfalls NIL. Die Zeichenkette str2 kann die Jokerzeichen '?' und '*' enthalten, wobei '?' genau irgendein einzelnes Zeichen und '*' eine Zeichenkette jeder Länge irgendeines Inhalts(49) darstellt. Der Zeichenkettenvergleich wird ohne Beachtung der Groß-/Kleinschreibung durchgeführt.
Beispiel: `(LIKE "Silke war für ein Jahr in Frankreich." "*Jahr*")' liefert TRUE.
Siehe auch Vergleichsfunktionen.
SPRINTF
formatiert eine Zeichenkette mit verschiedenen Daten.
(SPRINTF
fmt [expr ...])
SPRINTF
erhält eine Reihe von Parametern, die in Zeichenketten
umgewandelt werden und in aufbereiteter Form als einzelne Zeichenkette
zurückgegeben wird.
Die Zeichenkette fmt entscheidet genau, was in die zurückgegebene
Zeichenkette geschrieben werden soll und kann zwei Arten von Elemente
enthalten: ordinäre Zeichen, die unverändert kopiert werden und
Umwandlungsbefehle, die SPRINTF
anweisen, die Parameter aus seiner
Parameterliste zu nehmen und zu formatieren.
Umwandlungsbefehle beginnen immer mit dem Zeichen `%'.
Umwandlungsbefehle benötigen immer diese Form:
%
[flags][width][.
precision]type
where
SPRINTF
umwandeln soll, wie etwa Zeichenkette, Ganzzahl, Fliekommazahl
etc.
Zu beachten ist, daß alle Felder außer type optional sind. Die folgenden Tabellen listen die gültigen Optionen für diese Felder auf.
(Anm.d.Übersetzers: Bitte nicht den davorstehenden Punkt übersehen!)
SPRINTF
liefert die formatierte Zeichenkette oder NIL, wenn fmt
NIL ist.
Aufruf Ergebnis (SPRINTF "Hallo") "Hallo" (SPRINTF "%s" "Hallo") "Hallo" (SPRINTF "%10s" "Hallo") " Hallo" (SPRINTF "%-10.10s" "Hallo") "Hallo " (SPRINTF "%010.3s" "Hallo") " Hal" (SPRINTF "%-5.3b" TRUE) "TRU " (SPRINTF "%i" 3) "3" (SPRINTF "%03i" 3) "003" (SPRINTF "% 0+- 5.3i" 3) " 003 " (SPRINTF "%f" 12) "12.00" (SPRINTF "%10e 12.0) " 1.20e+1" (SPRINTF "%+-10.4f" 12.0) "+12.0000 " (SPRINTF "%10.5t" 12:30:00) " 12:30" (SPRINTF "%d" 28.11.1968) "28.11.1968" (SPRINTF "Ha%s %4.4s!" "llo" "Weltmeisterschaft") "Hallo Welt!"
Siehe auch PRINTF, FPRINTF, STR, Werte addieren, CONCAT, CONCAT2, COPYSTR.
Dieser Abschnitt behandelt Funktionen für mehrzeilige Texte.
LINE
holt eine Zeile aus einem mehrzeiligen Text.
(LINE
memo num)
Liefert die num-te Zeile (beginnend bei Null) aus dem gegebenen mehrzeiligen Text. Die Zeile hat dann kein abschließendes Neue-Zeile-Zeichen.
Ist str oder num gleich NIL oder ist num außerhalb des gültigen Bereichs (negativ oder größer als Anzahl Zeilen), dann wird NIL zurückgeliefert.
LINES
liefert die Anzahl der Zeilen in einem mehrzeiligen Text.
(LINES
memo)
Liefert die Anzahl der Zeilen des gegebenen mehrzeiligen Textes oder NIL, wenn memo NIL ist.
MEMOTOLIST
wandelt einen mehrzeiligen Text in eine Liste von
Zeichenketten um.
(MEMOTOLIST
memo)
Wandelt den gegebenen mehrzeiligen Text in eine Liste. Ist memo gleich NIL, dann wird NIL geliefert, anderenfalls wird eine Liste erzeugt, in der jedes Element eine Zeile des mehrzeiligen Textes enthält.
Beispiel: `(MEMOTOLIST "Meine Versicherung\nzahlt für\ndas kaputte Fahrrad.")' liefert ( "Meine Versicherung" "zahlt für" "das kaputte Fahrrad." ).
Siehe auch LISTTOMEMO.
LISTTOMEMO
wandelt eine Liste in einen mehrzeiligen Text um.
(LISTTOMEMO
list)
Wandelt eine gegebene Liste in einen mehrzeiligen Text. Ist list gleich NIL, dann wird NIL zurückgegeben, anderenfalls wird ein mehrzeiliget Text erzeugt, dessen einzelne Zeilen die Zeichenkettendarstellung des entsprechenden Listenelements enthalten(50).
Beispiel: `(LISTTOMEMO (LIST "Silke" "leiht mir" "'mein' Fahrrad" "bis zum" 01.09.1998)' liefert: "Silke\nleiht mir\n'mein' Fahrrad\nbis zum\n01.09.1998".
Siehe auch MEMOTOLIST.
FILLMEMO
füllt einen mehrzeiligen Text mit den Ergebnissen von
Ausdrücken.
(FILLMEMO
memo)
Erzeugt eine Kopie des gegebenen mehrzeiligen Textes, in dem alle Teilzeichenketten der Form `$(expr)' durch ihre Ergebnisse nach der Auswertung ersetzt werden.
Beispiel: `(FILLMEMO "(+ 1 1) ist $(+ 1 1).")' liefert "(+ 1 1) ist 2."
Man sollte nur kleine Ausdrücke in einem mehrzeiligen Text verwenden, da die Fehlersuche nicht einfach ist(51).
Siehe auch FORMATMEMO, INDENTMEMO.
FORMATMEMO
formatiert einen mehrzeiligen Text.
(FORMATMEMO
memo width fill)
Formatiert memo in einen mehrzeiligen Text mit Zeilen, die nicht länger sind als width Zeichen. Ist fill nicht NIL, dann werden Leerzeichen zum Auffüllen der Zeilen verwendet, damit die Zeilen genau die Länge width erhalten. Der mehrzeilige Test wird abschnittweise abgearbeitet. Ein Abschnitt beginnt beim ersten Zeichen, das kein Leerzeichen ist. Die Zeile mit diesem Zeichen mit den nachfolgenden Zeilen bis zur Zeile, in der das erste Zeichen win Leerzeichen ist, wird als Abschnitt aufgefaßt. Der gesamte Abschnitt wird wortweise formatiert, dies bedeutet, es werden soviele Wörter in eine Zeile gesetzt, wie dafür Platz ist(52).
Siehe auch FILLMEMO, INDENTMEMO.
INDENTMEMO
rückt einen mehrzeiligen Text ein, in dem links Leerzeichen
eingefügt werden.
(INDENTMEMO
memo indent)
Liefert eine Kopie des gegebenen mehrzeiligen Textes, in dem jede Zeile mit indent Leerzeichen eingerückt wird. Ist memo oder indent NIL, dann wird NIL zurückgeliefert. Ist indent negativ, dann wird 0 angenommen.
Siehe auch FILLMEMO, FORMATMEMO.
Dieser Abschnitt listet Funktionen zum Verarbeiten von Listen auf.
CONS
erzeugt ein Paar von Ausdrücken.
(CONS
elem list)
Erzeugt eine neue Liste. Das erste Element der neuen Liste ist elem, der Rest sind die Elemente von list (die eine Liste sein muß oder NIL). Die Liste list wird nicht kopiert, sondern nur ein Zeiger auf diese wird verwendet(53)!
Beispiel: `(CONS 1 (CONS 2 NIL))' liefert ( 1 2 ).
Die Elemente der Liste können von jedem Typ sein, z.B. ist es auch möglich,
eine Liste von Listen zu haben (z.B. siehe SELECT).
Der Konstruktor CONS
kann auch verwendet werden, um Element-Paare zu
erzeugen, z.B. `(CONS 1 2)' ist ein Paar mit den Ganzzahlen 1 und 2.
LIST
erzeugt eine Liste anhand ihrer Parameter.
(LIST
[elem ...])
nimmt die Parameter elem ... und generiert daraus eine Liste.
Dies ist gleichbedeutend dem Aufruf von (CONS
elem (CONS
... NIL))
.
Man beachte, daß NIL alleine für eine leere Liste steht.
LENGTH
ermittelt die Länge einer Liste.
(LENGTH
list)
liefert die Länge der gegebenen Liste.
Beispiel: `(LENGTH (LIST "a" 2 42 3))' liefert 4.
Siehe auch LIST.
FIRST
holt das erste Element aus einer Liste.
(FIRST
list)
liefert das erste Element der gegebenen Liste. Ist list leer (NIL), dann wird NIL geliefert.
Siehe auch REST, LAST, NTH, CONS.
REST
liefert die Teilliste nach dem ersten Element einer Liste.
(REST
list)
liefert den Rest der gegebenen Liste (die Liste ohne dem ersten Element). Ist list leer (NIL), dann wird NIL zurückgeliefert.
Beispiel: `(REST (LIST 1 2 3))' liefert ( 2 3 ).
LAST
holt das letzte Element aus einer Liste.
(LAST
list)
Liefert das letzte Element der gegebenen Liste oder NIL, wenn list NIL ist.
NTH
holt das n-te Element aus einer Liste.
(NTH
n list)
Liefert das n-te Element der gegebenen Liste (beginnend bei 0) oder NIL, wenn das Element nicht existiert.
APPEND
verbindet Listen.
(APPEND
[list ...])
liefert die Verknüpfung von list ....
Beispiel: `(APPEND (list 1 2) (list 3 4) (list 5))' liefert ( 1 2 3 4 5 ).
Siehe auch LIST.
REVERSE
kehrt eine Liste um.
(REVERSE
list)
liefert die umgekehrte Liste(54).
Beispiel: `(REVERSE (list 1 2 3))' liefert ( 3 2 1 ).
MAPFIRST
wendet eine Funktion auf alle Listenelemente an.
(MAPFIRST
func list [...])
Erzeugt eine Liste, deren Elemente das Ergebnis einer angegebenen Funktion sind, die als Parameter die einzelnen Listenelemente der Reihe nach bekommen hat. Die Länge der zurückgelieferten Liste ist genau so lang, wie die längste angegebene Liste. Ist eine der gegebenen Listen zu kurz, dann wird die Liste mit NIL aufgefüllt.
Ausdruck Wert (MAPFIRST 1+ (LIST 1 2 3)) ( 2 3 4 ) (MAPFIRST + (LIST 1 2 3) (LIST 2 3)) ( 3 5 NIL )
SORTLIST
sortiert die Elemente einer Liste.
(SORTLIST
func list)
Liefert eine Kopie der gegebenen Liste, die mit der Funktion func sortiert wurde. Die Sortierfunktion muß zwei Parameter für jedes Element verarbeiten und einen Ganzzahlwert liefern, der kleiner als Null ist, wenn das erste Element 'kleiner' ist als das zweite, einen Wert größer Null, wenn das zweite 'größer' ist als das erste und einen Wert gleich Null, wenn beide Elemente 'gleich' sind.(55)
Beispiel für eine Zeichenkettenvergleichsfunktion für die Sortierung:
(DEFUN cmp_str (x y) (COND ((< x y) -1) ((> x y) 1) (TRUE 0) ) )
Nun läßt sich eine Liste durch den Aufruf
(SORTLIST cmp_str (LIST "hi" "gut" "großartig" "ok"))
sortieren, die ( "großartig" "gut" "hi" "ok" ) liefert.
Siehe auch SORTLISTGT, MAPFIRST.
SORTLIST
sortiert die Elemente einer Liste.
(SORTLISTGT
gtfunc list)
Arbeitet wie SORTLIST
, aber hier wird eine Sortierfunktion angegeben,
die einen Wert ungleich NIL liefert, wenn das erste Element 'größer' ist als
das zweite, anderenfalls NIL.
Beispiel: `(SORTLISTGT > (LIST "hi" "gut" "großartig" "ok"))' liefert ( "großartig" "gut" "hi" "ok" ).
Siehe auch SORTLIST, MAPFIRST.
Zum Abfragen von Benutzereingaben können folgende Funktionen verwendet werden:
ASKFILE
fragt den Benutzer nach einem Dateinamen.
(ASKFILE
title oktext default savemode)
Öffnet ein Dateiauswahlfenster zur Eingabe eines Dateinamens. Der Fenstertitel kann in title, der Text des `Ok'-Knopfes in oktext und der vorgegebene Dateiname in default gesetzt werden. Für jeden dieser Argumente kann NIL gesetzt werden, um Vorgabewerte zu verwenden. Der letzte Parameter savemode (bool) setzt das Dateiauswahlfenster in den Speichermodus. Dieser Modus sollte verwendet werden, wenn nach einem Dateinamen gefragt wird, im etwas in eine Datei zu schreiben.
ASKFILE
liefert den eingegebenen Dateinamen als Zeichenkette oder NIL,
wenn der Benutzer das Fenster mit Abbrechen verlassen hat.
ASKDIR
fragt den Benutzer nach einem Verzeichnisnamen.
(ASKDIR
title oktext default savemode)
Öffnet ein Dateiauswahlfenster zur Eingabe eines Verzeichnisnamens. Die
Parameter werden auf die gleiche Weise verwendet als
wie(56) in
ASKFILE
(siehe ASKFILE).
ASKDIR
liefert den eingegebenen Verzeichnisnamen als Zeichenkette oder
NIL, wenn der Benutzer das Fenster mit Abbrechen verlassen hat.
ASKSTR
fragt den Benutzer nach einer Zeichenkette.
(ASKSTR
title oktext default maxlen)
Öffnet ein Fenster, das nach einer Zeichenketteneingabe fragt. Der Fenstertitel, der Text des `Ok'-Knopfes und der Vorgabewert können mit title, oktext beziehungsweise default (mit Zeichenketten oder NIL für die Vorgabewerte) gesetzt werden. maxlen bestimmt die maximale Anzahl Zeichen, die der Benutzer eingeben kann.
ASKSTR
liefert die eingegebene Zeichenkette oder NIL, wenn der
Benutzer das Fenster mit Abbrechen verlassen hat.
Siehe auch ASKFILE, ASKDIR, ASKCHOICESTR, ASKINT.
ASKINT
fragt den Benutzer nach einer Ganzzahl.
(ASKINT
title oktext default min max)
Öffnet ein Eingabefenster, das nach einer Ganzzahleingabe fragt. Der Fenstertitel und der Text des `Ok'-Knopfes können mit title und oktext (mit Zeichenketten oder NIL für Vorgabewerte) gesetzt werden. In default wird der Vorgabewert übergeben oder NIL, wenn mit einem leeren Feld begonnen werden soll. In min und max wird der erlaubte Zahlenbereich festgelegt. Eingegebene Werte außerhalb dieses Bereichs werden vom Eingabefenster nicht akzeptiert. Man verwende NIL für den Vorgabebereich(57).
ASKINT
liefert die eingegebene Ganzzahl oder NIL, wenn der Benutzer
das Fenster mit Abbrechen verlassen hat.
Siehe auch ASKSTR.
ASKCHOICE
fragt den Benutzer nach einer Auswahl aus mehreren Elementen.
(ASKCHOICE
title oktext choices default)
Öffnet ein Eingabefenster, das den Benutzer nach einem Element aus mehreren fragt. Der Fenstertitel und der Text des `Ok'-Knopfes können mit title und oktext (mit Zeichenketten oder NIL für Vorgabewerte) gesetzt werden. In choices wird eine Liste angegeben, aus dieser sich der Benutzer einen Eintrag auswählen kann. Diese Listeneinträge können alle Arten von Ausdrücken haben, die in Zeichenketten umgewandelt werden können. Die vorgegebene Auswahl wird in default angegeben, die ein Ganzzahlindex auf die Auswahlliste (beginnend bei Index 0 für das erste Element) ist und NIL markiert keine vorgegebene Auswahl.
ASKCHOICE
liefert den Index des gewählten Elements oder NIL, wenn der
Benutzer das Fenster mit Abbrechen verlassen hat.
(LET ((items (LIST "Erster Eintrag" 2 3.14 "Letzter Eintrag")) index) (SETQ index (ASKCHOICE "Wähle ein Element" "Ok" items NIL)) (IF index (PRINTF "Benutzer wählte Element Nummer %i mit dem Inhalt <%s>\n" index (STR (NTH index items)) ) ) )
Siehe auch ASKCHOICESTR, ASKOPTIONS.
ASKCHOICESTR
fragt den Benutzer nach einer Zeichenkette und bietet
vorgegebene an.
(ASKCHOICESTR
title oktext strings default)
Öffnet ein Eingabefenster, das dem Benutzer erlaubt, eine Zeichenkette aus mehreren auszuwählen oder jede beliebige Zeichenkette im separaten Zeichenkettenfeld einzugeben. Der Fenstertitel und der Text des `Ok'-Knopfes können mit title und oktext (mit Zeichenketten oder NIL für Vorgabewerte) gesetzt werden. In strings wird eine Liste von Zeichenketten übergeben, aus der der Benutzer eine auswählen kann. Der Vorgabewert des Zeichenkettenfeldes kann mit default (als Zeichenkette oder NIL für ein leeres Zeichenkettenfeld) gesetzt werden.
ASKCHOICESTR
liefert die ausgewählte Zeichenkette oder NIL, wenn der
Benutzer das Fenster mit Abbrechen verlassen hat.
(LET ((strings (LIST "Claudia" "Mats" "Ralphie")) likebest) (SETQ likebest (ASKCHOICESTR "Wen mögen Sie am liebsten?" "Ok" strings "Meine Collie-Hunde!") ) (IF likebest (PRINTF "Benutzer wählte <%s>\n" likebest)) )
Siehe auch ASKCHOICE, ASKOPTIONS.
ASKOPTIONS
fragt den Benutzer nach mehreren aus einer Liste von
Elementen.
(ASKOPTIONS
title oktext options selected)
Öffnet ein Eingabefenster, das dem Benutzer erlaubt, mehrere Optionen aus vielen auszuwählen. Der Fenstertitel und der Text des `Ok'-Knopfes können mit title und oktext (mit Zeichenketten oder NIL für Vorgabewerte) gesetzt werden. In options wird eine Liste von Optionen angegeben, aus der der Benutzer mehrere auswählen kann. Die Listenelemente können jeder Art von Ausdrücken sein, die sich in Zeichenketten umwandeln lassen. Die Vorgabeauswahl läßt sich in selected festlegen, die eine Liste von Ganzzahlen ist und jeweils den Index des entsprechenden Elements in der Liste options angibt, der vorab ausgewählt wird. Wird NIL statt der Liste angegeben, dann werden keine Elemente vorab ausgewählt.
ASKOPTIONS
liefert eine Liste von Ganzzahlen, die den Index der
ausgewählten Elemente enthält oder NIL, wenn der Benutzer das Fenster mit
Abbrechen verlassen oder kein Element ausgewählt hat.
(LET ((options (LIST "Salva Mea" "Insomnia" "Don't leave" "7 days & 1 week")) (selected (LIST 0 1 3)) ) (SETQ selected (ASKOPTIONS "Wähle Musiktitel" "Ok" options selected)) (IF selected ( (PRINTF "Benutzer wählte folgende Einträge:\n") (DOLIST (i selected) (PRINTF "\tNummer %i enthält: <%s>\n" i (STR (NTH i options))) ) ) ) )
(Anm.d.Übersetzers: Hier hören Programmierer und Übersetzer die gleiche Musik von Faithless :-)
ASKBUTTON
fragt den Benutzer nach einen Knopfdruck.
(ASKBUTTON
title text buttons canceltext)
Öffnet ein Eingabefenster mit dem gegebenen Fenstertitel title (als Zeichenkette oder NIL für einen Vorgabetitel) und dem gegebenen Beschreibungstext text (als Zeichenkette oder NIL für keinen Text). Die Funktion wartet auf einen Druck der in buttons (als Liste von Zeichenketten) festgelegten Knöpfe oder des `Abbrechen'-Knopfes. Der Text des Abbruchknopfes läßt sich mit canceltext ändern. Wird hier NIL angegeben, dann wird ein Vorgabetext verwendet, der sich nach der Anzahl der festgelegten Knöpfe richtet.
ASKBUTTON
liefert die Nummer des gedrückten Knopfes (beginnend bei 0
mit dem am weitesten links angeordneten Knopf) oder NIL, wenn der Benutzer
den `Abbruch'-Knopf gedrückt hat.
(LET ((buttons (LIST "Zuhause" "Im Bett" "Vor meinem Amiga")) index) (SETQ index (ASKBUTTON "Bitte beantworten:" "Wo werden sie morgen sein?" buttons "Weiß nicht") ) (IF index (PRINTF "Benutzer entschied sich für: <%s>\n" (NTH index buttons)) ) ) (ASKBUTTON "Info" "Du hast nun schon für fünf\nStunden mit deinem Amiga gespielt.\nGeh ins Bett!" NIL NIL )
Siehe auch ASKCHOICE.
ASKMULTI
fragt den Benutzer nach verschiedenartigen Informationen.
(ASKMULTI
title oktext itemlist)
ASKMULTI
ist ein Mehrzweck-Eingabefenster. Es öffnet ein Fenster mit
dem angegebenen Titel title, einem Satz von grafischen Objekten für die
Dateneingabe und zwei Knöpfen (`Ok' und `Abbrechen') zum Beenden
des Eingabefensters. Der Text für den `Ok'-Knopf kann mit oktext
verändert werden (als Zeichenkette oder NIL für einen Vorgabetext). Der
Satz der grafischen Objekte werden in itemlist festgelegt, das eine
Liste ein Elementen ist, in der jedes eine der folgenden Formate hat:
(LIST
title"String"
initial [help])
zum Bearbeiten einer Textzeile,(LIST
title"Memo"
initial [help])
zum Bearbeiten von mehrzeiligen Texten,(LIST
title"Integer"
initial [help])
zum Bearbeiten einer Ganzzahl,(LIST
title"Real"
initial [help])
zum Bearbeiten einer Fließkommazahl,(LIST
title"Date"
initial [help])
zum Bearbeiten eines Datums,(LIST
title"Time"
initial [help])
zum Bearbeiten einer Zeit,(LIST
title"Bool"
initial [help])
zum Bearbeiten eines booleschen Wertes,(LIST
title"Choice"
initial(LIST
choice ...)
[help])
für ein Auswahlfeld.(LIST
title"ChoiceList"
initial(LIST
choice ...)
[help])
zum Auswählen eines Elements aus einer Liste.(LIST
title"Options"
initial(LIST
choice ...)
[help])
zum Auswählen mehrerer Elemente aus einer Liste. non-list-expr für statischen Text
Der Titel title (als Zeichenkette oder NIL für keinen Titel) wird links neben dem grafischen Objekt angeordnet. Ist der Vorgabewert initial NIL, dann wird ein Vorgabewert verwendet (z.B. ein leeres Textfeld). Für Auswahlfelder muß der Vorgabewert der Index (beginnend bei 0) sein, für Auswahllistenfelder darf der Vorgabewert NIL (kein Eintrag ausgewählt) sein und für Optionsfelder muß der Vorgabewert eine Liste von Ganzzahlen sein, die die Indexe (beginnend bei 0) der Elemente sein, die vorbelegt sein sollen. Das optionale Hilfsfeld (eine Zeichenkette) kann verwendet werden, um dem Benutzer mehr Informationen über die Verwendung des Feldes mitzugeben.
ASKMULTI
liefert eine Liste von Werten, die der Benutzer bearbeitet
und über den `Ok'-Knopf bestätigt hat. Jeder Ergebniswert eines Feldes
hat das gleiche Format wie der für den Vorgabewert, z.B. für ein
Auswahllistenfeld ist der Rückgabewert der Index des ausgewählten Elements
(oder NIL, wenn keines ausgewählt wurde) oder für Optionsfelder ist er die
Liste von Ganzzahlen, die die Indexe der ausgewählten Elemente darstellen.
Für statischen Text wird NIL zurückgegeben.
Wurde z.B. ein Datumsfeld, ein statischer Text, ein Auswahlfeld, ein Optionsfeld und ein Zeichenkettenfeld mit dem Vorgabewert "Welt" festgelegt und der Benutzer gab 11.11.1999 ein, wählte den Auswahleintrag mit dem Index 2, wählte das dritte und vierte Element des Optionsfeldes und ließ das Zeichenkettenfeld unberührt, dann liefert die Funktion die Liste ( 11.11.1999 NIL 2 ( 3 4 ) "world" ).
Brach der Benutzer das Eingabefenster ab, wird NIL geliefert.
(ASKMULTI "Bitte bearbeiten:" NIL (LIST (LIST "_Name" "String" "") (LIST "_Geburtstag" "Date" NIL) (LIST "Ge_schlecht" "Choice" 0 (LIST "männlich" "weiblich")) (LIST "_Hat ein Auto?" "Bool" NIL) (LIST "_Mag", "Options" (LIST 0 2) (LIST "Bier" "Wein" "Whisky" "Wodka" "Schnaps") )) )
Man sehe sich auch das Projekt `AskDemo.mb' für weitere Beispiele an.
Dieser Abschnitt listet die Funktionen und Variablen zur Dateiein- und ausgabe (z.B. drucken) auf.
FOPEN
öffnet eine Datei zum Lesen/Schreiben.
(FOPEN
filename mode)
Öffnet eine Datei mit dem Dateinamen filename (als Zeichenkette). Das Argument mode (als Zeichenkette) steuert den Zugriff auf die Datei. Mit `"w"' wird die Datei zum Schreiben geöffnet, mit `"a"' zum Anfügen an die bestehende Datei und mit `"r"' zum Lesen aus einer Datei. Es sind auch andere Zeichen (oder Kombinationen von ihnen) möglich, wie z.B. `"r+"' zum Lesen und Schreiben. Es gibt keine Überprüfung, ob die angegebenen Modi gültig sind. Es wird jedoch NIL zurückgeliefert, wenn die Datei nicht geöffnet werden konnte.
FOPEN
liefert bei Erfolg einen Dateihandler. Schlug er fehl, wird NIL
geliefert. Sind filename oder mode NIL, dann wird NIL
zurückgeliefert.
Beispiel: `(FOPEN "PRT:" "w")' öffnet und liefert einen Dateihandle zum Drucker.
Siehe auch FCLOSE, stdout, FFLUSH.
FCLOSE
schließt eine Datei.
(FCLOSE
file)
Schließt gegebene Datei. Es liefert 0 bei Erfolg oder NIL, wenn ein Fehler auftrat. Ist file NIL, dann wird 0 geliefert (keine Fehler)! Der Zugriff auf eine Datei nach dem Schließen einer Datei ist eine illegale Operation und führt zum Abbruch der Programmausführung mit einer Fehlermeldung.
Die globale Variable stdout
trägt den Dateihandle zur Standardausgabe
von MUIbase. Der Ausgabedateinamen kann im Menüpunkt `Programm -
Ausgabedatei...' gesetzt werden. Man kann `PRT:' verwenden, um die
Ausgabe zum Drucken zu schicken oder `CON:////Output/CLOSE/WAIT' für die
Ausgabe in ein (neues) Shellfenster.
Beim ersten Zugriff auf diese Variable (entweder direkt, z.B. durch den Aufruf von `(FPRINTF stdout ...)' oder indirekt, z.B. durch den Aufruf von `(PRINTF ...)') wird die Datei geöffnet. Die Datei wird nicht vor der Programmausführung geöffnet. Dies verhindert das Öffnen der Datei, wenn keine Ausgabe erzeugt wird, z.b. wenn einfach nur Berechnungen und Änderungen an einigen Datensätzen durchgeführt werden.
Wenn MUIbase die Programmausgabedatei nicht öffnen kann, dann wird die Ausführung unterbruchen und eine Fehlermeldung ausgegeben.
PRINT
wandelt einen Ausdruck in eine Zeichenkette und gibt ihn aus.
)
Wandelt den Wert von elem in eine lesbare Zeichenkette und gibt ihn
über stdout
aus. Diese Funktion ist hauptsächlich zu Prüfzwecken
vorhanden.
PRINTF
gibt eine formatierte Zeichenkette aus.
(PRINTF
format [expr ...])
Formatiert eine Zeichenkette aus der gegebenen Formatzeichenkette und seinen
Parameter und gibt sie an stdout
aus.
Die Formatierung entspricht der von SPRINTF
(siehe SPRINTF).
PRINTF
liefert die Anzahl der ausgegebenen Zeichen oder NIL bei einem
Fehler. Ist format NIL, dann wird NIL geliefert.
Beispiel: `(PRINTF "%i Tage und %i Woche" 7 1)' gibt die Zeichenkette
"7 Tage und 1 Woche" nach stdout
aus und liefert 18.
Siehe auch PRINT, FPRINTF, stdout.
FPRINTF
gibt eine formatierte Zeichenkette in eine Datei aus.
(FPRINTF
file format [expr ...])
Formatiert eine Zeichenkette aus der gegebenen Formatzeichenkette und seinen
Parameter und gibt sie in die angegebene Datei aus.
Die Formatierung entspricht der von SPRINTF
(siehe SPRINTF).
PRINTF
liefert die Anzahl der ausgegebenen Zeichen oder NIL bei einem
Fehler. Ist file NIL, dann liefert FPRINTF
dennoch die Anzahl
der potentiell geschriebenen Zeichen zurück, macht aber keine Ausgabe.
Ist format NIL, dann wird NIL geliefert.
FERROR
prüft, on ein Ein-/Ausgabefehler einer Datei aufgetreten ist.
(FERROR
file)
liefert TRUE, wenn ein Fehler bei der gegebenen Datei auftrat, anderenfalls NIL. Ist `file' NIL, wird NIL geliefert.
Siehe auch FEOF, FOPEN, FCLOSE.
FEOF
prüft auf den Endestatus einer Datei.
(FEOF
file)
Überprüft den Dateende-Indikator der gegebenen Datei und liefert TRUE, wenn er gesetzt ist, anderenfalls NIL. Ist `file' NIL, wird NIL geliefert.
Siehe auch FERROR, FTELL, FOPEN, FCLOSE.
FSEEK
setzt die Schreib-/Leseposition in einer Datei.
(FSEEK
file offset whence)
Setzt die Schreib-/Leseposition für die gegebene Datei. Die neue Position -gemessen in Bytes- wird erreicht durch das Hinzufügen von offset bytes bezogen auf die Position, die durch whence festgelegt wird. Ist whence auf SEEK_SET, SEEK_CUR oder SEEK_END gesetzt, dann ist offset relativ zum Beginn der Datei, der aktuellen Position beziehungsweise zum Ende der Datei.
Bei Erfolg liefert FSEEK
0, anderenfalls NIL und die
Dateiposition bleibt unverändert.
Ist file, offset oder whence NIL, oder ist
whence nicht eine der Konstanten SEEK_SET, SEEK_CUR oder
SEEK_END, dann wird NIL geliefert.
Siehe auch FTELL, Vordefinierte Konstanten.
FTELL
liefert die Schreib-/Leseposition der Datei.
(FTELL
file)
Ermittelt die aktuelle Schreib-/Leseposition relativ zum Anfang der gegebenen Datei und liefert sie als Ganzzahl. Tritt ein Fehler auf oder ist `file' NIL, dann wird NIL geliefert. Siehe auch FSEEK, FEOF.
FGETCHAR
liest ein Zeichen aus einer Datei.
(FGETCHAR
file)
Liefert das nächste Zeichen von der gegebenen Datei als Zeichenkette oder NIL, wenn file NIL ist, das Ende der Datei erreicht wurde oder ein Fehler auftrat. Ist das nächste Zeichen ein Nullbyte, dann wird eine leere Zeichenkette geliefert.
Siehe auch FGETCHARS, FGETSTR, FPUTCHAR.
FGETCHARS
liest Zeichen aus einer Datei.
(FGETCHARS
num file)
liefert eine Zeichenkette, die die nächsten num Zeichen aus der gegebenen Datei enthält. Ist das Ende der Datei erreicht worden, bevor num Zeichen gelesen werden konnten, oder wenn ein Nullbyte gelesen wurde, dann werden nur die bisher gelesenen Zeichen zurückgegeben. Ist num oder file NIL, num negativ, das Ende der Datei erreicht worden, bevor das erste Zeichen gelesen wurde, oder ein Lesefehler aufgetreten, dann wird NIL zurückgeliefert.
FGETSTR
liest eine Zeichenkette aus einer Datei.
(FGETSTR
file)
liefert die nächste Zeile aus der gegebenen Datei oder NIL, falls file NIL ist, das Ende der Datei erreicht wurde oder ein Fehler auftrat. Das Ende einer Zeile wird entweder durch ein Neue-Zeile-Zeichen oder durch ein Nullbyte gekennzeichnet oder falls das Ende der Datei erkannt wurde. In jedem Fall enthält die Zeichenkette keine Neue-Zeile-Zeichen.
Siehe auch FGETCHAR, FGETCHARS, FGETMEMO, FPUTSTR.
FGETMEMO
liest einen mehrzeiligen Text aus einer Datei.
(FGETMEMO
file)
liefert einen mehrzeiligen Text, der den Inhalt der gegebenen Datei bis zum nächsten Nullbyte oder zum Ende der Datei enthält. Ist file NIL, das Ende der Datei erreicht worden, bevor ein Zeichen gelesen wurde oder trat ein Fehler auf, dann wird NIL zurückgeliefert.
FPUTCHAR
schreibt ein Zeichen in eine Datei.
(FPUTCHAR
str file)
Schreibt das erste Zeichen von str in die gegebene Datei. Ist str leer, dann wird ein Nullbyte geschrieben. Sind str oder file NIL, dann passiert nichts. Liefert str oder NIL, wenn ein Ausgabefehler auftrat.
FPUTSTR
schreibt eine Zeichenkette in eine Datei.
(FPUTSTR
str file)
Gibt str zusammen mit einem Neue-Zeile-Zeichen in die gegebene Datei aus. Sind str oder file NIL, dann passiert nichts. Liefert str oder NIL, wenn ein Ausgabefehler auftrat.
Siehe auch FPUTCHAR, FPUTMEMO, FGETSTR.
FPUTMEMO
schreibt einen mehrzeiligen Text in eine Datei.
(FPUTMEMO
memo file)
Gibt memo in die gegebene Datei aus. Sind memo oder file NIL, dann passiert nichts. Liefert memo oder NIL, wenn ein Ausgabefehler auftrat.
FFLUSH
leert den Schreibpuffer in eine Datei.
(FFLUSH
file)
Schreibt den Schreibpuffer(58) der gegebenen Datei. Liefert 0 bei Erfolg, NIL bei einem Fehler. Ist file NIL, dann wird 0 zurückgegeben (kein Fehler).
Dieser Abschnitt behandelt Funktionen für Datensätze.
NEW
legt einen neuen Datensatz für eine Tabelle an.
(NEW
table init)
Legt einen neuen Datensatz für die gegebene Tabelle an. Das Argument init legt den Datensatz fest, der zum Einrichten des neuen Datensatzes verwendet werden soll. Ein Wert von NIL steht für den Vorgabedatensatz.
NEW
liefert den Datensatzzeiger für den neuen Datensatz.
Die Funktion NEW
hat zudem den Nebeneffekt, daß der
Programm-Datensatzzeiger der gegebenen Tabelle (siehe Tabellen) auf den
neuen Datensatz gesetzt wird.
Beispiel: `(NEW table NIL)' legt einen neuen Datensatz in der gegebenen Tabelle an und richtet ihn mit dem Vorgabedatensatz ein.
Siehe auch NEW*, DELETE, Tabellen.
NEW*
ist die Version von NEW
(siehe NEW) mit dem Stern.
(NEW*
table init)
NEW*
prüft, ob eine Auslösefunktion für die gegebene Tabelle
(siehe Auslösefunktion Neu(59))
definiert wurde. Ist eine vorhanden, dann wird diese
zum Anlegen des Datensatzes ausgeführt und dessen Ergebnis zurückgeliefert.
Das Argument init gibt den Datensatz an, anhand dessen der neue
Datensatz initialisiert werden soll (NIL für den Vorgabedatensatz).
Wurde keine Auslösefunktion eingerichtet, dann verhält sich die Funktion wie
NEW
.
Achtung: Mit dieser Funktion ist es möglich, Endlosschleifen zu schreiben,
wenn z.B. für eine Tabelle eine Auslösefunktion für `New' definiert
wurde und diese Funktion NEW*
aufruft, um den Datensatz anzulegen.
DELETE
löscht einen Datensatz einer Tabelle.
(DELETE
table requester)
Löscht den aktuellen Programm-Datensatz der gegebenen Tabelle, nachdem ein optionales Löschfenster bestätigt wurde. Das erste Argument definiert die Tabelle, für die der aktuelle Programm-Datensatz gelöscht werden soll und das zweite ist ein boolescher Ausdruck. Ist dieser NIL, dann wird der Datensatz stillschweigend gelöscht, anderenfalls wird der Status des Menüpunkts `Datensätze löschen bestätigen?' geprüft. Ist dieser nicht gesetzt, dann wird der Datensatz auch stillschweigend gelöscht, anderenfalls erscheint das Löschbestätigungsfenster, das bestätigt werden muß. Bricht der Benutzer die Löschfunktion ab, dann wird der Datensatz nicht gelöscht.
Der Rückgabewert der Funkion DELETE
wiederspiegelt die ausgewählte
Aktion. Liefert sie TRUE, dann ist der Datensatz gelöscht worden,
anderenfalls NIL (wenn der Benutzer die Funktion unterbrochen hat).
Beim Löschen setzt DELETE
den Programm-Datensatzzeiger
(siehe Tabellen) der gegebenen Tabelle auf NIL.
Beispiel: `(DELETE table NIL)' löscht stillschweigend den aktuellen Datensatz der gegebenen Tabelle.
Siehe auch DELETE*, DELETEALL, NEW, Tabellen.
DELETE*
ist die Version von DELETE
(siehe DELETE) mit dem
Stern.
(DELETE*
table requester)
DELETE*
prüft, ob eine Auslösefunktion für die gegebene Tabelle
(siehe Auslösefunktion Löschen(60))
definiert wurde. Ist eine vorhanden, dann wird diese
zum Löschen des Datensatzes ausgeführt und dessen Ergebnis zurückgeliefert.
Das Argument requester gibt an, ob die Auslösefunktion ein
Bestätigungsfenster öffnen soll, bevor der Datensatz gelöscht wird.
Wurde keine Auslösefunktion eingerichtet, dann verhält sich die Funktion wie
DELETE
.
Achtung: Mit dieser Funktion ist es möglich, Endlosschleifen zu schreiben,
wenn z.B. für eine Tabelle eine Auslösefunktion für `Delete' definiert
wurde und diese Funktion DELETE*
aufruft, um den Datensatz zu löschen.
Siehe auch DELETE, DELETEALL, NEW*.
DELETEALL
löscht alle Datensätze einer Tabelle.
(DELETEALL
table[*
])
Löscht alle Datensätze der gegebenen Tabelle. Wird ein Stern hinter dem Tabellennamen angehängt, dann werden nur die Datensätze gelöscht, die dem aktuellen Filter der Tabelle genügen. Es erscheint kein Sicherheitsfenster, bevor dir Datensätze gelöscht werden!
DELETEALL
liefert TRUE, wenn alle Datensätze erfolgreich gelöscht
werden konnten, anderenfalls NIL. Ist table NIL, dann wird NIL
geliefert.
Beispiel: `(DELETEALL table*)' löscht alle Datensätze in der gegebenen Tabelle, die dem Filter der Tabelle genügen.
GETMATCHFILTER
liefert den Status der Filterübereinstimmung eines
Datensatzes.
(GETMATCHFILTER
rec)
Liefert TRUE, wenn der gegebene Datensatz dem Filter seiner Tabelle entspricht, anderenfalls NIL. Ist der Filter der Tabelle momentan nicht aktiviert, dann wird TRUE geliefert. Ist rec NIL (der Vorgabedatensatz), dann wird NIL geliefert.
Siehe auch SETMATCHFILTER, GETISSORTED, GETFILTERSTR, SETFILTERSTR.
SETMATCHFILTER
setzt den Status der Filterübereinstimmung eines
Datensatzes.
(SETMATCHFILTER
rec on)
Ändert den Status der Filterübereinstimmung beim gegebenen Datensatz auf den
Wert von on.
SETMATCHFILTER
liefert den neuen Status der Filterübereinstimmung des
gegebenen Datensatzes. Der neue Status kann vom erwarteten abweichen, weil
das Setzen auf NIL nur dann wirksam ist, wenn der Filter der dazugehörigen
Tabelle aktiviert ist, anderenfalls wird TRUE geliefert.
Der Aufruf von SETMATCHFILTER
mit dem Wert NIL für rec (der
Vorgabedatensatz) liefert immer NIL.
Siehe auch GETMATCHFILTER, SETISSORTED, GETFILTERSTR, SETFILTERSTR.
GETISSORTED
liefert den Sortierstatus eines Datensatzes.
(GETISSORTED
rec)
Liefert TRUE, wenn der gegebene Datensatz nach der für die Tabelle definierten Reihenfolge sortiert ist, ansonsten NIL. Ist rec NIL, dann wird NIL geliefert.
Siehe auch SETISSORTED, GETMATCHFILTER, REORDER, GETORDERSTR, SETORDERSTR, Comparison function.
SETISSORTED
setzt den Sortierstatus eines Datensatzes.
(SETISSORTED
rec on)
Ändert den Sortierstatus des angegebenen Datensaztes auf on.
Die Funktion wird verwendet, wenn man der Meinung ist, daß der
Datensatz in der richtigen Reihenfolge steht (on = TRUE)
oder er neu sortiert werden sollte (on = NIL).
Neusortieren aller unsortierten Datensätze kann mit der
Funktion REORDER
(siehe REORDER) durchgeführt
werden.
SETISSORTED
liefert den neuen Sortierstatus des gegebenen
Datensatzes. Der Aufruf von SETISSORTED
mit dem Wert NIL
für rec (der Anfangsdatensatz) wird NIL liefern.
Für ein Beispiel, wie diese Funktion angewendet wird, siehe Comparison function.
Siehe auch GETISSORTED, SETMATCHFILTER, REORDER, GETORDERSTR, SETORDERSTR, Comparison function.
RECNUM
liefert die Datensatznummer des Datensatzes.
(RECNUM
record)
Liefert die Datensatznummer des gegebenen Datensatzes. Man beachte, daß die Nummerierung der Datensätze von z.B. der der Listen abweicht. Bei Listen, Zeicheketten und anderem beginnt die Zählung bei Null, bei den Datensätzen beginnt sie jedoch bei 1. Die Nummer 0 ist für den Vorgabedatensatz reserviert. Dies scheint mit den restlichen MUIbase-Funktionen unvereinbar zu sein, aber hier macht es wirklich Sinn, da die Datensatznummern auch in der Fensteranzeige verwendet werden.
COPYREC
kopiert Datensätze.
(COPYREC
rec source)
Kopiert den Inhalt des Datensatzes source in den Datensatz rec. Ist source NIL, dann wird rec auf die Werte des Vorgabedatensatzes gesetzt. Ist rec NIL, dann wird eine Fehlermeldung erzeugt.
COPYREC
liefert rec.
Siehe auch NEW.
Dieser Abschnitt behandelt Funktionen für Felder einer Tabelle.
ATTRNAME
liefert den Namen des Feldes.
(ATTRNAME
attr)
Liefert eine Zeichenkette mit dem Namen des angegebenen Feldes.
Siehe auch TABLENAME
MAXLEN
liefert die maximale Anzahl von Zeichen eines
Zeichenkettenfeldes.
(MAXLEN
string-attr)
Liefert die maximale Anzahl von Zeichen, die das gegebene Zeichenkettenfeld aufnehmen kann.
Siehe auch LEN.
GETLABELS
liefert alle Auswahltexte eines Auswahl- oder
Zeichenkettenfeldes.
(GETLABELS
attr)
Liefert die Auswahltexte des gegebenenen Auswahl- oder Zeichenkettenfeldes. Im Falle eines Auswahlfeldes werden die im Auswahltexteditor (siehe Typabhängige Einstellungen(61)) eingegebenen Texte zurückgegeben, Bei Zeichenkettenfeldern werden die Auswahltexte zurückgegebene, die für das Listenansicht-Popup (siehe Feldobjekteditor) eingegeben wurden.
Die Auswahltexte werden in einer einzelnen Zeichenkette zurückgegeben und werden jeweils durch ein Neue-Zeile-Zeichen getrennt.
Beispiel: Man nehme an, man hat ein Auswahlfeld mit den Auswahltexten
`Auto', `Haus' und `Öl'.
Der Aufruf von GETLABELS
mit diesem Feld liefert dann die Zeichenkette
"Auto\nHaus\nÖl".
Hinweis: Diese Rückgabezeichenkette läßt sich einfach mit MEMOTOLIST
(siehe MEMOTOLIST) in eine Liste umwandeln.
Siehe auch SETLABELS.
SETLABELS
wird verwendet, um die Auswahltexte eines
Zeichenkettenfeldes zu setzen.
(SETLABELS
attr str)
Setzt die Auswahltexte des Zeichenkettenfeldes attr auf die Auswahlfelder, die im Parameter str aufgelistet sind. Der Parameter str enthält für jeden Auswahltext eine Zeile. Die Auswahltexte ersetzen diejenigen, die in dem Listenansicht-Popup des Feldobjekteditors (siehe Feldobjekteditor) eingegeben wurden.
SETLABELS
liefert den Wert des Parameters str.
Beispiel: `(SETLABELS Table.String "Mein Haus\nist\ndein Haus")' setzt die Listenansicht-Auswahltexte des gegebenen Zeichenkettenfeldes auf sets the list-view labels of the specifies string attribute to `Mein Haus', `ist' und `dein Haus'.
Hinweis: Man kann eine Liste von Auswahltexte durch den Aufruf von LISTTOMEMO in das benötigte Zeichenkettenformat umwandeln.
Siehe auch GETLABELS.
TABLENAME
liefert den Namen einer Tabelle.
(TABLENAME
table)
Liefert eine Zeichenkette, die den Namen der angegebenen Tabelle enthält.
Siehe auch ATTRNAME
GETORDERSTR
liefert die Datensatzreihenfolge einer Tabelle.
(GETORDERSTR
table)
Verwendet die Tabelle eine Felderliste zum Sortieren, dann enthält die gelieferte Zeichenkette die Feldnamen, getrennt durch Leerzeichen. Jedes Feld hat ein `+' oder ein `-' vorangestellt, um eine auf- bzw. absteigende Sortierung anzuzeigen.
Wird die Tabelle anhand einer Vergleichsfunktion sortiert, dann wird der Name dieser Funktion geliefert.
Eine leere Zeichenkette zeigt an, daß keine Sortierung vorliegt.
Angenommen, es gibt eine Tabelle `Person', die nach ihren Feldern `Name' (aufsteigend), `Stadt' (aufsteigend) und `Geburtstag' (absteigend) sortiert ist. Dann liefert `(ORDERSTR Person)' die Zeichenkette "+Name +Stadt -Geburtstag".
Siehe auch SETORDERSTR, REORDER, REORDERALL, GETISSORTED, SETISSORTED, Sortieren, Comparison function.
SETORDERSTR
setzt die Sortierreihenfolge einer Tabelle.
(SETORDERSTR
table order)
Setzt die Sortierreihenfolge der gegebenen Tabelle auf die Felder in der Zeichenkette order. Die Zeichenkette order kann entweder eine Liste von Feldnamen enthalten oder den Namen der Vergleichsfunktion.
Zum Sortieren einer Feldliste muß die Zeichenkette order die Feldnamen für die Sortierung enthalten, die durch eine beliebige Anzahl von Leerzeichen, Tabulatoren oder Neue-Zeile-Zeichen getrennt sind. Jedem Feldnamen kann ein `+' oder ein `-' für auf- bzw. absteigende Sortierung vorangestellt werden. Wird dieses Zeichen weggelassen, dann wird aufsteigende Sortierung angenommen.
Zum Sortieren anhand einer Vergleichsfunktion muß die Zeichenkette order den Namen der Funktion tragen.
SETORDERSTR
liefert TRUE, wenn es möglich war, die neue Sortierung zu
setzen, anderenfalls NIL, wenn z.B. ein unbekanntes Feld angegeben wurde oder
das Typ des Feldes für die Sortierung nicht erlaubt ist. Wird NIL für
order angegeben, dann passiert nichts und es wird NIL zurückgeliefert.
Hinweis: Zum Erzeugen der Sortierzeichenkette sollten man nicht direkt den
Feldnamen in die Zeichenkette einfügen, weil bei einer Änderung des
Feldnamens der Name in der Zeichenkette nicht mit verändert wird. Besser ist
es, die Funktion ATTRNAME
(siehe ATTRNAME) zu verwenden und dessen
Ergebnis in die Sortierzeichenkette zu kopieren.
Man betrachte eine Tabelle `Person' mit den Feldern `Name', `Stadt' und `Geburtstag'. `(SETORDERSTR Person (SPRINTF "+%s" (ATTRNAME Person.Name)))' setzt dann die Sortierreihenfolge der Tabelle `Person' auf `Name' als (aufsteigendes) Sortierfeld.
Siehe auch GETORDERSTR, REORDER, REORDERALL, GETISSORTED, SETISSORTED, Sortieren, Comparison function.
REORDER
bringt alle unsortierten Datensätze zurück in die richtige
Reihenfolge.
(REORDER
table)
Untersucht alle Datensätze der gegebenen Tabelle nach unsortierten
Datensätzen und fügt diese in ihrer korrekten Position ein.
Nach dem Einfügen eines unsortierten Datensatzes wird der Sortierstatus
des Datensatzes auf TRUE gesetzt, so daß bei nach Beendigung der Funktion
REORDER
der Sortierstatus aller Datensätze auf TRUE steht.
REORDER
liefert NIL.
Normalerweise wird diese Funktion nur dann aufgerufen, wenn eine Vergleichsfunktion für die Sortierung der Tabelle definiert wurde. Sortierungen anhand einer Felderliste sind automatisch, das bedeutet, daß ein Datensatz automatisch sortiert wird, wenn er benötigt wird.
Für einen Anwendungsfall zur Anwendung dieser Funktion siehe Comparison function.
Siehe auch REORDERALL, GETORDERSTR, SETORDERSTR, GETISSORTED, SETISSORTED, Sortieren, Comparison function.
REORDERALL
sortiert alle Datensätze einer Tabelle neu.
(REORDERALL
table)
Sortiert alle Datensätze der gegebenen Tabelle neu, indem der Sortierstatus
aller Datensätze auf NIL gesetzt und dann REORDER
zum kompletten
Neusortieren aufgerufen wird.
REORDERALL
liefert NIL.
Siehe auch REORDER, GETORDERSTR, SETORDERSTR, GETISSORTED, SETISSORTED, Sortieren, Comparison function.
GETFILTERACTIVE
liefert den Filterstatus einer Tabelle.
(GETFILTERACTIVE
table)
Liefert TRUE, wenn der Filter gegebenen Tabelle momentan aktiviert ist, anderenfalls NIL.
Siehe auch SETFILTERACTIVE, GETFILTERSTR, GETMATCHFILTER.
SETFILTERACTIVE
setzt den Filterstatus einer Tabelle.
(SETFILTERACTIVE
table bool)
Setzt den Filterstatus der gegebenen Tabelle. Ist bool nicht NIL, dann wird er Filter aktiviert, anderenfalls deaktiviert.
SETFILTERACTIVE
liefert den neuen Status des Filters.
Der neue Status muß nicht dem erwarteten entsprechen, falls beim Aktivieren
des Filters ein Fehler auftrat und der Filter deshalb nicht aktiviert werden
konnte.
Deaktivieren des Filters gelingt jedoch immer..
Siehe auch GETFILTERACTIVE, SETFILTERSTR, SETMATCHFILTER.
GETFILTERSTR
liefert den Datensatzfilterausdruck einer Tabelle.
(GETFILTERSTR
table)
Liefert den Datensatzfilterausdruck der gegebenen Tabelle als Zeichenkette. Eine leere Zeichenkette bedeutet, daß kein Filterausdruck für diese Tabelle gesetzt wurde.
Siehe auch SETFILTERSTR, GETFILTERACTIVE, GETMATCHFILTER.
SETFILTERSTR
setzt den Datensatzfilterausdruck einer Tabelle.
(SETFILTERSTR
table filter-str)
Setzt den Datensatzfilterausdruck der gegebenen Tabelle auf den Ausdruck im Parameter filter-str(62). Ist der Filter der gegebenen Tabelle momentan aktiviert, dann wird der neue Filterausdruck sofort auf alle Datensätze angewendet und der Status der Filterübereinstimmung aller Datensätze neu berechnet.
SETFILTERSTR
liefert TRUE, wenn es möglich war, den gegebenen
Filterzeichenkettenausdruck zu kompilieren, anderenfalls wird NIL geliefert.
Man beachte, daß man nur das Ergebnis der Kompilierung erhält. Ist der Filter
der gegebenen Tabelle momentan aktiviert und das Neuberechnen aller Stati der
Filterübereinstimmungen fehlschlägt, dann wird man nicht über das Ergebnis
dieser Funktion informiert. Daher ist der empfohlene Weg, einen neuen
Filterausdruck zu setzen, folgender:
(SETFILTERACTIVE Table NIL) ; gelingt immer. (IF (NOT (SETFILTERSTR Table filter-string)) (ERROR "Kann den Filter für %s nicht setzen!" (TABLENAME Table)) ) (IF (NOT (SETFILTERACTIVE Table TRUE)) (ERROR "Kann den Filter für %s nicht aktivieren!" (TABLENAME Table)) )
Wird SETFILTERSTR
mit dem Wert NIL für den Parameter filter-str
aufgerufen, dann passiert nichts und NIL wird zurückgeliefert.
Beispiel: `(SETFILTERSTR Table "(> Wert 0.0)")'.
Siehe auch GETFILTERSTR, SETFILTERACTIVE, SETMATCHFILTER.
RECORDS
liefert die Anzahl der Datensätze in einer Tabelle.
(RECORDS
table)
Liefert die Anzahl der Datensätze in der gegebenen Tabelle. Man kann einen Stern zum Tabellennamen hinzufügen, um die Anzahl der Datensätze zu ermitteln, die dem Filter der Tabelle genügen.
RECORD
liefert einen Datensatzzeiger für eine gegebene Datensatznummer.
(RECORD
table num)
Liefert den Datensatzzeiger des num-ten Datensatzes in der gegebenen Tabelle oder NIL, wenn ein Datensatz mit dieser Nummer nicht existiert. Man kann einen Stern zum Tabellennamen hinzufügen, um den num-ten Datensatz zu erhalten, der dem Datensatzfilter genügt(63)'(64).
Es ist darauf zu achten, daß Datensatznummern bei 1 beginnen und die Datensatznummer 0 für den Vorgabedatensatz verwendet wird.
SELECT
ermittelt und liefert diverse Daten von Datensätzen.
(SELECT
[DISTINCT
] exprlistFROM
tablelist [WHERE
where-expr] [ORDER BY
orderlist])
wobei exprlist entweder ein einfacher Stern `*' oder eine Liste von durch Komma getrennten Ausdrücken mit optionalen Titeln ist:
exprlist:*
| expr"Titel",
...
und tablelist eine Liste von Tabellennamen:
tablelist: table[*
] [ident
],
...
Für jede Tabelle in der Tabellenliste kann ein Identifier(65) Dies kann nützlich sein, wenn eine Tabelle mehr als einmal in der Tabellenliste vorkommt (siehe unten das Beispiel zum Vergleichen von Altersangaben). Wird ein Stern zum Tabellennamen hinzugefügt, dann werden nur die Datensätze der Tabelle betrachtet, die dem momentanen Filter der Tabelle genügen.
Die Sortierliste hat den folgenden Aufbau:
orderlist: expr [ASC
|DESC
],
...
wobei expr, ... beliebige Ausdrücke oder Feldnummern sein können.
Zum Beispiel sortiert `(SELECT Name FROM ... ORDER BY 1)'
das Ergebnis nach dem Feld `Name'.
Man kann zudem ASC
oder DESC
für eine auf- bzw. absteigende
Sortierung angeben.
Ist keiner der beiden vorhanden, dann wird aufsteigende Sortierung
angenommen.
Die SELECT-FROM-WHERE-Abfrage bildet das (mathematische) Kreuzprodukt aller Tabellen in der Tabellenliste (es wertet alle Datensatzmengen in table, ... aus) und prüft den WHERE-Ausdruck (wenn vorhanden). Liefert der WHERE-Ausdruck TRUE (oder es gibt keinen WHERE-Ausdruck), dann wird eine Liste erzeugt, dessen Elemente anhand der Ausdrucksliste im SELECT-Teil berechnet wurden. Wurde ein einzelner Stern in der Ausdrucksliste angegeben, dann enthält die Liste die Werte aller Felder, die zu den Tabellen in der Tabellenliste gehören (hiervon ausgenommen sind die virtuellen Felder und Knöpfe).
Das Ergebnis der Abfrage ist eine Liste von Listen. Der erste Listeneintrag enthält die Titelzeichenketten, die restlichen die Werte der FROM-Liste für die passenden Datensätze.
Siehe Abfragebeispiele für einige Beispiele mit der Funktion SELECT
.
Siehe auch FOR ALL.
Dieser Abschnitt beschreibt die Funktionen zum Verändern von Benutzeroberflächenelementen.
SETCURSOR
setzt den Cursor auf ein Benutzeroberflächenelement.
(SETCURSOR
attr-or-table)
Setzt den Cursor auf das gegebene Feld oder Benutzeroberflächenelement der Tabelle. Die Funktion öffnet auch das Fenster, in dem das Feld/die Tabelle eingebettet ist, wenn das Fenster noch geschlossen ist.
SETCURSOR
liefert TRUE, wenn kein Fehler auftrat (Fenster konnte
geöffnet werden) oder NIL bei einem Fehler.
GETDISABLED
liefert den Inaktiv-Status eines Feldes.
(GETDISABLED
attr)
Liefert den Inaktiv-Status des angegebenen Feldes im aktuellen Datensatz.
Siehe auch SETDISABLED, GETWINDOWDISABLED.
SETDISABLED
setzt den Inaktiv-Status eines Feldes.
(SETDISABLED
attr bool)
Setzt den Inaktiv-Status des angegebenen Feldes im aktuellen Datensatz auf den Wert von bool. Liefert den neuen Wert des Inaktiv-Status.
Siehe auch GETDISABLED, SETWINDOWDISABLED.
GETWINDOWDISABLED
liefert den Inaktiv-Status eines Fensters.
(GETWINDOWDISABLED
attr-or-table)
Liefert den Status des Inaktiv-Flags für das Fenster, in dem das angegebene Feld oder die Tabelle eingebettet ist. Ist das Feld oder die Tabelle im Hauptfenster eingebettet, dann wird NIL geliefert(66).
Siehe auch SETWINDOWDISABLED, GETWINDOWOPEN, GETDISABLED.
SETWINDOWDISABLED
setzt den Inaktiv-Status eines Fensters.
(SETWINDOWDISABLED
attr-or-table disabled)
Setzt den Status des Inaktiv-Flags des Fensters, in dem das angegebene Feld bzw. die Tabelle eingebettet ist, auf den Wert von disabled. Wenn man ein Fenster deaktiviert, dann wird das Fenster geschlossen und der dazugehörige Fensterknopf wird deaktiviert. Das Hauptfenster eines Projekts kann nicht deaktiviert werden.
SETWINDOWDISABLED
liefert den neuen Inaktiv-Status des Fensters.
Siehe auch GETWINDOWDISABLED, SETWINDOWOPEN, SETDISABLED.
GETWINDOWOPEN
liefert den Geöffnet-Status eines Fensters.
(GETWINDOWOPEN
attr-or-table)
Liefert den Geöffnet-Status des Fensters, in dem das Feld bzw. die Tabelle eingebettet ist.
Siehe auch SETWINDOWOPEN, GETWINDOWDISABLED.
SETWINDOWOPEN
öffnet und schließt ein Fenster.
(SETWINDOWOPEN
attr-or-table open)
Öffnet oder schließt das Fenster, in dem das gegebenen Feld bzw. die gegebenen Tabelle eingebettet ist. ist open nicht NIL, dann wird das Fenster geöffnet, anderenfalls wird es geschlossen. Das Hauptfenster eines Projekts kann nicht geschlossen werden.
SETWINDOWOPEN
liefert den neuen Geöffnet-Status des Fensters.
Siehe auch GETWINDOWOPEN, SETWINDOWDISABLED.
Dieser Abschnitt listet Funktionen auf, die mit Projekten zu tun haben.
PROJECTNAME
liefert den Projektnamen.
(PROJECTNAME)
PROJECTNAME
liefert den Namen des aktuellen Projekts als
Zeichenkette oder NIL, wenn noch kein Name definiert wurde.
Siehe auch CHANGES.
CHANGES
liefert die Anzahl der bisher gemachten Änderungen am
aktuellen Projekt.
(CHANGES)
Liefert eine Ganzzahl mit der Anzahl der Änderungen seit der letzten Speicherung des aktuellen Projekts.
Siehe auch PROJECTNAME.
Dieser Abschnitt listet Funktionen auf, die auf das Betriebssystem zugreifen.
EDIT
startet den externen Editor.
(EDIT
filename)
Startet den externen Editor zum Bearbeiten der gegebenen Datei.
Der externen Editor kann unter dem Menüpunkt `Einstellungen - Externen
Editor setzen' (siehe Externer Editor) eingestellt werden. EDIT
starten den externen Editor asynchron, das bedeutet, die Funktion kehrt
sofort wieder zurück (und wartet nicht auf das Ende des Editors).
EDIT
liefert TRUE, wenn der Editor erfolgreich gestartet werden
konnte, anderenfalls NIL.
Siehe auch EDIT*, VIEW, SYSTEM.
EDIT*
ist die Version von EDIT
mit dem Stern und hat den selben
Effekt wie EDIT
(siehe EDIT).
Der einzige Unterschied ist, daß EDIT*
den externen Editor synchron
startet und wartet, bis der Benutzer den Editor verlassen hat.
Siehe auch EDIT, VIEW*, SYSTEM.
VIEW
startet den externen Anzeiger.
(VIEW
filename)
Startet den externen Anzeiger zum Anzeigen der gegebenen Datei.
Der externen Anzeiger kann unter dem Menüpunkt `Einstellungen - Externen
Anzeiger setzen' (siehe Externer Anzeiger) eingestellt werden. VIEW
starten den externen Anzeiger asynchron, das bedeutet, die Funktion kehrt
sofort wieder zurück (und wartet nicht auf das Ende des Anzeigers).
VIEW
liefert TRUE, wenn der Anzeiger erfolgreich gestartet werden
konnte, anderenfalls NIL.
Siehe auch VIEW*, EDIT, SYSTEM.
VIEW*
ist die Version von VIEW
mit dem Stern und hat den selben
Effekt wie VIEW
(siehe VIEW).
Der einzige Unterschied ist, daß VIEW*
den externen Anzeiger synchron
startet und wartet, bis der Benutzer den Anzeiger verlassen hat.
Siehe auch VIEW, EDIT*, SYSTEM.
SYSTEM
ruft ein externes Programm auf.
(SYSTEM
fmt [arg ...])
Ruft ein externes Programm auf. Die Befehlszeile zum Programmaufruf wird aus
fmt und den optionalen Parametern wie in der Funktion SPRINTF
(siehe SPRINTF) erzeugt.
SYSTEM
wartet, bis das aufgerufene Programm beendet wurde.
Wenn nicht gewünscht ist, daß SYSTEM
warten soll, dann benutzt man
eine Befehlszeile, die das Programm im Hintergrund startet.
SYSTEM
liefert bei Erfolg TRUE, anderenfalls NIL, wenn z.B. die
Befehlszeile nicht ausgeführt werden konnte oder der aufgerufene Befehl einen
Fehlercode lieferte.
Beispiel: `(SYSTEM "run %s %s" "clock" "digital")' startet die Systemuhr mit Digitalmodus als Hintergrundprozeß.
Siehe auch EDIT, EDIT*, VIEW, VIEW*.
STAT
untersucht eine Datei.
(STAT
filename)
Untersucht, ob der angegebene Dateiname im Dateisystem existiert.
STAT
liefert NIL, wenn der Dateiname nicht gefunden werden konnte; 0,
wenn der Dateiname existiert und ein Verzeichnis ist, und eine Ganzzahl größer 0,
wenn der Dateiname existiert und eine gültige Datei
ist(67)
TACKON
erzeugt einen Pfadnamen.
(TACKON
dirname filename)
Verknüpft dirname und filename zu einem Pfadnamen.
TACKON
weiß, wie es mit Doppelpunkten und Schrägstrichen
(Slashes) in dirname umzugehen hat. Es liefert den Pfadnamen
als Zeichekette oder NIL, wenn dirname oder filename NIL
ist.
Beispiel: `(TACKON "Sys:System" "CLI")' liefert "Sys:System/CLI".
FILENAME
extrahiert den Dateinamen aus einem Pfadnamen.
(FILENAME
path)
Extrahiert die letzte Komponente eines gegebenen Pfadnamens.
Es wird nicht geprüft, ob die letzte Komponente momentan auf
eine Datei verweist, so daß es auch möglich ist, FILENAME
zu verwenden, um den Namen eines Unterverzeichnisses zu erhalten.
FILENAME
liefert sein Ergebnis als Zeichenkette oder NIL,
wenn path NIL ist.
Beispiel: `(FILENAME "Sys:System/CLI")' liefert "CLI".
DIRNAME
extrahiert den Verzeichnis-Teil eines Pfadnamens.
(DIRNAME
path)
Extrahiert den Verzeichnis-Teil des gegebenen Pfadnamens.
Es wird nicht geprüft, ob path momentan auf eine Datei
verweist, so daß es auch möglich ist, DIRNAME
zu verwenden,
um den Namen eines übergeordneten Verzeichnisses zu erhalten.
DIRNAME
liefert sein Ergebnis als Zeichenkette oder NIL,
wenn path NIL ist.
Beispiel: `(DIRNAME "Sys:System/CLI")' liefert "Sys:System".
TODAY
liefert das heutige Datum.
(TODAY)
Liefert das heutige Datum als Datumswert.
Siehe auch NOW.
NOW
liefert die aktuelle Uhrzeit.
(NOW)
Liefert die aktuelle Uhrzeit als Zeitwert.
Siehe auch TODAY.
MESSAGE
gibt eine Meldung für den Benutzer aus.
(MESSAGE
fmt [arg ...])
Setzt den Fenstertitel des Pause/Abbrechen-Fensters (wenn es geöffnet ist).
Die Titelzeichenkette wird aus fmt und den optionalen Parametern wie in
der Funktion SPRINTF
(siehe SPRINTF) erzeugt.
MESSAGE
liefert die formatierte Titelzeichenkette.
Beispiel: `(MESSAGE "6 * 7 = %i" (* 6 7))'.
GC
erzwingt das Aufräumen des Speichers(68).
(GC)
Erzwingt das Aufräumen des Speichers und liefert NIL. Im Normalfall wird das Aufräumen automatisch von Zeit zu Zeit durchgeführt.
MUIbase kennt einige vordefinierte globale Variablen.
Momentan existiert nur eine einzige globale Variable: stdout
(siehe stdout).
Die folgenden vordefinierten Konstanten können in jedem Ausdruck bei der Programmierung verwendet werden:
Name Typ Wert Bemerkung -------------------------------------------------------------------------NIL
jeder NILTRUE
bool TRUERESET
Zeichenkette "\33c"NORMAL
Zeichenkette "\33[0m"ITON
Zeichenkette "\33[3m"ITOFF
Zeichenkette "\33[23m"ULON
Zeichenkette "\33[4m"ULOFF
Zeichenkette "\33[24m"BFON
Zeichenkette "\33[1m"BFOFF
Zeichenkette "\33[22m"ELITEON
Zeichenkette "\33[2w"ELITEOFF
Zeichenkette "\33[1w"CONDON
Zeichenkette "\33[4w"CONDOFF
Zeichenkette "\33[3w"WIDEON
Zeichenkette "\33[6w"WIDEOFF
Zeichenkette "\33[5w"NLQON
Zeichenkette "\33[2\"z"NLQOFF
Zeichenkette "\33[1\"z"INT_MAX
Ganzzahl 2147483647 Größter GanzzahlwertINT_MIN
Ganzzahl -2147483648 Kleinster GanzzahlwertHUGE_VAL
Fließkommazahl 1.797693e+308 Größte absolute FließkommazahlPI
Fließkommazahl 3.14159265359OSVER
Ganzzahl <OS-Version>OSREV
Ganzzahl <OS-Revision>MBVER
Ganzzahl <MUIbase-Version>MBREV
Ganzzahl <MUIbase-Revision>LANGUAGE
Zeichenkette hängt von der lokalen Sprache abSEEK_SET
Ganzzahl siehe stdio.h Suche vom Beginn der Datei.SEEK_CUR
Ganzzahl siehe stdio.h Suche von aktueller Position.SEEK_END
Ganzzahl siehe stdio.h Suche vom Ende der Datei.
Siehe Konstanten für weitere Informationen über Konstanten.
Zum Definieren eigener Konstanten benutzt man die Preprozessor-Anweisung
#define
(siehe #define).
Es ist möglich, eine Funktion als einen Parameter an eine andere Funktion zu übergeben. Dies ist nützlich für die Definition von übergeordneten Funktionen, wie z.B. zum Sortieren oder Abbilden einer Liste.
Um eine Funktion auzurufen, die als Parameter übergeben wurde, muß die
Funktion FUNCALL
(siehe FUNCALL) verwendet werden.
(DEFUN map (l fun) # Parameter: Liste und Funktion (LET (res) # lokale Variable res, vorbelegt mit NIL (DOLIST (i l) # jedes Element der Reihe nach (SETQ res (CONS (FUNCALL fun i) res) # Funktion anwenden und ) # neue Liste erzeugen ) (REVERSE res) # die Liste muß nun umgekehrt werden ) )
Jetzt kann diese Abbildefunktion zum Beispiel verwendet werden, um alle Elemente einer Liste mit Ganzzahlen um 1 zu erhöhen:
`(map (LIST 1 2 3 4) 1+)' liefert ( 2 3 4 5 ).
Es ist möglich, den Typ einer lokalen Variable durch Anfügen eines Typdeklarierers hinter dem Namen festzulegen. Die folgenden Typdeklarierer existieren:
Deklarierer Beschreibung :INT für Ganzzahlen :REAL für Fließkommazahlen :STR für Zeichenketten :MEMO für mehrzeilige Zeichenketten :DATE für Datumswerte :TIME für Zeitwerte :LIST für Listen :FILE für Dateihandler :FUNC für Funktionen jedes Typs :table für Datensatzzeiger auf table
Der Typdeklarierer wird an den Variablennamen wie im folgenden Beispiel angehängt:
(LET (x:INT (y:REAL 0.0) z) ...)
Das Beispiel definiert drei neue Variablen `x', `y' und `z', wobei `x' vom Typ Ganzzahl ist und mit NIL vorbelegt wird, `y' vom Typ Fließkommazahl ist und mit 0.0 vorbelegt wird, und `z' eine Variable ohne Typ ist, die mit NIL vorbelegt wird.
Der Vorteil von Typspezifizierern ist, daß der Compiler mehr Typfehler entdecken kann, z.B. wenn eine Funktion
(DEFUN foo (x:INT) ...)
definiert ist und sie mit `(foo "bar")' aufgerufen wird, dann erzeugt der Compiler eine Fehlermeldung. Wird `foo' jedoch mit einem Wert ohne Typ aufgerufen, z.B. `(foo (FIRST list))', dann kann keine Fehlerprüfung durchgeführt werden, da zum Zeitpunkt des Kompilierens der Typ von `(FIRST list)' nicht bekannt ist.
Aus Geschwindigkeitsgründen wird beim Programmlauf keine Typüberprüfung durchgeführt. Es könnte eingebaut werden, aber dies würde eine kleine Verlangsamung bewirken, die nicht wirklich notwendig ist, da ein falscher Typ früher oder später in einem Typfehler endet.
Typdeklarierer für Datensatzzeiger haben eine andere nützliche Eigenschaft. Wird eine Variable als Datensatzzeiger auf eine Tabelle belegt, dann kann auf alle Felder dieser Tabelle mit dem Variablennamen statt des Tabellennamens im Feldpfad zugegriffen werden. Hat man z.B. eine Tabelle `Foo' mit einem Feld `Bar' und man definiert eine Variable `foo' als
(LET (foo:Foo)
dann kann man das Feld `Bar' des dritten Datensatzes mit
(SETQ foo (RECORD Foo 3)) (PRINT foo.Bar)
ausgeben.
Zu beachten ist in Select-from-where Ausdrücken, daß die Variablen in der FROM-Liste automatisch vom Typ des Datensatzzeigers des zugeordneten Tabelle sind.
Der Aufbau von Ausdrücken ist von sehr großer Bedeutung, um zu verstehen, was ein Programm tut.
Dieser Abschnitt bescheibt die Semantik, abhängig vom Aufbau der Ausdrücke:
(
func [expr ...])
AND
, OR
und IF
.
Diese Funktionen müssen nicht zwingend alle Ausdrücke errechnen.
Mehr zu nicht-strikten Funktionen, siehe Lisp-Aufbau, AND, OR,
and IF.
(
[expr ...])
()
wird zu NIL.
LET
(siehe LET) definiert werden.
Zum automatischen Ausführen von MUIbase-Programmen können Auslösefunktionen für Projekte, Tabellen und Felder festgelegt werden, wie in bestimmten Fällen aufgerufen werden. Dieser Abschnitt bescheibt alle vorhandenen Auslösemöglichkeiten.
Nach dem Öffnen eines Projekts durchsucht MUIbase das Programm des Projekts
nach einer Funktion mit dem Namen onOpen
.
Existiert eine solche Funktion, dann wird diese ohne Parameter aufgerufen.
(DEFUN onOpen () (ASKBUTTON NIL "Danke für das Öffnen!" NIL NIL) )
Siehe auch onClose, onChange, Beispielprojekt `Trigger.mb'.
Bevor ein Projekt geschlossen wird, durchsucht MUIbase das Programm des
Projekts nach einer Funktion mit dem Namen onClose
.
Existiert eine solche Funktion, dann wird diese ohne Parameter aufgerufen.
In der jetzigen Version wird der Rückgabewert der Funktion ignoriert und das
Projekt unabhängig vom Rückgabewert geschlossen.
Wurden in der Funktion onClose
Änderungen am Projekt durchgeführt,
dann fragt MUIbase nach, ob das Projekt zuerst gespeichert werden soll, bevor
das Projekt geschlossen wird. Wird der Menüpunkt `Projekt - Speichern &
Schließen' zum Schließen des Projekts aufgerufen, dann wird die
Auslösefunktion aufgerufen, bevor das Projekt gespeichert wird, so daß die
Änderungen automatisch gespeichert werden.
(DEFUN onClose () (ASKBUTTON NIL "Auf Wiedersehen!" NIL NIL) )
Siehe auch onOpen, onChange, Beispielprojekt `Trigger.mb'.
Wann immer der Benutzer eine Änderung am Projekt durchführt oder nach dem
Speichern eines Projekts, durchsucht MUIbase das Programm des Projekts nach
einer Funktion mit dem Namen onChange
.
Existiert eine solche Funktion, dann wird diese ohne Parameter aufgerufen.
Dies kann verwendet werden, um die Anzahl der Änderungen zu erfassen, die ein
Benutzer an diesem Projekt durchgeführt hat.
(DEFUN onChange () (SETQ Control.NumChanges (CHANGES)) )
Im obigen Beispiel könnte `Control.NumChanges' ein virtuelles Feld sein, das in einer `Nur-ein-Datensatz'-Tabelle zum Anzeigen der Anzahl von Projektänderungen verwendet wird.
Siehe auch onOpen, onClose, Beispielprojekt `Trigger.mb'.
Sobald der Benutzer einen neuen Datensatz durch Auswählen der Menüpunkte `Neuer Datensatz' oder `Datensatz kopieren' anlegen möchte und die Auslösefunktion `Neu' für diese Tabelle auf eine MUIbase-Funktion gesetzt wurde, dann wird diese Auslösefunktion ausgeführt. Die Auslösefunktion für `Neu' kann im Tabellenfenster (siehe Tabellen erstellen) gesetzt werden.
Die Auslösefunktion erhält NIL oder einen Datensatzzeiger als ersten und
einzigen Parameter. NIL bedeutet, daß der Benutzer einen neuen Datensatz
anlegen möchte und ein Datensatzzeiger zeigt an, daß der Benutzer einen
Datensatz eine Kopie dieses Datensatzes anlegen will. Hat die Auslösefunktion
mehr als einen Parameter, dann werden diese mit NIL vorbelegt. Die
Auslösefunktion sollte nun einen neuen Datensatz mit NEW
(siehe NEW)
anlegen. Der Rückgabewert der Auslösefunktion wird ausgewertet. Ist er ein
Datensatzzeiger, dann wird dieser Datensatz angezeigt.
Die Auslösefunktion `Neu' wird auch aufgerufen, wenn ein
MUIbase-Programm die Funktion NEW*
(siehe NEW*) aufruft.
(DEFUN newRecord (init) (PROG1 ; zum Rückgeben des Ergebnisses von NEW (NEW Table init) ... ) )
Siehe auch NEW*, Auslösefunktion Löschen.
Sobald der Benutzer einen Datensatz durch Auswählen des Menüpunkts `Datensatz löschen' löschen möchte und die Auslösefunktion `Löschen' für diese Tabelle auf eine MUIbase-Funktion gesetzt wurde, dann wird diese Auslösefunktion ausgeführt. Die Auslösefunktion für `Löschen' kann im Tabellenfenster (siehe Tabellen erstellen) gesetzt werden.
Die Auslösefunktion erhält einen booleschen Parameter als einzigen Parameter.
Ist er nicht NIL, dann sollte die Funktion nachfragen, ob der Benutzer
wirklich diesen Datensatz löschen möchte. Wenn er es möchte, dann sollte die
Funktion DELETE
(siehe DELETE) zum Löschen des Datensatzes aufrufen.
Die Auslösefunktion `Delete' wird auch aufgerufen, wenn ein
MUIbase-Programm die Funktion DELETE*
(siehe DELETE*) aufruft..
(DEFUN deleteRecord (requester) (DELETE Table requester) )
Siehe auch DELETE*, Auslösefunktion Neu.
Um eine Sortierung von Datensätzen einer Tabelle zu definieren, kann eine Vergleichsfunktion verwendet werden, die zwei Datensatzzeiger als Argumente erhält und eine Ganzzahl zurückliefert, die das Sortierverhältnis der beiden Datensätze anzeigt. Die Vergleichsfunktion sollte einen Wert kleiner 0 liefern, wenn ihr erstes Argument kleiner ist als das zweite; 0, wenn sie gleich sind und einen Wert größer 0, wenn das erste Argument größer ist als das zweite.
Angenommen, man hat eine Tabelle `Persons' mit dem Zeichenkettenfeld `Name', dann könnte man folgende Funktion zum Vergleich zweier Datensätze verwenden:
(DEFUN cmpPersons (rec1:Persons rec2:Persons) (CMP rec1.Name rec2.Name) )
Dies wird alle Datensätze bezüglich dem Feld `Name' sortieren, wobei Zeichengrößen unterschieden werden. Anzumerken ist, daß Sortieren anhand einer Felderliste nicht das gleiche Ergebnis liefert, da der Zeichenkettenvergleich zeichengrößenunabhängig durchgeführt wird.
Mit einer Vergleichsfunktion lassen sich sehr komplexe Sortierungen definieren. Man achte jedoch darauf, keine rekursiven Funktionsaufrufe zu erzeugen, die sich selbst aufrufen. MUIbase wird seine Programmausführung anhalten und dies mit einer Fehlermeldung quittieren, sollte so etwas versucht werden. Auch sollten keine Befehle verwendet werden, die Seiteneffekte erzeugen könnten, wie z.B. einen Wert einem Feld zuweisen.
Wird eine Vergleichsfunktion verwendet, dann weiß MUIbase nicht immer, wann es die Datensätze neu zu sortieren hat. Nehmen wir im obigen Beispiel zusätzlich an, daß es die Tabelle `Toys' mit dem Zeichenkettenfeld `Name' und das Beziehungsfeld `Owner' gibt, das auf `Persons' verweist. Zudem nehmen wir folgende Vergleichsfunktion an:
(DEFUN cmpToys (rec1:Toys rec2:Toys) (CMP* rec1.Owner rec2.Owner) )
Diese Funktion verwendet die Sortierung von `Persons', um die Sortierung der Datensätze festzustellen, so daß die Datensätze von `Toys' analog der Sortierung von `Persons' sortiert sind.
Ändert nun der Benutzer einen Datensatz in der Tabelle `Persons' und dieser Datensatz erhält eine neue Position, dann müßten auch Datensätze in `Toys' neu sortiert werden, die auf diesen Datensatz verweisen. MUIbase kennt jedoch diese Abhängigkeit nicht.
Neben der Verwendung des Menüpunktes `Tabelle - Alle Datensätze neu sortieren' auf die Tabelle `Toys' zum Neusortieren kann auch ein automatisches Neusortieren implementiert werden, indem folgende Auslösefunktion für das Feld `Name' der Tabelle `Persons' festgelegt wird:
(DEFUN setName (newValue) (SETQ Persons.Name newValue) (FOR ALL Toys WHERE (= Toys.Owner Persons) DO (SETISSORTED Toys NIL) ) (REORDER Toys) )
Diese Funktion löscht die Sortierzustände aller Datensätze, die auf den aktuellen Datensatz der Tabelle `Persons' verweisen und sortiert anschließend alle unsortierten Datensätze der Tabelle `Toys'.
Siehe auch Sortieren, GETISSORTED, SETISSORTED, REORDER, REORDERALL, GETORDERSTR, SETORDERSTR, Demo `Order.mb'.
Im Feldfenster (siehe Felder erstellen) kann eine Auslösefunktion definiert werden, die immer dann aufgerufen wird, denn der Benutzer den Inhalt des Feldes ändern möchte.
Wurde eine solche Auslösefunktion definiert und der Benutzer ändert den Wert
dieses Feldes, dann wird der Datensatzinhalt nicht automatisch auf den neuen
Wert gesetzt. Stattdessen wird der Wert als erster Parameter an die
Auslösefunktion übergeben. Die Auslösefunktion kann nun den Wert überprüfen
und ihn ablehnen. Um den Wert im Datensatz zu speichern, muß die Funktion
SETQ
verwendet werden.
Die Auslösefunktion sollte das Ergebnis des SETQ
-Aufrufs
(siehe SETQ) oder den alten Wert des Feldes, wenn sie den neuen Wert
abzulehnt, zurückgeben.
Die Auslösefunktion wird auch ausgeführt, wenn ein MUIbase-Programm die
Funktion SETQ*
(siehe SETQ*) zum Setzen eines Feldwertes
aufruft.
(DEFUN setAmount (amount) (IF some-expression (SETQ Table.Amount amount) (ASKBUTTON NIL "Ungültiger Wert!" NIL NIL) ) Table.Amount ; liefert momentanen Wert zurück )
Siehe auch SETQ*
In MUIbase sind virtuelle Felder besondere Felder, die ihren Inhalt nebenbei berechnen, wenn er benötigt wird. Wird z.B. zu einem anderen Datensatz gewechselt, indem man auf einen der Pfeile in der Panelleiste einer Tabelle klickt und ein virtuelles Feld in dieser Tabelle das Flag `Sofort' (siehe Feldobjekteditor) gesetzt hat, dann wird der Wert dieses Feldes berechnet und dargestellt. Zum Berechnen des Wertes wird die Auslösefunktion `Berechne' des Feldes aufgerufen. Diese Auslösefunktion kann im Feldfenster (siehe Typabhängige Einstellungen (69)). festgelegt werden. Der Rückgabewert dieser Funktion definiert den Wert des virtuellen Feldes. Wurde keine `Berechne'-Auslösefunktion für ein virtuelles Feld festgelegt, dann ist der Wert des Feldes NIL.
Man kann auch die Berechnung eines virtuellen Feldes auslösen, indem man einfach in einem MUIbase-Programm darauf zugreift, so daß man z.B. auf Knopfdruck zum Berechnen des Wertes eines virtuellen Feldes wie im folgenden nur eine Funktion für den Knopf festlegen muß:
(DEFUN buttonHook () virtual-attr )
Man kann auch den virtuellen Wert auf jeden Wert setzen, indem man die
Funktion SETQ
verwendet:
(SETQ virtual-attr expr)
Wird jedoch nach dem SETQ
-Aufruf auf das virtuelle Feld zugegriffen,
dann wird der Wert des virtuellen Feldes neu berechnet.
Der Wert eines virtuellen Feldes wird nicht zwischengespeichert, da nicht einfach festzustellen ist, wann der Wert neu berechnet werden muß und wann nicht. Daher sollte man auf virtuelle Felder möglichst sparsam zugreifen und den Wert in lokalen Variablen für die weitere Verwendung selbst zwischenspeichern.
Für ein Beispiel, wie virtuelle Felder benutzt werden, sehe man sich das Beispielprojekt `Movie.mb' an.
Siehe auch virtuelles Feld, Beispielprojekt `Movie.db'.
Go to the first, previous, next, last section, table of contents.