Tips und Techniken für die AS/400
Endlich ist sie da, unsere lang ersehnte jährliche Ausgabe mit Tips und Techniken! In diesem Abschnitt haben wir fünfzig der besten Tips, Tricks und Techniken für die AS/400 zusammengestellt. Einige davon stammen von Anwendern wie Ihnen, andere von den technischen Redakteuren von NEWS/400. Das Ergebnis ist eine prall gefüllte Kiste mit unverzichtbaren Tips, Tricks und Techniken. Überzeugen Sie sich selbst, wie Sie sich mit diesen erstaunlichen AS/400-Tips Ihre tägliche Arbeit erleichtern können.Dieser Abschnitt enthält Tips zur RPG- und CL-Programmierung, Informationen zu ILE und SQL, Nützliches zu Datums- und Zeitoperationen, Ratschläge für die Systemverwaltung und vieles mehr. Wenn Ihnen das noch nicht reichen sollte, finden Sie weitere interessante und nützliche Tips, z.B. 25 Tips zur Netzwerkanbindung und Client/Server-Programmierung in NEWS/400 Februar 98, Seite 42, Fortsetzung in der April-Ausgabe von NEWS/400.. Wem auch das noch nicht genug ist, der findet weitere Tips unter: http://www.news.400.com Nach der Lektüre dieser Tips werden nicht nur Sie selbst beeindruckt sein, sondern auch Ihre Freunde und Kollegen werden staunen. Entscheidend ist jedoch, daß die Tricks Ihnen helfen, das Beste aus Ihrer AS/400 herauszuholen. Und das Erfolgsrezept heißt: NEWS/400:
Auswertung logischer Ausdrücke
Vereinfachte Datendefinitionen
Vermeiden von Array-Indexfehlern
Zusammensetzen von Programmen mit Teildatei-Kopien
RPG IV und der Gleitkomma-Datentyp
Schnellere Array- und Stringbearbeitung
Verwenden von leeren logischen Anweisungen
Arrays vs. Datenstruktur mit Mehrfachvorkommen
Konvertieren von RPG III-Code zu RPG IV mit Code/400
RPG
Auswertung logischer Ausdrücke
RPG IV erlaubt Ihnen, logische Ausdrücke für alle Operationen zu kodieren, die den erweiterten Faktor 2 unterstützen. Viele von Ihnen werden bereits mit der Kodierung der logischen Ausdrücke für If-, DoW-, DoU- und When-Operationen vertraut sein. Sie können jedoch auch logische Ausdrücke für Eval- und Return-Operationen kodieren. Durch logische Ausdrücke läßt sich der Code erheblich vereinfachen. Die folgenden Beispiele sollen das verdeutlichen. Eine Prozedur ruft ein API auf, das die standardmäßige API-Fehlerdatenstruktur zurückgibt. Wenn der Aufruf an das API keinen Fehler aufweist, gibt die Prozedur *On zurück. Falls das API mit einem Fehlerzustand endet, gibt die Prozedur *Off zurück. Anstatt der Langversion:
können Sie auch die folgende Kurzform eingeben:
Beide Codepassagen führen zu einem absolut identischen Ergebnis. Die Kurzfassung ist jedoch wesentlich kompakter. Sehen wir uns die Kurzfassung einmal genauer an. Zunächst wertet das Programm den in der Klammer stehenden logischen Ausdruck aus. Wenn ErDtaLen gleich 0 ist, ist der Ausdruck wahr, und das Ergebnis ist *On. Wenn ErDtaLen nicht gleich 0 ist, ist der Ausdruck falsch, und das Ergebnis ist *Off. Anschließend gibt das Programm als Ergebnis des Ausdrucks *On oder *Off an die aufrufende Prozedur zurück. Nachdem ich die Grundidee aufgezeigt habe, können wir uns nun einem etwas komplexeren Beispiel zuwenden. Stellen Sie sich eine Anzeige vor, in der Sie ein Element in einer Datei erstellen, ändern oder löschen können. Die DDS für die Anzeige definiert einen Titel für jeden Vorgang, und die Ausgabe wird durch Bedingungsindikatoren gesteuert:
Die folgenden C-Spezifikationen bestimmen die Bedingungsindikatoren:
Für die Option Create (Erstellen) ist *In01 auf Ein (On) gesetzt. *In02 und *In03 sind auf Aus (Off) gesetzt, und der Titel „Create Item“ wird eingeblendet. Wenn Sie sich etwas in die hier behandelte Logik vertiefen, werden Sie feststellen, daß sich die Programmlogik ebenso auf die Optionen Change (Ändern) und Delete (Löschen) anwenden läßt.
Vereinfachte Datendefinitionen
Sie können die Definition der Variablen in Ihren Programmen vereinfachen, indem Sie sie wie andere Variablen definieren. Definitionen mit „Like“ (Wie) verbessern die Lesbarkeit und Wartungsfähigkeit Ihrer Programme. Verwenden Sie das Schlüsselwort Like in den D-Spezifikationen, wenn Sie eine Variable wie eine andere definieren möchten. Sie können die „Like“-Definitionen einsetzen, um Kopien von extern beschriebenen Dateien zu halten und Variablen von Standardtypen zu erstellen. Erstellen Sie eine Variable, die eine Kopie eines Feldes aus einer extern beschriebenen Datei hält (die in einem Programm benutzt wird), indem Sie die Variable wie das Feld definieren. Das folgende Beispiel zeigt das Erstellen einer Variable, um eine Kopie von Feld ItmNbr in der Datei ItmMst zu speichern, die in einem Programm verwendet wird. Geben Sie den folgenden Code ein:
- D SavItmNbr Like ( ItmNbr )
Sie können Variablen von Standardtypen erstellen, indem Sie die in Abbildung 1 aufgeführte Teildatei-Kopie StdTypH verwenden. StdTypH definiert Standarddatentypen, die in beliebigen Programmen verwendet werden können. StdIdx definiert einen Index-Datentyp für ein beliebiges Array, und StdNam definiert einen Datentyp für OS/400-Namen, z.B. Namen von Objekten und Teildateien. Um eine Variable von einem Standardtyp zu erstellen, müssen Sie zunächst eine Copy-Anweisung für die Teildatei StdTypH in den D-Spezifikationen des Programms kodieren. Definieren Sie anschließend die Variable wie einen der Standardtypen in StdTypH. Wenn Sie beispielsweise ein Objektnamen-Array mit einem Array-Index erstellen möchten, geben Sie folgendes ein:
- /Copy SrcFile,StdTypH D ObjNamAry Like( StdNam ) D Dim( 999 ) D ObjNamIdx Like( StdIdx )
Vermeiden von Array-Indexfehlern
Mit etwas Sorgfalt können Sie Array-Indexfehler in Ihren RPG IV-Programmen vermeiden. Dabei sind die D-Spezifikationen von entscheidender Bedeutung. Achten Sie darauf, bei jeder Definition eines Arrays auch einen Index zu definieren, der groß genug für den Verweis auf jedes Element in dem Array ist. Außerdem müssen Sie eine benannte Konstante definieren, mit der die Gesamtgröße des Arrays definiert wird. Bei der Definition eines Objektnamen-Arrays kann der Code wie in diesem Beispiel aussehen:
- /Copy SrcFile,StdTypH D ObjNamAry Like(StdNam) D Dim(999 ) D ObjNamIdx Like(StdIdx ) D ObjNamSiz C %Elem(ObjNamAry)
Das Array ObjNamAry enthält 999 Elemente. ObjNamIdx bezeichnet den Index für das Array und ist definiert wie StdIdx, das groß genug ist, um einen Index für ein Array von beliebiger Größe zu speichern. (Das Array und der Index wurden mit Standarddatentypen definiert, wie sie im vorherigen Abschnitt „Vereinfachte Datendefinitionen“ beschrieben wurden.) ObjNamSiz definiert die Array-Größe mit Hilfe der eingebauten %Elem-Funktion. Wenn Sie die Größe von ObjNamAry ändern wollen, müssen Sie nur das Dim-Schlüsselwort ändern – ObjNamIdx verweist weiter auf jedes Element in dem Array, und ObjNamSiz definiert die neue Array-Größe. Die C-Spezifikationen des Programms sollten beim Überprüfen des Wertes für ObjNamIdx immer ObjNamSiz verwenden, um Array-Indexfehler zu vermeiden. Gehen Sie dabei folgendermaßen vor:
- C Eval ObjNamIdx = ObjNamIdx + 1 C If ObjNamIdx > Ø And C ObjNamIdx = ObjNamSiz C Eval ObjNamAry( ObjNamIdx ) C =ObjNam C EndIf
Zusammensetzen von Programmen mit Teildatei-Kopien
Teildatei-Kopien sind bei der Modularisierung von Code auf der Source-Ebene praktisch. Mit Hilfe der Teildatei-Kopien können Sie standardmäßige Datendefinitionen zur Verfügung stellen. Außerdem lassen sich mit Teildatei-Kopien die Prototypen und die erforderlichen Definitionen für die Prozeduren in Ihren Service-Programmen definieren. Diese Tips enthalten Beispiele für beide Arten von Teildatei-Kopien. Das Beispiel unter „Vereinfachte Datendefinitionen“ (s.o.) zeigt, wie mit der Teildatei-Kopie StdTypH (Abbildung 1) Standarddatentypen definiert werden, die in beliebigen Programmen verwendet werden können. V3R7 RPG IV unterstützt verschachtelte Teildatei-Kopien, d.h. Teildatei-Kopien, die wiederum Kopier-Anweisungen für andere Teildatei-Kopien enthalten.
Dies kann unter Umständen dazu führen, daß mehrere Kopien derselben Teildatei-Kopie expandiert werden, während das Programm kompiliert wird. Wenn dieser Fall eintritt, wird das Programm aufgrund unzulässiger Datendefinitionsduplikate beendet. Schützen Sie sich vor bösen Überraschungen bei der Arbeit mit Teildatei-Kopien, indem Sie die folgenden einfachen Regeln beachten: Erstens: Kodieren Sie für jede in einer Quellenteildatei erforderliche Teildatei-Kopie eine Kopier-Anweisung. Zweitens: Starten Sie jede der Teildatei-Kopien mit einer bedingten Komplierungsanweisung, um sicherzustellen, daß die Teildatei während der Kompilierung nur einmal expandiert wird. Ein einfaches Beispiel soll die Funktionsweise dieser beiden Regeln verdeutlichen. Programm A verwendet die Teildatei-Kopien StdTypH und CmdH. Die Teildatei-Kopie CmdH verwendet außerdem die Teildatei-Kopie StdTypH. Daraus ergibt sich folgende Baumstruktur für die Kopier-Anweisung in Programm A:
- /Copy StdTypH /Copy CmdH /Copy StdTypH
Um eine fehlerfreie Kompilierung sicherzustellen, beginnt jede Teildatei-Kopie mit der folgenden bedingten Kompilierungsanweisung:
- /If Not Defined( MemberCopied) /Define MemberCopied /Else /Eof /EndIf
Geben Sie in dem oben geschriebenen Code statt dem Wort Member in MemberCopies den Namen der Teildatei-Kopie ein, für die bei der Kompilierung die Bedingung gelten soll. Die bedingten Kompilierungsanweisungen für die Teildatei StdTypH lauten:
- /If Not Defined( StdTypHCopied) /Define StdTypHCopied /Else /Eof /EndIf
Beim ersten Kopieren der Teildatei wird das Makro MemberCopied definiert, und der Rest der Teildatei wird expandiert. Bei nachfolgenden Kopien stellt der Compiler fest, daß MemberCopied bereits definiert wurde. Dadurch wird für die Teildatei-Kopie das Dateiende erzwungen und eine weitere Expandierung verhindert. Die expandierte Quelle enthält weiterhin nur eine Kopie des ausführbaren Code in der Teildatei-Kopie.
RPG IV und der Gleitkomma-Datentyp
Seit V3R7 unterstützt RPG IV auch den Gleitkomma-Datentyp, so daß Sie die CEE Math APIs von ILE (Intergrated Language Environment) in RPG IV-Programmen nutzen können. Mit dem Programm in Abbildung 2 wird das API CEERANO (Basic Random Number Generation) aufgerufen, das mathematisch gebunden werden kann. Anhand des Beispiels werden die Einsatzmöglichkeiten dieses Datentyps aufgezeigt. Der Eingabeparameter C0Seed hat einen gültigen Bereich von 0 bis 2.147.483.646. Wenn der Wert 0 ist, generiert das API einen Anfangswert aus der aktuellen GMT-Zeit des Systems. Bei der Rückgabe ändert CEERAN0 den Wert, so daß er als neuer Anfangswert in einem nachfolgenden Aufruf verwendet werden kann. Der Ausgabeparameter C0RndNbr ist eine doppelte 64-Bit-Gleitkommazahl mit einem Wert zwischen 0 und 1. Wenn ein ungültiger Anfangswert verwendet wird, wird –1 zurückgegeben. Die Programmlogik basiert auf dem minimalen und maximalen Wert für die Zufallszahlgeneration. Die Werte werden in den D-Spezifikationen initialisiert. Das Programm verwendet die eingebaute %DecH-Funktion, um die Gleitkomma-Zufallszahl in eine gepackte Dezimalzahl mit einer Länge von 30 Ziffern und 29 Dezimalpositionen umzuwandeln. Anschließend wird dieser Wert mit dem maximalen Wert multipliziert. Da 1 die größtmögliche Zufallszahl ist, kann das Ergebnis nie höher als der maximale Wert sein. Durch die Do-Schleife des Programms wird sichergestellt, daß die Zufallszahlgeneration wiederholt wird, bis das Ergebnis größer oder gleich dem minimalen Wert ist.
Schnellere Array- und Stringbearbeitung
Sie können die Array- und Stringbearbeitung beschleunigen, indem Sie Array-Indizes und Variablen, in denen die Position und die Länge der Strings gespeichert sind, immer als ganzzahlige Werte definieren. Der RPG IV-Compiler wurde so optimiert, daß die Integer-Werte unter Verwendung des Integer-Datentyps verarbeitet werden. Durch den Integer-Datentyp läßt sich die Leistung von Programmen mit vielen Array- und Stringbearbeitungen deutlich verbessern. Verwenden Sie bei der Definition von ganzen Zahlen den Datentyp I mit einer Länge von entweder 5 oder 10, und geben Sie Null für Dezimalstellen ein:
- D StdIdx S 1ØIØ D StdInt S 1ØIØ
Verwenden von leeren logischen Anweisungen
Eine leere logische Anweisung (auch Null-Logik-Anweisung genannt) ist eine logische Operation ohne zugeordnete Aktion.
- C If Error = *On C* Exsr DoNothing C Else C Exsr DoSomething C EndIf
Leere logische Anweisungen gelten oft als schlechte Angewohnheit. Lehrbücher für Programmierer stellen diese Anweisungen oft auf eine Stufe mit Goto-Anweisungen, und betonen immer wieder, daß leere logische Anweisungen auf jeden Fall vermieden werden sollten. Gezielt eingesetzt, kann eine leere logische Anweisung jedoch durchaus sinnvoll sein. Wenn der oben beschriebene Abschnitt mit der Absicht geschrieben wurde, Platz für die spätere Hinzufügung von Code zu schaffen (etwa um auf Fehler zu reagieren), dann ist die Verwendung der leeren logischen Anweisung durchaus sinnvoll. Mit leeren logischen Anweisungen läßt sich auch eine komplexe Logik vereinfachen, und sie sind besonders bei Select-Anweisungen sinnvoll. Ein Bearbeitungsprogramm kann unter Umständen die Dateneingabe vom Bildschirm neu formatieren, und anschließend eine Option ausführen, falls die Daten keine Fehler enthalten. Anhand der komplexen Select-Logik (Abbildung 3B) wird dieser Ablauf erläutert. Es wird jede Option getestet und auf einen Anzeigefehler hin untersucht. Die vereinfachte Select-Logik (Abbildung 3B) verwendet eine leere logische Anweisung, um eventuelle Anzeigefehler zu überprüfen und testet dann jede Option. Die vereinfachte Logik ist kürzer und leichter zu lesen als die komplexe. Da die Überprüfung der Anzeigefehler nur an einer Stelle durchgeführt wird, ist die Instandhaltung der einfachen Logik wesentlich leichter.
Arrays vs. Datenstruktur mit Mehrfachvorkommen
Beim Speichern eines Arrays mit Datensätzen werden Sie sicher erst einmal an die Verwendung einer Datenstruktur mit Mehrfachvorkommen denken. Die Occur-Operation nimmt jedoch sehr viel Zeit in Anspruch, und wenn die Performance entscheidend ist, werden Sie wesentlich höhere Geschwindigkeiten erzielen, wenn Sie mit Arrays arbeiten. Die Verwendung von Arrays zur Imitation einer Datenstruktur mit Mehrfachvorkommen ist ein einfacher Vorgang. Das folgende Beispiel verdeutlicht das:
- D ObjDs Ds D ObjNam Like( StdNam ) D ObjLib Like( StdNam ) D ObjTxt Like( StdTxt ) D ObjAry S Like( ObjDs ) D DIM( 999 ) D ObjIdx Like( StdIdx )
Definieren Sie den Datensatz zunächst als eine Datenstruktur. In diesem Beispiel definiert ObjDs eine Datenstruktur, die den Namen, die Bibliothek und den Text eines Objektes enthält. Definieren Sie dann das Array wie die Datenstruktur. Das Array ObjAry hält 999 Elemente, von denen jedes der Datenstruktur ObjDs entspricht. Sie können auf die Datensätze in dem Array zugreifen, indem Sie einen Index verwenden und das relevante Array-Element in die Datenstruktur verschieben:
- C Eval ObjIdx = 1 C Eval ObjDs = ObjAry( ObjIdx)
Ausrichten der Zeichen in RPG IV Wenn Sie mit V3R7 oder höher arbeiten, können Sie den Wert eines Zeichenfeldes in einer einzelnen RPG-Anweisung rechts ausrichten, indem Sie die eingebauten Funktionen verwenden. Abbildung 4A zeigt, wie diese Technik die richtige Anzahl von Leerzeichen mit dem Original-Feldwert verkettet, um einen rechts ausgerichteten Wert auszugeben. Mit nur wenigen Änderungen am Code können Sie den Feldwert nach demselben Prinzip zentrierern. Abbildung 4B zeigt die entsprechende Anweisung.
Konvertieren von RPG III-Code zu RPG IV mit Code/400
Wenn Sie an einer RPG IV-Teildatei arbeiten und sich Code aus einer RPG III-Quelle „ausleihen“ müssen, können Sie mit CODE/400 für Windows 95 die alte Teildatei problemlos über einen einfachen Menübefehl in RPG IV umwandeln. Sie haben die Möglichkeit, entweder einen vollständigen Abschnitt oder nur einen Teil des Code zu konvertieren. Wählen Sie „Convert RPG Source“ (RPG-Quelle konvertieren) im Actions-Menü einer Bearbeitungssitzung der RGG III-Quellenteildatei, wenn Sie den ganzen Abschnitt konvertieren möchten. Konvertieren Sie einen Teil des Code, indem Sie den entsprechenden Teil mit der Maus auswählen und anschließend den Befehl „Convert Selection“ (Auswahl konvertieren) im Actions-Menü auswählen. Kopieren Sie den neu konvertierten RPG IV-Code, und fügen Sie ihn in das Programm ein.
Fortsetzung im Zweiten Teil.
Mit freundlichen Grüßen
- Ihr Burgy Zapp
![Künstler Burgy Zapp [http://burgyzapp.de]](http://newsolutions.de/it/wp-content/uploads//re2_k1_Image-54_Z_Negativ-300x300.jpg)


