Mit der Hilfe von Binderverzeichnissen sind wir jetzt in der Lage auch Programme, in denen Prozeduren aus verschiedenen Service-Programmen aufgerufen werden, in einem einzigen Schritt zu erstellen. Der Nachteil dabei ist, dass man sich die unterschiedlichen Compile-Optionen für die nächste Umwandlung merken muss. Einfacher wäre es, wenn die Compile-Optionen im Quell-Code hinterlegt werden könnten. Und genau das ist auch möglich! Und nicht nur in RPG, sondern auch in CL-Programmen. Wie das funktioniert wird in diesem Artikel gezeigt.
Sofern mit nur mit einem einzigen Binderverzeichnis oder immer mit den gleichen Binderverzeichnissen gearbeitet wird und immer die gleiche Aktivierungsgruppe für alle Programme gleichermaßen gilt, könnten u. U. die Unterlassungs-Werte im System-Befehl geändert werden. Spätestens aber dann, wenn man flexibler werden will oder muss, also unterschiedliche Binderverzeichnisse oder Aktivierungsgruppen benötigt, ist man genauso weit wie vor der Änderung des System-Befehls, d. h. ein manueller Eingriff ist erforderlich.
H-Bestimmungen für ILE-Optionen in RPG Quellen
Anstatt bei jeder Umwandlung an die entsprechenden Umwandlungsoptionen erinnern zu müssen, können die folgenden Optionen auch direkt in den H-Bestimmungen hinterlegt werden.
- Default-Aktivierungsgruppe – Schlüssel-Wort DFTACTGRP(*YES | *NO)
Der Aufruf von externen ILE-Prozeduren und Funktionen ist nur bei Verwendung der Option DFTACTGRP(*NO) zulässig.
Werden Programme mit DFTACTGRP(*YES) erstellt, verhalten sie sich wie OPM (Original Program Model) Programme (z. B. RPGIII). Die Verwendung von DFTACTGRP(*YES) ist dann sinnvoll, wenn eine alte RPGII/RPGIII-Anwendung, Programm für Programm zunächst nur nach RPGIV konvertiert werden soll. In modernen ILE-Anwendungen sollten weder Programme noch Service-Programme in der Default-Aktivierungsgruppe ausgeführt werden.
Die Angabe des Schlüssel-Wortes DFTACTGRP in den H-Bestimmungen ist nur zulässig, wenn das Programm mit dem Befehl CRTBNDRPG (RPG Binder-Programm erstellen) generiert wird. Bei einer zweistufigen Kompilierung bzw. bei Ausführung des Befehls CRTRPGMOD (RPG Modul erstellen) führt die Angabe des Schlüssel-Wortes DFTACTGRP in den H-Bestimmungen zu einem Kompilierungsfehler.
Seit der letzten Erweiterung in Release 7.1, ist die Angabe des Schlüssel-Wortes DFTACTGRP(*NO) für ILE-Programme optional. Wird eines der Schlüssel-Worte ACTGRP (Aktivierungsgruppe), BNDDIR (Binderverzeichnis) oder STGMDL (Storage Model) in den H-Bestimmungen hinterlegt, wird DFTACTGRP(*NO) vom Compiler automatisch hinzugefügt. - Aktivierungsgruppe – Schlüssel-Wort ACTGRP(*STGMDL | *NEW | *CALLER | ‘BENANNT’)
Sofern das Programm nicht in der Default-Aktivierungs-Gruppe ausgeführt werden soll, ist die Angabe einer Aktivierungsgruppe erforderlich. Im Umkehrschluss bedeutet dies, das Schlüssel-Wort ACTGRP kann nicht angegeben werden, wenn das Schlüssel-Wort DFTACTGRP(*YES) angegeben wurde.
Der Name der Aktivierungsgruppe kann entweder fix vorgegeben werden (= benannte Aktivierungsgruppe) oder über einen der zulässigen Sonderwerte festgelegt werden.- *STGMDL:
Abhängig vom ausgewählten Storage Model (Single Level oder Terasspace) wird das Programm entweder in der Aktivierungsgruppe QILE (Single Level) oder QILETS (Teraspace) aktiviert. - *NEW
Bei jedem Aufruf wird das Programm mit allen Service-Programmen, die mit der Aktivierungsgruppe *CALLER erstellt wurden und aus denen mindestens eine Prozedur aufgerufen wird, in einer neuen Aktivierungsgruppe aktiviert, die nach Programm-Ende wieder gelöscht wird. Beim Löschen der Aktivierungsgruppe wird alles was in der Aktivierungsgruppe aktiviert wurde, z. B. Service-Programme aber auch die ODP (Offenen Daten-Pfade) der ausgeführten SQL-Statement wieder gelöscht. - *CALLER
Das Programm wird in der gleichen Aktivierungsgruppe ausgeführt wie das rufende (Service-)Programm.
- *STGMDL:
Die Angabe des Schlüssel-Wortes ACTGRP in den H-Bestimmungen ist nur erlaubt, wenn das Programm mit dem Befehl CRTBNDRPG (RPG Binder-Programm erstellen) generiert wird.
- Binderverzeichnis – Schlüssel-Wort BNDDIR(‘BINDERVZ1’ {:’BINDERVZ2’…})
In den H-Bestimmungen können mit Hilfe des Schlüssel-Wortes BNDDIR entweder ein einziges oder mehrere Binderverzeichnisse angegeben werden. Die einzelnen Binderverzeichnisse werden von einander durch Doppelpunkte getrennt, in Hochkommata eingebettet und in Großbuchstaben angegeben. Binderverzeichnisse können auch qualifiziert in der Form ‘BIBLIOTHÈK/BINDERVERZ‘ angegeben werden.
Werden Compile-Optionen in den H-Bestimmungen hinterlegt, so überschreiben die in den H-Bestimmungen hinterlegten Optionen die Angaben im Kompilierungs-Befehl. Eine Ausnahme dieser Regel bilden jedoch die Binderverzeichnisse, d. h. die Binderverzeichnis-Einträge im Kompilierungs-Befehl werden NICHT überschrieben.
Achtung: Werden in den H-Bestimmungen und im Kompilierungs-Befehl unterschiedliche Binderverzeichnisse angegeben, so werden ALLE angegebenen Binderverzeichnisse, also sowohl die in den H-Bestimmungen als auch die in dem Kompilierungs-Befehl aufgelisteten Binderverzeichnisse durchsucht.
Das folgende Code-Beispiel zeigt ILE-Compile-Optionen für ein Programm, zunächst im fixen und im Anschluss die gleichen Optionen im Free-Format.
Das Programm wird nach Erstellung aufgrund des Schlüssel-Wortes ACTGRP in der Aktivierungsgruppe YOURPGM ausgeführt. Die Angabe des Schlüssel-Wortes DFTACTGRP(*NO) ist in der Free-Format Codierung optional. Deshalb wurde das Schlüssel-Wort nur im fixen, nicht jedoch im Free-Format angegeben. Zum Auffinden der zu bindenden Module und Service-Programme werden die Binderverzeichnisse YOURBNDD01 und YOURBNDD03, die sich zur Compile-Zeit in der Bibliotheksliste befinden, sowie das Binderverzeichnis YOURBNDD02 in Bibliothek YOUROBJLIB durchsucht.
H DftActGrp(*No) Actgrp('YOURPGM')
H BndDir('YOURBNDD01': 'YOUROBJLIB/YOURBNDD02': 'YOURBNDD03')
CTL-Opt ActGrp('YOURPGM')
BndDir('YOURBNDD01': 'YOUROBJLIB/YOURBNDD02': 'YOURBNDD03');
Beispiel 1: H-Bestimmungen mit ILE-Erstellungs-Optionen
Werden Programme, die embedded SQL beinhalten erstellt, können die Erstellungs-Optionen wahlweise in den H-Bestimmungen oder über das Schlüssel-Wort COMPILEOPT in einer SET OPTION-Anweisung hinterlegt werden.
Anmerkung: Da die Compile-Optionen (COMPILEOPT) weder im Kompilierungs-Befehl CRTSQLRPGI noch in der SET OPTION-Anweisung auf Gültigkeit geprüft werden, ist die Angabe in den H-Bestimmungen dem SET OPTION Statement vorzuziehen.
Compiler-Direktiven für ein oder zweistufige Kompilierung
Die Schlüssel-Worte DFTACTGRP (Default-Aktivierungsgruppe) und ACTGRP (Aktivierungsgruppe) dürfen nur dann in den H-Bestimmungen hinterlegt sein, wenn das Programm mit dem Befehl CRTBNDRPG erstellt wird.
Versucht man eine Quelle in der eines der Schlüssel-Worte ACTGRP oder DFTACTGRP verwendet wurde zweistufig zu kompilieren, d. h. zunächst das Modul erstellen und im Anschluss daran das Programm zu binden, wird dies nicht gelingen. Bereits beim Erstellen des Moduls tritt ein Kompilierungsfehler auf.
Über Compiler-Direktiven ist es möglich die Schlüssel-Worte so zu hinterlegen, dass sie nur berücksichtigt werden, wenn die Kompilierung über CRTBNDRPG erfolgt.
Compiler-Direktiven beginnen immer mit einem Slash (/). Im fixen Format muss der Slash auf Position 7 angegeben werden, im Free-Format kann die Compiler-Direktive an jeder beliebigen Stelle zwischen Position 8 und 80 begonnen werden. Wird im Full-Free-RPG (** FREE auf der 1. Position in der 1.Zeile) codiert, kann der Slash an jeder beliebigen Stelle stehen. Pro Zeile kann jedoch immer nur eine einzige Compiler-Direktive angegeben werden. Zu den Compiler-Direktiven gehören u. a. /COPY, /INCLUDE aber auch /FREE und /END-FREE.
Neben diesen Compiler-Direktiven gibt es noch die bedingten Compiler-Direktiven. Die Bedingungen werden über eine /IF-Anweisung geprüft. Auf /IF muss entweder DEFINED oder NOT DEFINED folgen. Die eigentliche Bedingung wird im Anschluss eingebettet in runden Klammern angegeben, z. B. /IF DEFINED (*CRTBNDRPG).
Neben den /IF-Direktiven gibt es noch /ELSEIF und /ELSE-Direktiven sowie die /ENDIF-Direktive. Jede /IF-Direktive muss mit einer /ENDIF-Direktive abgeschlossen werden. Die Angabe von /ELSE bzw. /ELSEIF-Direktiven ist optional.
Code-Zeilen zwischen der IF-Direktive und der /ENDIF-Direktive werden vom Compiler nur dann berücksichtigt, wenn die Bedingung in der /IF-Direktive angegebene Bedingung wahr ist.
Um bestimmte Code-Zeilen während der Kompilierung basierend auf dem verwendeten Kompilierungs-Befehl zu aktivieren oder ignorieren, wurden die folgenden vordefinierten Bedingungen bereitgestellt:
- *CRTBNDRPG
Die Code-Zeilen werden nur berücksichtigt, wenn die Kompilierung mit dem Befehl CRTBNDRPG erfolgt. - *CRTRPGMOD
Die Code-Zeilen werden nur berücksichtigt, wenn die Kompilierung mit dem Befehl CRTRPGMOD erfolgt.
Das folgende Beispiel zeigt nochmals die H-Bestimmungen aus dem vorhergehenden Beispiel. Dieses Mal sind die Schlüssel-Worte DFTACTGRP und ACTGRP bedingt, d. h. sie werden nur berücksichtigt, wenn die Kompilierung mit CRTBNDRPG erfolgt. Wird die Quelle mit CRTMODRPG in ein Modul umgewandelt, werden beide Schlüssel-Worte ignoriert und das Modul kann ordnungsgemäß erstellt werden. Das Schlüssel-Wort BNDDIR ist weder im fixen noch im Free-Format bedingt, d. h. es wird immer berücksichtigt.
Für die Free-Format-Anweisungen ist noch anzumerken, dass in diesem Beispiel die Compiler-Direktiven innerhalb des CTL-OPT-Statements angegeben wurden und nur für einen Teil der Schlüssel-Worte gelten. Diese Syntax ist zulässig. Alternativ hätten auch mehrere CTL-OPT-Statements, die einzeln bedingt werden, angegeben werden können.
/If Defined (*CRTBNDRPG)
H DftActGrp(*No) Actgrp('YOURPGM')
/EndIf
H BndDir('YOURBNDD01': 'YOUROBJLIB/YOURBNDD02': 'YOURBNDD03')
CTL-Opt BndDir('YOURBNDD01': 'YOUROBJLIB/YOURBNDD02': 'YOURBNDD03')
/If Defined (*CRTBNDRPG)
ActGrp('YOURPGM')
/EndIf
;
Beispiel 2: Compiler-Direktiven für ein- oder zweistufige Kompilierung
CL-Befehl DCLPRCOPT für ILE-Optionen in CL-Quellen
Sofern ILE-CL-Programme erstellt werden müssen, die in einer speziellen Aktivierungsgruppe ausgeführt werden oder aus denen Prozeduren aufgerufen werden, die in mehreren Service-Programmen hinterlegt sind und die wiederum in diversen Binderverzeichnissen hinterlegt sind, so können diese Informationen wie auch bei ILE-RPG-Programmen im Kompilierungsbefehl angegeben werden.
Aber auch für CL besteht die Möglichkeit solche Kompilierungsoptionen direkt in der Quelle zu hinterlegen. Dies geschieht mit Hilfe des CL-Befehls DCLPRCOPT (Verarbeitungsoptionen deklarieren) zu hinterlegen.
Die Verwendung des Befehls DCLPRCOPT ist nur innerhalb von ILE-CL-Quellen (Teildatei-Art CLLE) erlaubt. Der Befehl DCLPRCOPT darf in einer Quelle nur einmalig angegeben werden. Wurde der Befehl DCLPRCOPT mehrfach codiert, bricht die Kompilierung mit Fehlermeldung CPD0323 ab. Wie alle anderen DECLARE-Befehle z. B. DCL (CL-Variable deklarieren) oder DCLF (Datei deklarieren) muss auch der DCLPRCOPT am Anfang des CL-Quell-Codes vor allen anderen Befehlen angegeben werden. Unter den Declare-Befehlen jedoch gibt es keine vorgeschriebene Reihenfolge.
Die folgende Tabelle zeigt den Befehl DCLPRCOPT mit allen Optionen und deren Ausprägungen.

Wurde der Befehl DCLPRCOPT in einer CLLE-Quelle angegeben, überschreiben die angegebenen Werte die in den Kompilierungs-Befehlen angegebenen Werte oder die in den Kompilierungs-Befehlen hinterlegten Default-Werte.
Das folgende Beispiel zeigt den Anfang des Source Codes eines CLLE-Programms. Über den Befehl DCLPRCOPT zunächst die Default-Aktivierungsgruppe auf *NO gesetzt und die Aktivierungsgruppe YOURCLGPM verwendet. Das Binder-Service-Programm YOURSRVP01 wird gebunden und sofort aktiviert (Unterlassungs-Wert für Aktivierung ist *IMMED). Das Binder-Service-Programm YOURSRVP02 in Bibliothek YOUROBJLIB wird ebenfalls gebunden, seine Aktivierung jedoch bis zum ersten Aufruf einer Prozedur aus diesem Service-Programm verzögert (Aktivierung = *DEFER). Die Binderverzeichnisse YOURBNDD01 und YOURBNDD03 in der Bibliotheksliste, sowie das Binderverzeichnis YOURBNDD02 in Bibliothek YOUROBJLIB werden während des Binder-Schritts durchsucht.
PGM PARM(&Parm1 &Parm2 &Parm3)
DCL VAR(&Parm1) TYPE(*CHAR) LEN(10)
/* Weitere Variablen */
DCLPRCOPT DFTACTGRP(*NO) +
ACTGRP(YOURCLPGM) +
BNDSRVPGM((YOURSRVP01) (YOUROBJLIB/YOURSRVP02 *DEFER)) +
BNDDIR(YOURBNDD01 YOUROBJLIB/YOURBNDD02 YOURBNDD03)
Beispiel 4: Setzen von ILE-Optionen in CLLE-Quellen über den Befehl DCLRPCOPT
Soweit zum Einbinden von Compile-Optionen in die RPG- und CL-Programm-Quellen.
… und nun viel Spaß bei der ein- und zweistufigen Kompilierung.
Birgitta Hauser ist IBM Champion und Spezialistin für SQL- sowie RPG-Programmierung.
Frau Hauser gibt regelmäßig Workshops im Rahmen der MIDRANGE ACADEMY.
Sie schreibt regelmäßig für MIDRANGE und den TechKnowLetter. Hier erhalten Sie brandneue, tiefe Informationen zu SQL, RPG und vielem mehr.
Der TechKnowLetter erscheint monatlich. Sechs Ausgaben erhalten Sie für 88 Euro hier.