#limit (11.0)##pagelength (16.5)##block# #start (2.0,0.0)# #page (151)# #headodd# #center#EUDAS#right#% #end# #headeven# %#center#EUDAS #end# #center#1 14 Ausdrücke in ELAN 14.1 Was sind Ausdrücke ? In diesem Kapitel wollen wir uns mit ELAN-Ausdrücken beschäfti­ gen, wie sie für EUDAS gebraucht werden. Natürlich kann dies keine ernsthafte Einführung für ELAN-Programmierer sein - mit solchen Ambitionen halten Sie sich am besten an die entsprechende ELAN- Literatur. Dieser Text richtet sich eher an den Benutzer, der kaum Erfah­ rung mit ELAN hat, aber die Möglichkeiten von EUDAS optimal nut­ zen will. Viele fortgeschrittene Fähigkeiten von EUDAS laufen ja über ELAN-Programme. #on("b")#Vorkommen#off("b")# Sie haben ELAN-Ausdrücke bereits an verschiedenen Stellen eingesetzt, wenn Sie sich mit den vorhergehenden Kapiteln befaßt haben. ELAN-Ausdrücke werden in nahezu allen Verarbei­ tungsfunktionen benötigt. Im Druckmuster dienen sie dazu, den Inhalt eines Feldmusters festzulegen. Die Definition einer Abkürzung besteht immer aus dem Namen der Abkürzung und einem Ausdruck. Ebenso wird in einer Gruppendefinition ein Ausdruck angegeben. Beim Kopiermuster und beim Änderungsmuster besteht jeweils die rechte Seite einer Anweisung aus einem Ausdruck. Weiterhin werden Ausdrücke auch in anderen ELAN-Konstruktionen benötigt, wie zum Beispiel direkt am Anfang einer IF-Anweisung. #on("b")#Bedeutung#off("b")# Ein Ausdruck steht allgemein für einen Wert. Im ein­ fachsten Fall kann dies eine Konstante sein, der Wert des Aus­ drucks ändert sich also nicht. Anderenfalls spricht man von einem zusammengesetzten Ausdruck. Dessen Wert ergibt sich dann durch die Ausführung der im Ausdruck angegebenen Operationen. Dieser Wert kann je nach dem aktuellen Zustand des Systems verschieden sein, da er jedes Mal neu berechnet wird, wenn er gebraucht wird. Ein Beispiel für einen zusammengesetzten Ausdruck ist 2+2 Dieser Ausdruck steht für den Wert 4. Der Wert eines Ausdrucks ist das, was uns eigentlich interes­ siert. Beim Druckvorgang wird dieser Wert dann gedruckt, beim Kopieren und Verändern in ein Feld eingetragen. #on("b")#Zusammensetzung#off("b")# Ausdrücke lassen sich aus verschiedenen Ele­ menten zusammensetzen. Grundlage bilden die Konstanten. Konstan­ ten können durch #on("i")#Operatoren#off("i")# miteinander verknüpft werden. So ist in dem Ausdruck 2+3 das '+' ein Operator, der die Konstanten 2 und 3 verknüpft. Das Ergebnis der Verknüpfung hängt natürlich vom jeweiligen Operator ab. Wie Sie schon in der Schule gelernt haben ("Punktrechnung vor Strichrechnung"), muß man die Reihenfolge der Operatoren festlegen, wenn mehrere Operatoren im Spiel sind. Ähnliche Regeln gibt es für alle Operatoren in ELAN. Wenn eine andere Reihenfolge der Operatoren erwünscht ist, können Sie diese durch Einsatz von Klammern verändern. Auch dies dürfte Ihnen aus der Schule noch in Erinnerung sein. Der Unter­ schied in ELAN ist lediglich, daß es dort einige zusätzliche Opera­ toren gibt, die Ihnen nicht aus der Mathematik vertraut sind. Ein weiteres Konstruktionselement von Ausdrücken sind #on("i")#Funk­ tionen#off("i")#. Auch diese kennen Sie aus der Schule. Lediglich die Schreibweise muß für den "dummen" Computer etwas ausführlicher gehalten werden (Beispiel: sin (3.14 * x)). Die Argumente der Funktion hinter dem Funktionsnamen müssen auf jeden Fall in Klammern stehen. In der Terminologie der Pro­ grammiersprachen spricht man von #on("i")#Parametern#off("i")#. Parameter können wieder komplexe Ausdrücke sein. Bei Funktionen mit mehreren Parametern werden diese durch Komma getrennt: min (2.5 * x, x + 1.25) 14.2 Datentypen Bevor wir beginnen, konkrete Ausdrücke zu behandeln, müssen wir erst das Konzept der #on("i")#Datentypen#off("i")# einführen. Grundidee dabei ist, daß es verschiedene Klassen von Werten gibt, die nicht einfach untereinander gemischt werden können. So gibt es in ELAN einen grundlegenden Unterschied zwischen #on("i")#Zahlen#off("i")# und #on("i")#Texten#off("i")#. Texte bestehen aus einer beliebigen Aneinan­ derreihung von Zeichen, die im Normalfall nur für den betrachten­ den Menschen eine Bedeutung haben. Mit Zahlen kann man dagegen Berechnungen anstellen. Der tiefere Grund für die Trennung in verschiedene Typen ist also, daß für jeden Typ gewisse Operationen definiert snd, die nur für diesen Typ sinnvoll sind. So ist zum Beispiel die Addition der beiden Texte "abc" und "-/-" völlig sinnlos. Aber nicht nur die Operationen sind verschieden, sondern auch die interne Darstellung im Rechner. So werden der Text "1234" und die Zahl 1234 völlig anders gespeichert, obwohl man ihnen die glei­ che Bedeutung beimessen könnte. #on("b")#Grundtypen#off("b")# In ELAN gibt es vier verschiedene Grundtypen, die für uns wichtig sind. Sie können sich in ELAN auch eigene Typen schaffen, dies geht jedoch weit über unsere Bedürfnisse hinaus. Der in EUDAS am meisten verwendete Typ heißt #on("i")#TEXT#off("i")#. TEXT- Objekte bestehen aus einer Folge von 0 bis 32000 Zeichen. Die Zei­ chen entstammen einem Satz von 256 verschiedenen Symbolen, die jeweils eine andere Darstellung haben. Einige der Zeichen lassen sich überhaupt nicht darstellen, sondern führen bestimmte Funktio­ nen aus (zum Beispiel Bildschirm löschen). Sämtliche Feldinhalte einer EUDAS-Datei sind TEXTe, ebenso die Zeilen von Textdateien. Auch Datei- und Feldnamen sind TEXTe. Von daher besteht eigentlich kein Grund, warum Sie sich außer zur Programmierung noch mit anderen Datentypen beschäfti­ gen sollten. Neben den Texten gibt es noch die Zahlen. Diese sind in ihrer internen Darstellung so beschaffen, daß ein effizientes Rechnen mit ihnen möglich ist. Andererseits können sie nicht mehr beliebige Informationen darstellen, sondern haben eine sehr eingeschränkte Bedeutung. Um unterschiedichen Bedürfnissen gerecht zu werden, gibt es in ELAN zwei verschiedene Zahltypen. Der Typ #on("i")#INT#off("i")# umfaßt nur ganze Zahlen ohne Kommastellen. Damit die Zahl möglichst wenig Spei­ cherplatz belegt, ist der Wertebereich bei den meisten Rechnern auf -32768..32767 beschränkt (die krummen Zahlen ergeben sich wegen der Binärarithmetik des Rechners). Dieser Typ eignet sich am besten zum Abzählen und zum Auswählen aus einer festen Anzahl von Objekten (zum Beispiel Feld 1 bis Feld 255). Zum eigentlichen Rechnen gibt es den Typ #on("i")#REAL#off("i")#. Dieser umfaßt auch Kommazahlen. Genauigkeit, Wertebereich und Darstellung sind nahezu identisch mit den Möglichkeiten eines Taschenrechners. der Typ REAL wird immer dann verwendet, wenn mit realen Größen (Geldbeträge, physikalische Werte) gerechnet werden muß. Zuletzt gibt es noch den Typ #on("i")#BOOL#off("i")#. Er hat nur zwei mögliche Werte, nämlich TRUE (wahr) und FALSE (falsch). Er wird dazu benö­ tigt, Ausdrücke zu schreiben, die den Zweig einer IF-Anweisung bestimmen. #on("b")#Denotation#off("b")# ELAN verfügt über einen strengen Typenschutz; das heißt, Objekte verschiedenen Typs dürfen nicht gemischt werden. Daher muß schon bei der Schreibweise der Konstanten festgelegt sein, welchen Typ die Konstante hat. Bei Texten geschieht dies durch den Einschluß in Anführungs­ striche. Die Anführungsstriche sorgen gleichzeitig auch für eine Abgrenzung der Zeichen des Textes und des umgebenden Programms. Sie kennen diese Schreibweise bereits von vielen Stellen in EUDAS. Ebenfalls keine Probleme bereitet der Typ BOOL, da die Schreibweise der beiden möglichen Werte TRUE und FALSE eindeutig ist. Problematisch wird es bei den Zahlen. Da die ganzen Zahlen in den rationalen Zahlen enthalten sind, muß für die ganzen Zahlen durch die Schreibweise festgelegt werden, zu welchem der beiden Typen sie gehören. Man hat festgelegt, daß REAL-Zahlen immer mit Komma geschrieben werden müssen, während Zahlen ohne Komma den Typ INT haben (das Komma wird in ELAN bei den REAL-Zahlen in internationaler Schreibweise als Punkt notiert). So ist 4 eine INT-Zahl, während 4.0 den Typ REAL besitzt. Denken Sie in Zukunft immer daran, welcher Zahltyp jeweils ver­ langt wird und richten Sie die Schreibweise danach. #on("b")#Unterschied zu Feldtypen#off("b")# Verwechseln Sie die hier vorgestellten Datentypen nicht mit den Feldtypen einer EUDAS-Datei. Die Feld­ typen beziehen sich immer auf den gleichen Datentyp, nämlich TEXT. Die Feldtypen bestimmen lediglich die spezielle Behandlung des Feldes beim Suchen und Sortieren, während Datentypen tat­ sächlich Unterschiede in der Speicherung und den anwendbaren Operationen bedeuten. Daher können Sie Feldtypen auch nach Bedarf ändern, während der Datentyp eines Objekts ein für alle Mal feststeht. Merken Sie sich, daß Feldinhalte in EUDAS immer den Typ TEXT haben. #on("b")#Umwandlungen#off("b")# Obwohl verschiedene Datentypen nicht miteinander gemischt werden dürfen, können sie mit speziellen Funktionen in­ einander umgewandelt werden. So ist zum Beispiel die Addition von 1 und 1.5 verboten, aber der folgende Ausdruck real (1) + 1.5 liefert den Wert 2.5 mit dem Typ REAL. Umgekehrt geht die Um­ wandlung mit der Funktion 'int', dabei werden jedoch die Nachkom­ mastellen abgeschnitten. Weitere Hinweise dazu erhalten Sie im Abschnitt 14.4. Wichtiger jedoch ist die Umwandlung von Zahlen in TEXT-Ob­ jekte. Was Sie auf Ihrem Bildschirm oder Ausdruck sehen, sind ja immer nur Zeichenfolgen und damit Texte. Zahlen (INT oder REAL) in ihrer internen Darstellung können Sie prinzipiell nicht sehen. Sie müssen zur Darstellung immer in Texte umgewandelt werden. Auch beim Rechnen mit Werten aus EUDAS-Dateien müssen mehrere Umwandlungen stattfinden. Der Feldinhalt, der ja ein TEXT ist, muß zunächst in eine Zahl umgewandelt werden. Dann wird mit dieser Zahl gerechnet. Wenn das Ergebnis wieder in ein Feld einge­ tragen oder gedruckt werden soll, muß eine Rückumwandlung in einen Text vorgenommen werden. Die zum Umwandeln benötigten Funktionen werden ebenfalls im Abschnitt 14.4 besprochen. #on("b")#Funktionsbeschreibung#off("b")# In den zwei folgenden Abschnitten sollen die wichtigsten Funktionen und Operatoren anhand von Beispielen beschrieben werden. Da jede Funktion nur auf bestimmte Datentypen angewendet werden kann, gibt es eine Notation, die genau die Form eines Funktionsaufrufs festlegt. INT PROC min (INT CONST a, b) Die obige Schreibweise hat folgende Bedeutung: Spezifiziert wird die Funktion 'min', die als Ergebnis einen INT-Wert liefert (das INT ganz links). Die Bezeichnung PROC gibt an, daß es sich um eine Funktion handelt. In Klammern ist dann angegeben, welche Parame­ ter verwendet werden müssen. Die Funktion hat zwei Parameter, beide vom Typ INT. Die Bezeichnung CONST gibt an, daß auch Kon­ stanten verwendet werden dürfen (Normalfall). Zu beachten ist, daß bei jedem Aufruf beide Parameter vorhan­ den und vom Typ INT sein müssen. Anderenfalls gibt es eine Feh­ lermeldung. Die gleiche Schreibweise wird auch zur Spezifikation von Ope­ ratoren verwendet: INT OP + (INT CONST a, b) Jedoch dürfen Operatoren nicht mit Parametern in Klammern ge­ schrieben werden, sondern der Operator wird zwischen die Parameter geschrieben. Eine Besonderheit von ELAN ist es, daß es verschiedene Opera­ toren und Funktionen mit gleichem Namen geben kann. Die Funktio­ nen werden nur unterschieden nach dem Typ ihrer Parameter. So gibt es nicht nur den oben genannten Operator '+', sondern auch den folgenden: REAL OP + (REAL CONST a, b) Obwohl im Aussehen gleich, handelt es sich doch um verschiedene Operatoren mit möglicherweise völlig verschiedener Wirkung. Dies sieht man an diesem Beispiel: TEXT OP + (TEXT CONST a, b) Dieser Operator führt nun keine Addition aus, sondern eine #on("i")#Verket­ tung#off("i")# zweier Texte. Je nach Typ der Parameter wird der entspre­ chende Operator ausgesucht. 14.3 TEXT-Funktionen In diesem Abschnitt wollen wir die wichtigsten Funktionen und Operatoren zur Behandlung von Texten beschreiben. Wie Sie noch sehen werden, spielt dabei aber auch der Typ INT eine gewisse Rolle. #on("b")#EUDAS-Abfragen#off("b")# Die wichtigste Funktion zur Abfrage von Inhal­ ten der aktuellen Datei sollten Sie bereits kennen: TEXT PROC f (TEXT CONST feldname) Neu ist eigentlich nur die Schreibweise der Spezifikation. Sie sollten aber in der Lage sein, daraus einen konkreten Ausdruck zu kon­ struieren. Bisher haben wir immer die Schreibweise f ("Feldname") verwendet. Dies ist jedoch nur ein Beispiel. Die korrekte Angabe finden Sie oben. Die Funktion 'f' darf natürlich nicht angewendet werden, wenn keine Datei geöffnet ist. In die Verlegenheit kommen Sie aber nur beim Ausprobieren, denn alle gefährlichen EUDAS-Funktionen sind sonst gesperrt. Falls das angegebene Feld nicht existiert, wird mit einer Feh­ lermeldung abgebrochen. Beachten Sie, daß dies immer erst bei der Ausführung festgestellt werden kann. Bei der Eingabe, zum Beispiel eines Druckmusters, kann dies noch nicht überprüft werden. Eine weitere Abfrage, die EUDAS während des Druckens ermög­ licht, ist die Funktion TEXT PROC lfd nr Diese hat keine Parameter und liefert die laufende Nummer des gedruckten Satzes. Diese beiden Funktionen können als Ausgangsbasis dienen zur Manipulation mit weiteren Funktionen. #on("b")#Verkettung#off("b")# Zur Verkettung von Teiltexten gibt es den oben schon beschriebenen Operator '+'. Wenn Sie mehr als zwei Texte verketten wollen, können Sie den Operator beliebig hintereinander verwenden: f ("PLZ") + " " + f ("Ort") Wie in diesem Beispiel können Sie sowohl Konstanten als auch Tex­ te, die von anderen Funktionen geliefert werden, verketten. Beach­ ten Sie, daß die Texte immer ohne Zwischenraum aneinandergehängt werden; daher wird im obigen Beispiel ein Leerzeichen extra ange­ geben. Wenn Sie eine bestimmte Anzahl von gleichen Zeichen haben möchten (zum Beispiel für horizontale Linien oder große Zwischen­ räume), können Sie dafür folgenden Operator verwenden: TEXT OP * (INT CONST anzahl, TEXT CONST einzeltext) Hier sehen Sie als Beispiel einen Operator, der mit verschiedenen Datentypen arbeitet. Sie müssen die Parameter jedoch immer in der angegebenen Reihenfolge benutzen. Das folgende Beispiel ist kor­ rekt: 20 * "-" während dies nicht erlaubt ist: "-" * 20 Wieder können Sie diesen Operator mit anderen Funktionen verknü­ pfen: "!" + 10 * " " + "!" + 5 * "-" + "!" Da der Multiplikationsoperator Vorrang vor der Addition hat, kom­ men Sie hier sogar ohne Klammern aus (überlegen Sie sich, wo ein Fehler auftreten würde, wenn dies nicht so wäre). Als Ergebnis dieses komplexen Ausdrucks ergäbe sich der folgende Text: "! !-----!" #on("b")#Teiltexte#off("b")# Um auch Teile von Texten bearbeiten zu können, werden die Zeichen eines Textes von 1 an (mit INT-Zahlen) durchnumeriert. Anhand dieser Positionen können Sie Teiltexte extrahieren. Damit Sie die Position des letztes Zeichens (und damit die An­ zahl der Zeichen) erfragen können, gibt es die Funktion INT PROC length (TEXT CONST text) Wieviel Zeichen in einem Feld stehen, können Sie also mit length (f ("Feldname")) erfahren. Einen Teiltext bekommen Sie mit der Funktion 'subtext'. Diese gibt es in zwei Ausführungen. TEXT PROC subtext (TEXT CONST text, INT CONST anfang) liefert den Teiltext von einer bestimmten Position an (einschließ­ lich) bis zum Textende. Mit TEXT PROC subtext (TEXT CONST t, INT CONST anf, ende) können Sie auch die Position des letzten Zeichens (einschließlich) angeben. Daher würden die beiden folgenden Aufrufe subtext (f ("Feldname"), 1) subtext (f ("Feldname"), 1, length (f ("Feldname"))) den Feldinhalt unverändert liefern. Ein weiteres Beispiel: subtext ("Ein Text als Beispiel", 5, 8) liefert als Ergebnis "Text". Es gibt noch den Operator 'SUB', der jeweils nur ein Zeichen aus dem Text liefert: TEXT OP SUB (TEXT CONST text, INT CONST stelle) Der Aufruf ist gleichwertig zu einem Aufruf von 'subtext', in dem beide Stellen gleich sind. Bei beiden Funktionen wird nicht vorhandener Text einfach ignoriert. So liefert subtext ("Hallo", 4, 8) das Ergebnis "lo" und "Hallo" SUB 10 den leeren Text "". #on("b")#Verschachtelte Ausdrücke#off("b")# Wie Sie bereits gesehen haben, kann man Ausdrücke ineinander verschachteln. Dies ist in unserem Fall sehr nützlich, wenn Teiltexte bestimmt werden sollen, deren Posi­ tion nicht konstant ist. Ein Beispiel, in dem 'length' bei der Fest­ legung der Endposition verwendet wird, haben Sie weiter oben bereits gesehen. Als weitere Möglichkeit können Sie mit Positionen, die ja INT- Zahlen sind, ganz normal rechnen. Folgender Ausdruck liefert zum Beispiel die letzten drei Zeichen eines Feldes: subtext (f ("Feldname"), length (f ("Feldname")) - 2) Wichtig ist, daß ein Ausdruck, der wieder als Parameter für einen anderen Ausdruck verwendet werden soll, den richtigen Typ hat, der von dem anderen Ausdruck verlangt wird. In dem obigen Beispiel muß als Position ein INT verwendet werden. Diese Position wird vom Operator '-' berechnet. Es gibt aber nur einen Subtraktionsoperator, der einen INT liefert, nämlich den, der wiederum zwei INTs subtrahiert. Glücklicherweise sind sowohl 'length' als auch die 2 vom Typ INT, anderenfalls wäre der Ausdruck fehlerhaft. 'length' wiederum benötigt einen TEXT als Parameter, der von der Funktion 'f' stammt, die als Parameter eben­ falls einen TEXT verlangt. Wie Sie sehen, kann es durchaus verwickelt zugehen, wenn ein Ausdruck aus den verschiedensten Teilausdrücken unterschiedlichen Typs zusammengesetzt ist. Die gleiche Überprüfung wie eben ge­ schildert sollten Sie bei jedem Ausdruck vornehmen, damit keine Fehlermeldung erscheint. #on("b")#Variable Positionen#off("b")# Zur Berechnung von Positionen gibt es noch eine weitere nützliche Prozedur, nämlich INT PROC pos (TEXT CONST text, teiltext) Sie liefert die Position, an der der angegebene Teiltext zum ersten Mal in dem Text vorkommt, oder 0, wenn der Teiltext nicht darin vorkommt. So ist pos ("Hallo", "l") = 3 und pos ("Hallo", "lo") = 4 und pos ("Hallo", "xx") = 0 Diese Funktion kann zum Beispiel dazu verwendet werden, ein Feld in mehrere Teile aufzuspalten. Sind zum Beispiel Name und Vorname in einem Feld durch Leerzeichen getrennt hintereinandergeschrie­ ben, liefert subtext (f ("Name"), 1, pos (f ("Name"), " ") - 1) den Vornamen und entsprechend subtext (f ("Name"), pos (f ("Name"), " ") + 1) den Nachnamen. Soll die Position erst ab einer gewissen Stelle ge­ sucht werden, gibt es noch die folgende Variation der Funktion: INT PROC pos (TEXT CONST text, teiltext, INT CONST ab) Bei dieser Funktion wird erst ab der angegebenen Stelle einschließ­ lich gesucht. 14.4 Rechenfunktionen #on("b")#Umwandlungen#off("b")# Bevor mit dem Inhalt eines Feldes gerechnet wer­ den kann (auch wenn das Feld den Feldtyp ZAHL hat), muß der Wert des Feldinhaltes als REAL-Zahl berechnet werden. Dazu gibt es die Funktion REAL PROC wert (TEXT CONST feldname) Die Funktion 'wert' ignoriert alle Sonderzeichen in dem Feld außer dem Minuszeichen (als Vorzeichen) und dem eingestellten Dezimal­ komma. Wenn das Feld 'Summe' beispielsweise "-***20,09 DM" ent­ hält, ergibt sich wert ("Summe") = 20.09 Zum kaufmännischen Rechnen ist es manchmal erforderlich, den Wert auf eine bestimmte Anzahl von Nachkommastellen zu runden. Diese Anzahl kann man bei einer Variante von 'wert' als Parameter ange­ ben: REAL PROC wert (TEXT CONST feldname, INT CONST kommastellen) Mit den so erhaltenen Werten können Sie dann die weiter unten beschriebenen Berechnungen durchführen. Bevor Sie das Ergebnis jedoch drucken oder in ein Feld eintragen können, müssen Sie den REAL-Wert wieder in einen TEXT verwandeln. Dazu dient die Funk­ tion TEXT PROC zahltext (REAL CONST wert, INT CONST kommastellen) Der übergebene Wert wird mit der gewünschten Anzahl von Komma­ stellen als Text formatiert. Dazu wird der Wert gerundet. Außerdem wird statt eines Punktes das eingestellte Dezimalkomma eingesetzt. Die Länge des Textes richtet sich nach der Anzahl von benötigten Stellen, es werden also keine führenden Nullen oder Leerzeichen eingesetzt (dafür kann man den Text beim Drucken ja rechtsbündig einsetzen). Wird 0 als Kommastellen angegeben, wird auch kein Dezimal­ komma erzeugt (Darstellung wie ein INT). Als Abkürzung können Sie auch TEXT PROC zahltext (TEXT CONST feldname, INT CONST kommastellen) als Ersatz für zahltext (wert ("Feldname"), kommastellen) verwenden. So kann ein Feld einheitlich zum Drucken formatiert werden. #on("b")#Arithmetik#off("b")# Sowohl mit INT- als auch mit REAL-Zahlen (jedoch nicht gemischt) können Sie die üblichen Rechenoperatoren '+', '-' und '*' verwenden. Auch Minimum ('min') und Maximum ('max') sind für zwei Parameter dieser Typen definiert. Lediglich die Division wird bei beiden Typen unterschiedlich gehandhabt. Für REAL-Zahlen gibt es den Operator '/' für die übliche Division. Da die ganzzahlige Division eine andere Bedeutung hat, wird dafür der Operator 'DIV' verwendet. Den Rest der ganz­ zahligen Division liefert 'MOD'. 'abs' liefert den Wert eines REAL oder INT ohne das Vorzeichen. Die Umwandlungsfunktionen 'int' und 'real' hatten wir ja bereits weiter oben erwähnt. Für REAL-Zahlen gibt es noch weitere mathematische Funktio­ nen (Exponentialfunktion, Trigonometrie), die Sie am besten im EUMEL-Benutzerhandbuch nachschlagen, wenn Bedarf dafür besteht. 14.5 Abfragen #on("b")#IF-Abfragen#off("b")# Wie Sie schon im vorigen Kapitel gesehen haben, kann man in Druckmustern auch IF-Abfragen als Ausdrücke ver­ wenden. Die IF-Abfragen können zwar auch ineinander verschach­ telt werden, sie dürfen jedoch nicht mehr innerhalb eines normalen Ausdrucks angewendet werden. Eine IF-Abfrage enthält 3 Teilausdrücke in folgender Form: IF 'BOOL-Ausdruck' THEN 'Ausdruck1' ELSE 'Ausdruck2' END IF Der erste Ausdruck muß einen Wert vom Typ BOOL liefern, der ent­ scheidet, welcher der beiden Teilausdrücke ausgewertet wird. Wir werden gleich noch sehen, was für Möglichkeiten es da gibt. Die beiden Teilausdrücke dürfen auch wieder IF-Abfragen sein, sind sie es jedoch nicht, dürfen in ihnen dann keine IF-Abfragen mehr vorkommen. Die IF-Abfragen liegen also immer auf der äußer­ sten Ebene. Die beiden Teilausdrücke dürfen einen beliebigen Typ haben, er muß jedoch für beide gleich sein. Als Ergebnis der IF-Abfrage wird 'Ausdruck1' geliefert, wenn der BOOL-Ausdruck wahr ist, sonst 'Ausdruck2'. #on("b")#Vergleiche#off("b")# Die wesentlichen Operationen, die boolesche Ausdrücke zur Verwendung in IF-Abfragen bilden, sind die Vergleichsoperato­ ren: = <> <= >= < > Sie vergleichen jeweils zwei Elemente vom Typ TEXT, INT oder REAL und liefern TRUE (wahr) oder FALSE (falsch). Selbstverständlich können auch sie zwei zusammengesetzte Teilausdrücke vergleichen. Eine Anwendung ist zum Beispiel der Test, ob ein Text in einem anderen enthalten ist: IF pos (f ("Betrag"), "DM") > 0 THEN "deutsches Geld" ELSE "ausländisches Geld" END IF Die Funktion 'pos' wird hier dazu benutzt, festzustellen, ob es sich um deutsches oder ausländisches Geld handelt. Oft müssen jedoch mehrere Vergleiche miteinander kombiniert werden. Zu diesem Zweck gibt es die beiden Operatoren AND (und) und OR (oder). Damit AND das Ergebnis TRUE liefert, müssen beide Vergleiche wahr sein, bei OR muß mindestens einer der beiden wahl sein. Die Reihenfolge aller dieser Operatoren ist so gewählt, daß normalerweise keine Klammern benötigt werden. Funktionen haben immer Vorrang vor Operatoren, bei den Operatoren kommt die Multi­ plikation vor der Addition, dann kommen die Vergleiche, danach das AND und danach das OR. Alle anderen Operatoren (#on("i")#insbesondere SUB#off("i")#) teilen sich den letzten Rang. Wenn Sie also in einem Ausdruck mehrere Vergleiche mit AND und OR verknüpfen, und das OR soll stärker binden als das AND, müssen Sie dies durch Klammern ausdrücken. Den oben besprochenen Operator SUB sollten Sie immer in Klammern setzen, wenn Sie ihn in einem Vergleich benutzen. Da er die niedrigste Priorität hat, gäbe es sonst mit Sicherheit Fehler: IF (f ("Name") SUB 1) = "M" THEN "vielleicht Müller" ELSE "bestimmt nicht" END IF #on("b")#Refinements#off("b")# Bisher hatten wir gesagt, daß IF-Abfragen nicht innerhalb von anderen Ausdrücken verwendet werden dürfen. Diese Einschränkung kann man umgehen, indem man #on("i")#Refinements#off("i")# verwen­ det. Ein Refinement hat im Druckmuster eine ähnliche Wirkung wie eine Abkürzung, lediglich der Name darf nur mit Kleinbuchstaben und Ziffern geschrieben sein und kann nicht als Feldmuster ver­ wendet werden. &abk : subtext (f ("Name"), namensanfang) . namensanfang : IF pos (f ("Name"), " ") > 0 THEN pos (f ("Name"), " ") + 1 ELSE length (f ("Name")) END IF . Innerhalb von Refinements dürfen auch wieder andere Refinements verwendet werden. Auch in Kopier- und Änderungsmustern können Sie Refinements verwenden. Hier müssen Sie jedoch darauf achten, daß alle Refine­ ments am Ende gesammelt werden und vor dem ersten Refinement ein Punkt stehen muß. Ebenso müssen die Refinements wie im Druckmuster durch Punkte voneinander getrennt sein: "Anrede" K anrede; . anrede : IF f ("m/w") = "w" THEN "Frau" ELSE "Herr" END IF .