von Scott Klement
Wussten Sie, dass es möglich ist, den Namen einer Datenstruktur in RPG erst während der Ausführungszeit festzulegen? Dies geschieht durch Angabe einer Variablen als Datenstrukturnamen. Die Definition erfolgt im Schlüsselwort DTAARA durch Spezifikation des Sonderwertes *VAR.
RPG bietet grundsätzlich zwei Möglichkeiten, um eine Datenstruktur zu lesen. Einerseits besteht die alte Möglichkeit über eine externe Datenstruktur (UDS), andererseits die Nutzung der Operationscodes IN und OUT. Der Grund, warum ich dies besonders erwähne, ist die Tatsache, dass ich immer wieder auf Menschen treffe, die diese beiden Methoden durcheinanderbringen. Vielfach wird die Ansicht vertreten, dass die Datenstruktur mittels UDS erstellt werden muss und für den eigentlichen Zugriff die Operationscodes IN und OUT erforderlich sind. Wenn auch der gemischte Gebrauch in RPG zulässig ist, hilft uns das in unserem speziellen Fall (Festlegung des Datenstrukturnamens zur Ausführungszeit) nicht weiter, da der Name bereits bekannt sein muss, wenn UDS die Datenstruktur zu Beginn des Programms liest. Daraus wiederum folgt, dass die Angabe des Datenstrukturnamens nicht erst in den C-Spezifikationen festgelegt werden kann.
Mittels UDS definierte Datenstrukturen müssen Zeichen-Datenstrukturen (*CHAR) sein. Sie werden automatisch zu Programmbeginn gelesen und bei Beendigung des Programms automatisch fortgeschrieben. Hier ein Definitionsbeispiel:
D MyDtaAra UDS D Lastdate 10A |
Startet das Programm, das diesen Code enthält, wird die Datenstruktur namens MyDtaAra automatisch eingelesen. Es muss eine Zeichen-Datenstruktur von zehn Byte Länge sein. Das Feld Lastdate kann im Programm geändert werden und wird bei Ende des Programms automatisch auf die Platte zurückgeschrieben.
Soll die Datenstruktur im Programm einen anderen Namen haben als auf der Platte, kann das Schlüsselwort DTAATA (siehe Abbildung 1) verwendet werden.
D MyDtaAra UDS DTAARA(OTHERNAME)
D lastdate 10A
|
Abbildung 1: Spezifizieren eines abweichenden Datenstrukturnamens
Diese Methode birgt allerdings diverse Nachteile:
- Da die Datenstruktur automatisch bei Programmstart gelesen wird, muss ihr Name bereits zu diesem Zeitpunkt bekannt sein und kann nicht erst in den C-Spezifikationen festgelegt werden.
- Datenstrukturen sind Zeichenfelder (*CHAR), so dass der Datenbereich immer als Zeichenfeld definiert sein muss.
- Da RPG die Datenstruktur zum Update öffnet, wird bei Programmstart ein Lock platziert, das anderen Programmen den Zugriff verwehrt. Hat ein anderes Programm diese Datenstruktur bereits im Zugriff und mit einem Lock belegt, muss das aktuell startende Programm warten, bis die Datenstruktur von dem anderen Programm wieder freigegeben wird.
Die neuere (obwohl eigentlich auch schon alte) Unterstützung für Datenstrukturen erlaubt es, im Programm ein Feld oder eine Datenstruktur zu definieren, die (wie in Abbildung 2 zu sehen) mit dem Operationscode IN gelesen und mit dem Operationscode OUT zurückgeschrieben wird.
D MyDtaAra DS DTAARA(OTHERNAME)
D lastdate 10A
/free
IN *LOCK MyDtaAra;
lastdate = '12/13/2014';
OUT MyDtaAra;
/end-free
|
Abbildung 2: Lesen und Schreiben von Datenstrukturen mit OP-Codes IN und OUT
In diesem Beispiel wird die Datenstruktur OTHERNAME nicht automatisch bei Programmbeginn gelesen, da in Spalte 23 der D-Spezifikationen kein U angegeben wurde. Stattdessen wird sie mit dem Operationscode IN gelesen und mit dem OP-Code OUT fortgeschrieben. Soll die Datenstruktur beim Einlesen nicht mit einem Lock versehen werden, kann im OP-Code IN auf den Zusatz *LOCK verzichtet werden.
Diese Unterstützung ermöglicht auch das Einlesen dezimaler Datenstrukturen (jener Datenstrukturen also, die mit TYPE(*DEC) in der Anweisung CRTDTAARA erstellt wurden). Das Einlesen geschieht durch Spezifikation des Schlüsselwortes DTAARA für ein dezimales gepacktes Feld im Programm (Abbildung 3). In diesem kleinen Beispiel wird auch ersichtlich, wie sich eine Bibliothek im Schlüsselwort DTAARA spezifizieren lässt.
D DailyTotal s 11P 2 DTAARA('RECVLIB/DAILYTOTAL')
/free
IN DailyTotal;
msg = 'Daily total = ' + %editc(DailyTotal:'L');
dsply msg;
/end-free
|
Abbildung 3: DTAARA und dezimal gepackte Felder
Ich möchte nun zur Ausgangsfrage zurückkehren. Seit V5R2 ist es möglich, im Schlüsselwort DTAARA den Spezialwert *VAR anzugeben. Mit Hilfe dieser Option lässt sich eine Variable als Datenstrukturname verwenden. (Abbildung 4).
D CoolName s 21A
D DailyTotal s 11P 2 dtaara(*Var:CoolName)
/free
CoolName = 'RECVLIB/TOT' + %char(%date(): *YMD0);
IN *LOCK DailyTotal;
DailyTotal = 123456789.87;
OUT DailyTotal;
/end-free
|
Abbildung 4: Vergabe eines Datenstrukturnamens basierend auf dem Tagesdatum
In diesem Beispiel wird der Datenstrukturname basierend auf dem aktuellen Tagesdatum zusammengestellt. Vorausgesetzt, heute sei der 12. Juli 2007, ergibt sich für die einzulesende Datenstruktur der Name TOT070712 in der Bibliothek RECVLIB. Die Datenstruktur wird beim Lesen mit einem Lock versehen. Nach Veränderung des Inhalts wird die Datenstruktur mit dem Operationscode OUT wieder auf die Platte zurückgeschrieben.


