REXX und DMS - service professional GmbH
Transcrição
REXX und DMS - service professional GmbH
347 Anhang - A FehlerMeldungen 348 REXX unter MVS-TSO/E Anhang - A 349 Fehlermeldungen Die nachfolgenden Fehlernummern werden vom Interpreter bei Auftreten eines Syntaxfehlers ausgegeben. Der Interpreter meldet die Fehlernummer mit dem Vorspann IRXxxxxI und einer kurzen Erläuterung. Wurde in einem Programm SIGNAL ON SYNTAX kodiert, liegt die jeweilige Fehlernummer in der Variablen RC. Beschrieben werden auf den folgenden Seiten jeweils: ● die Fehlernummer ● die Kurzerklärung im Originaltext ● die Bedeutung ● die Systemreaktion und ● die Benutzeraktion Darüber hinaus können folgende Manuals der IBM zu Rate gezogen werden: ● TSO/E Messages ● MVS Message Library: System Messages Vol. 1 und 2 IRX0003I Error running progname line nn: Program is unreadable Erklärung: Das Programm konnte nicht gelesen werden. Die Ursache hierfür ist häufig der Aufruf von IRXEXEC mit Übergabe eines Programmes, das wegen falschen Formates nicht gelesen werden kann. Systemreaktion: Programm-Abbruch Bediener-Aktion: Prüfen Sie das Format des Programmes oder benachrichtigen Sie die Systemprogrammierung. IRX0004I Error running progname line nn: Program interrupted Erklärung: Die Programmausführung wurde unterbrochen. Im allgemeinen ist die Ursache hierfür die Eingabe HI auf die PA-1-Taste hin, oder der Befehl EXECUTIL HI innerhalb des Programmes. Liegt die Ursache in einem anderen Fehler, wird eine entsprechende Fehlermeldung ausgegeben. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Sofern der Abbruch nicht gewollt war, beheben Sie Ihr Problem aufgrund der ausgegebenen Fehlermeldung. 350 REXX unter MVS-TSO/E Fehlermeldungen IRX0005I Machine storage exhaust Erklärung: Speicherüberlauf. In aller Regel wird der Fehler durch eine Fehlerschleife eines Programmes erzeugt, bei der Speichervariablen in endloser Zahl erzeugt werden und der Interpreter nicht genügend Speicher zur Verfügung gestellt bekommt. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Prüfen Sie die Ursache für die Endlosschleife (TRACE). Läuft Ihr Programm nicht in einer Fehlerschleife, kontaktieren Sie die Systemprogrammierung. IRX0006I Error running progname line nn: Unmatched *" or quote "/ Erklärung: Der Interpreter hat Dateiende (oder Datenende bei einer INTERPRET-Instruktion) erreicht, ohne auf ein Kommentar- oder Literalbegrenzungszeichen gestoßen zu sein. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm, indem Sie das fehlende Begrenzungszeichen hinzufügen. Fällt es Ihnen schwer, die Ursache zu finden, kodieren Sie das Statement TRACE SCAN an den Programmanfang und starten Sie Ihr Programm erneut. Auf diesem Weg sollte es möglich sein, die Ursache für den Fehler zu finden. IRX0007I Error running progname line nn: WHEN or OTHERWISE expected Erklärung: Der Interpreter findet in einem SELECT-Gebilde keine WHEN- oder OTERWISE-Klausel. Häufige Ursache ist das Fehlen eines END-Statements (siehe Beispiel). Falsch Richtig SELECT SELECT WHEN ? THEN WHEN ? THEN DO SAY ... SAY ... EXIT EXIT OTHERWISE NOP END END OTHERWISE NOP : END Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. Anhang - A 351 Fehlermeldungen IRX0008I Error running progname line nn: Unexpected THEN or ELSE Erklärung: Der Interpreter fand eine THEN- oder ELSE-Klausel, für die es keine Zuordnung zu einem IF-Befehl gibt. Häufige Ursache ist das Fehlen eines END-Statements (siehe Beispiel). Falsch Richtig IF ? THEN IF ? THEN DO SAY ... SAY ... EXIT EXIT ELSE SAY ... END : ELSE SAY ... Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0009I Error running progname line nn: Unexpected WHEN or OTHERWISE Erklärung: Der Interpreter fand eine WHEN- oder OTHERWISE-Klausel außerhalb eines SELECT-Gebildes. Häufige Ursache ist der Versuch, durch einen Sprung mit SIGNAL das SELECT-Gebilde zu verlassen (in diesem Fall wird das SELECT-Gebilde als unmittelbar beendet betrachtet). Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0010I Error running progname line nn: Unexpected or unmatched END Erklärung: Der Interpreter fand mehr END-Statements, als DO- oder SELECT-Anweisungen vorhanden sind, oder die ENDs stehen in einer Reihenfolge, die keine Zugehörigkeit zu einem DO- oder SELECT-Statement erkennen lassen. Diese Situation tritt häufig in zwei Situationen auf: Auf ein THEN- oder ELSE-Konstrukt folgt unmittelbar ein END. Mit SIGNAL wurde versucht in eine Schleife zu springen. Wird das Schleifenende gelesen, kann die Beziehung zum Schleifenkopf nicht hergestellt werden (SIGNAL ist kein GOTO-Befehl). Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. TRACE SCAN ist hilfreich. 352 REXX unter MVS-TSO/E Fehlermeldungen IRX0011I Error running progname line nn: Control stack full Erklärung: Diese Meldung erscheint, wenn die mögliche Verschachtelungstiefe von 250 für DO-END oder IF-THEN-ELSE überschritten wurde, oder ein LOOP durch eine Anweisung wie befehl="INTERPRET befehl" INTERPRET befehl kodiert wird. Hier erzeugt der INTERPRET-Befehl die Schleife, die zur Meldung führt, wenn sie mehr als 250 mal durchlaufen wird. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0012I Error running progname line nn: Clause > 500 characters Erklärung: Die Länge eines Befehles überschreitet 500 Zeichen. Im Befehl liegende Kommentare werden dabei nicht berücksichtigt, mehrere Blanks zwischen zwei Befehlsteilen werden wie eines betrachtet. Der häufigste Grund für die Meldung ist ein fehlendes Literal-Begrenzungszeichen. In diesem Fall erscheint die Meldung gleich zu Beginn der Programmverarbeitung. Die Meldung wird am Terminal durch drei führende Plus(+) markiert. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0013I Error running progname line nn: Invalid character in data Erklärung: Der Interpreter fand ein nicht erlaubtes Zeichen außerhalb eines Literals. Häufig sind dies im deutschsprachigen Raum die Umlaute. Erlaubte Zeichen lesen sie bitte im Kapitel 1 nach (Namensvergabe für Variablen). Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. Anhang - A 353 Fehlermeldungen IRX0014I Error running progname line nn: Incomplete DO/SELECT/IF Erklärung: Der Interpreter hat Programmende erreicht, ohne daß für jedes DO oder SELECT ein END, oder für IF ein zugehöriges THEN erkannt wurde. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0015I Error running progname line nn: Invalid hex constant Erklärung: Hexadezimale Konstanten dürfen weder führende noch nachlaufende Blanks enthalten. Blanks dürfen ausschließlich zur Trennung an der Bytegrenze innerhalb der Konstanten kodiert werden. '14'x 'C8 E3 C7 D6'x '2df4'x Häufige Fehler sind beispielsweise das Kodieren des Buchstaben O statt der Zahl 0, oder eine Variable X wird unmittelbar im Anschluß an ein Literal kodiert (das Literal wird so zu einer HEX-Konstanten). Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0016I Error running progname line nn: Label not found Erklärung: Das Ziel einer Sprunganweisung SIGNAL kann nicht gefunden werden. Häufig liegt es an Schreibfehlern, oder das Label wurde vergessen (SIGNAL ON SYNTAX reklamiert ein fehlendes Label SYNTAX erst, wenn Syntaxfehler auftritt). Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0017I Error running progname line nn: Unexpected PROCEDURE Erklärung: Die Anweisung PROCEDURE wurde an falscher Stelle entdeckt. Der häufigste Fehler hierfür: PROCEDURE ist nicht die erste Instruktion, die durch CALL oder Funktionsaufruf angesteuert wird. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. 354 REXX unter MVS-TSO/E Fehlermeldungen IRX0018I Error running progname line nn: THEN expected Erklärung: Alle IF und WHEN-Klauseln verlangen zwingend den Operanden THEN. Entweder fehlt die Angabe, oder ein anderes Wort wurde vor THEN kodiert. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0019I Error running progname line nn: String or Symbol expected Erklärung: Die Instruktionen CALL, SIGNAL, SIGNAL ON oder SIGNAL OFF erwarten zwingend ein Symbol oder Literal im Anschluß. Entweder wurde es vergessen oder es enthält ein an dieser Stelle nicht erlaubtes Sonderzeichen wie "(". Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0020I Error running progname line nn: Symbol expected Erklärung: Befehle wie DROP, PARSE oder UPPER erwarten zwingend ein oder mehrere Symbole hinter dem Befehlswort. Das Symbol wurde nicht gefunden. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0021I Error running progname line nn: Invalid data on end of clause Erklärung: Eine Instruktion wie NOP oder SELECT wird von etwas anderem als einem Kommentar gefolgt. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0022I Error running progname line nn: Invalid character string Erklärung: Eine unzulässige Zeichenfolge wurde entdeckt (siehe REXX-REFERENCE-Manual, Befehl OPTIONS - exotisch) Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. Anhang - A 355 Fehlermeldungen IRX0023I Error running progname line nn: Invalid SCBS/ DBCS mixed string Erklärung: Siehe vorhergehende Meldung. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0024I Error running progname line nn: Invalid TRACE request Erklärung: Eine ungültige TRACE-Option wurde kodiert. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0025I Error running progname line nn: Invalid subkeyword found Erklärung: Der Befehlsprozessor erwartet hinter bestimmten Befehlen ganz bestimmte Sub-Parameter. So ist beispielsweise hinter NUMERIC einer der Werte DIGITS, FUZZ oder FORM zu kodieren. Erkennt der Befehlsprozessor irgend etwas anderes, erscheint diese Meldung. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0026I Error running progname line nn: Invalid whole number Erklärung: Wo zwingend eine ganze Zahl erwartet wird, wurde entweder etwas anderes entdeckt, oder der Maximalwert von 999 999 999 wurde überschritten. Dies kann beispielsweise in der Anweisung NUMERIC oder auf der rechten Seite der Potenzierung (**) vorkommen. Ebenso kann der Fehler hervorgerufen werden, wenn das Programm als Kommando aufgerufen wurde und in der Anweisung EXIT oder RETURN ein Returncode zurückgereicht werden soll, der über eine Variable geliefert wird. Entweder ist die entsprechende Variable falsch gefüllt, oder es handelt sich um einen Schreibfehler wie EXIT RT statt EXIT RC (Ist die Variable nicht gefüllt, zeigt sie inhaltlich auf ihren zu Großschreibung konvertierten Eigennamen). Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. 356 REXX unter MVS-TSO/E Fehlermeldungen IRX0027I Error running progname line nn: Invalid DO syntax Erklärung: Der Befehlsprozessor entdeckte einen Syntaxfehler in einem Schleifenkopf. Dies kann die doppelte Kodierung von BY oder TO sein, oder BY oder TO waren angegeben, aber eine Steuervariable war nicht definiert. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0028I Error running progname line nn: Invalid LEAVE or ITERATE Erklärung: LEAVE oder ITERATE wurden als falsch erkannt, weil sie entweder außerhalb einer Schleife stehen oder der Name hinter der Anweisung nicht mit einer Steuervariablen eines Schleifenkopfes übereinstimmt. Bedenken Sie, daß mit einer Instruktion LEAVE in einer Subroutine keine Schleife im Hauptprogramm verlassen werden kann. Auch wenn Sie SIGNAL zum GOTO vergewaltigen, kann es zu dieser Meldung kommen. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0029I Error running progname line nn: Environment name to long Erklärung: Der Name einer Systemumgebung ist länger als 8 Byte. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihre ADDRESS-Instruktion. IRX0030I Error running progname line nn: Name or string > 250 Byte Erklärung: Ein Literal oder ein Variablenname größer 250 Byte wurde entdeckt. Häufigste Ursache ist das Fehlen eines Begrenzungszeichens für ein Literal. Müssen Variablen mit einem Literal > 250 Byte gefüllt werden, muß dies in mehreren Schritten geschehen: A="literal < 250 Byte" B="Literal < 250 Byte" C=A!!B Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. Anhang - A 357 Fehlermeldungen IRX0031I Error running progname line nn: Name starts with numeric or "." Erklärung: Entsprechend der Regeln für Variablen darf der Name einer Variablen weder mit Punkt noch mit einer Zahl beginnen (man könnte sonst numerische Konstante redefinieren, was katastrophale Folgen hätte). Systemreaktion: Programm-Abbruch. Bediener-Aktion: Geben Sie der Variablen einen vernünftigen Namen. Auch wenn einige Sonderzeichen an Stelle 1 erlaubt sind, benutzen Sie einen Buchstaben. IRX0032I Error running progname line nn: Invalid use of stem Erklärung: Ein Variablenstamm wurde auf falsche Weise genutzt (Das Konvertieren eines Variablenstammes über UPPER VAR. ist beispielsweise nicht möglich). Systemreaktion: Programm-Abbruch. Bediener-Aktion: Die Verarbeitung des Variablenstammes mit allen seinen Variablen muß notfalls in einer Programmschleife erledigt werden. IRX0033I Error running progname line nn: Invalid expression result Erklärung: Das Resultat eines Ausdruckes ist falsch. Wurde beispielsweise in der Instruktion NUMERIC der Wert für DIGITS oder FUZZ verändert, kann es zu dieser Fehlermeldung kommen, weil der Wert von FUZZ nicht größer dem von DIGITS sein darf. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0034I Error running progname line nn: Logical value not 0 or 1 Erklärung: Ausdrücke in IF, WHEN, UNTIL oder WHILE müssen immer ein logisches TRUE(1) oder FLASE(0) liefern. Der Befehl: IF result THEN EXIT ist falsch, wenn der Inhalt von RESULT weder 0 noch 1 ist. Besser wäre in diesem Fall sicher IF result >< 0 THEN EXIT Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. 358 REXX unter MVS-TSO/E Fehlermeldungen IRX0035I Error running progname line nn: Invalid expression Erklärung: Ein Formfehler in einem Ausdruck. Mögliche Ursachen sind zwei aufeinanderfolgende Bool'sche Operanden, ein Ausdruck, bei welchem hinter dem Vergleichsoperanden kein Wert folgt, oder ein Zuweisungsbefehl, bei dem in einer Konstanten nicht erlaubte Sonderzeichen kodiert sind und keine Literalbegrenzer genutzt wurden (z.B.: var = 7 ++ b). Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0036I Error running progname line nn: Unmatched "(" in expression Erklärung: Die Anzahl öffnender Klammern in einer Instruktion weicht von der Anzahl schließender Klammern ab. Diese Situation tritt auf, wenn die Klammer in einem Befehl als Literal genutzt werden soll, aber keine Literalbegrenzer kodiert werden: Falsch: IF POS((,variable) > 0 THEN ... Richtig: IF POS("(",variable) > 0 THEN... Hinweis:Prüfungen dieser Art finden nur für REXX-Instruktionen statt. Kodieren wir beispielsweise einen EXECIO-Befehl, bei dem die schließende Klammer nicht zwingend ist, ist das OK: Richtig: EXECIO 4 DISKR ddname (FINIS Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0037I Error running progname line nn: Unexpected "," or ")" Erklärung: Komma wurde außerhalb eines Funktionsaufrufes (nicht als Fortsetzungszeichen) gefunden, oder in einem numerischen Ausdruck gibt es mehr schließende als öffnende Klammern. Wird Komma in einem Character-Ausdruck benutzt, sollte dieser als Literal kodiert werden: Falsch: SAY Waehle A, B, oder C Richtig: SAY "Waehle A, B, oder C" Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. Anhang - A 359 Fehlermeldungen IRX0038I Error running progname line nn: Invalid template or pattern Erklärung: Ein nicht erlaubtes Sonderzeichen wurde als Trennzeichen für Parsing genutzt (wie %). Die Meldung wird auch ausgegeben, wenn der Operand WITH in der Instruktion PARSE VALUE vergessen wird. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0039I Error running progname line nn: Evaluation stack overflow Erklärung: Der Befehlsprozessor konnte einen Ausdruck aufgrund seiner Komplexität nicht auflösen (zu viele Klammern oder ineinander verschachtelte Funktionen). Systemreaktion: Programm-Abbruch. Bediener-Aktion: Brechen Sie den Ausdruck auf. Erzeugen Sie temporäre Variablen und führen Sie deren Ergebnisse wieder zusammen. IRX0040I Error running progname line nn: Incorrect call to routine Erklärung: Häufigste Ursache hierfür ist, daß einer internen oder externen Funktion (REXX oder UDF) ein falscher Wert übergeben wurde. Dies ist abhängig von der jeweiligen Funktion. Sollte kein Funktionsaufruf stattfinden, liegt es oft an falscher Schreibweise. Wird ein Klammernpaar im direkten Anschluß an ein Wort kodiert, geht der Befehlsprozessor immer davon aus, daß es sich hierbei um eine Funktion handelt. Deshalb: Falsch: SAY Moegliche Eingabe(1/2) Richtig: SAY "Moegliche Eingabe(1/2)" Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. 360 REXX unter MVS-TSO/E Fehlermeldungen IRX0041I Error running progname line nn: Bad arithmetic conversion Erklärung: Der Befehlsprozessor fand in einem numerischen Ausdruck einen Wert, der nicht numerisch war, oder einen Exponenten, der außerhalb der möglichen Werte (+999 999 999 bis -999 999 999) liegt.Die häufigsten Ursachen sind Tippfehler im Namen einer Variablen oder TSO-Befehle, die nicht als Literale definiert wurden. Der Befehl EXECIO * DISKR führt zum Versuch, zwei Character-Variablen miteinander zu multiplizieren. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0042I Error running progname line nn: Arithmetic overflow/underflow Erklärung: Eine numerische Variable hat den Maximal- oder Minimalwert überschritten (999 999 999 bis -999 999 999). Häufige Ursache ist, wenn in einer Fehlerschleife eine Variable endlos mit sich selbst addiert oder multipliziert wird. Die Meldung wird auch ausgegeben, wenn mit 0 dividiert werden soll. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0043I Error running progname line nn: Routine not found Erklärung: Im Programm erfolgte ein Funktionsaufruf oder eine CALLInstruktion. Es gibt drei mögliche Ursachen: Der Name der Routine (Programm oder Funktion) wurde als Labelname im Programm nicht gefunden. Es handelt sich nicht um eine REXX-Funktion, und die externe Suche innerhalb der SYSEXEC/SYSPROC-Verkettung war ergebnislos. Sollte keine Funktion aufgerufen werden, ist die Meldung das Ergebnis einer falschen Schreibweise. Wird ein Klammernpaar unmittelbar an eine Zeichenfolge kodiert, geht der Befehlsprozessor immer davon aus, daß es sich hierbei um einen Funktionsaufruf handelt. Entweder haben Sie vergessen, ein Blank zwischen Zeichenfolge und Klammer zu kodieren, oder in einem arithmetischen Ausdruck fehlt ein Operationszeichen: Falsch: ERG=VAR1(VAR2-7) Richtig: ERG=VAR1*(VAR2-7) Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. Anhang - A 361 Fehlermeldungen IRX0044I Error running progname line nn: Function did not return data Erklärung: Eine Funktion liefert keine Daten zurück, obwohl sie dem Anschein nach fehlerfrei beendet wurde. Wird beispielsweise mit STORAGE(..) ein Speicherbereich gelesen, auf den man keinen Zugriff hat, gibt die Funktion keinen Wert zurück (STORAGE() ist in diesem Buch nicht dokumentiert). Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0045I Error running progname line nn: No data specified on function RETURN Erklärung: Ein REXX-Programm wurde als Funktion aufgerufen und bei dessen Programmende wurden über die Anweisung RETURN keine Daten zurückgereicht. Eine Funktion muß immer einen Wert zurückreichen, da er im Ablauf des Programmes an die Stelle der Funktion tritt. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Korrigieren Sie Ihr Programm. IRX0046I Nicht belegt IRX0047I Nicht belegt IRX0048I Error running progname line nn: Failure in system service Erklärung: Der Befehlsprozessor beendete ein Programm, weil eine Systemroutine (Ein-/Ausgaben oder Stackmanipulation) mißglückte. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Überprüfen Sie Ihr Programm. Wenden Sie sich an die Systemprogrammierung. IRX0049I Error running progname line nn: Interpreter failure Erklärung: Der Interpreter führt eine laufende Selbstprüfung durch. Endet eine dieser Prüfungen mit einem schweren Fehler, wird diese Meldung ausgegeben. Systemreaktion: Programm-Abbruch. Bediener-Aktion: Informieren Sie die Systemprogrammierung. Leiten Sie eine Nachricht an IBM weiter. 362 Fehlermeldungen REXX unter MVS-TSO/E 363 Anhang - B REXX und DMS (Dialog Management Services) 364 REXX und DMS REXX unter MVS-TSO/E 365 Anhang - B REXX und DMS Die Servicepalette des Dialog Managers umfaßt mehrere Bausteine, die im Verbund das Erstellen von Dialog-Anwendungen auf einem sehr hohen Komfortgrad ermöglichen. Die einzelnen Dienste des Dialog Managers werden als Mitglieder von PODateien erstellt. Die Aufteilung nach Zugehörigkeit zu einem Service und die Nutzung nachfolgender Dateinamen ist eine Empfehlung: userid.????????.PANELS Bildschirmmasken für die Services DISPLAY und SELECT userid.????????.TABLES Tabellenein- und -ausgaben für alle Tabellen-Services (wobei Ausgaben prinzipiell wahlfrei zugeordnet werden können). userid.????????.MSGS Nachrichten, die in Bildschirmmasken benutzt werden. userid.????????.SKELS Skelette für den FILE-TAILORING-SERVICE. userid.PROFILE Bildet mit seinen Mitgliedern den applikationsabhängigen Variablenpool ab. Alle diese Bibliotheken müssen dem Dialog Manager unter entsprechenden DD-Namen bekannt sein. Auf eine detaillierte Beschreibung des Umfeldes können wir hier nicht eingehen. Die einzelnen Serviceleistungen wollen wir kurz anreißen: Display Service Wird zur Anzeige von Bildschirmmasken genutzt. Hierbei wird davon ausgegangen, daß in der Bildschirmmaske prinzipiell beliebig viele Ein-/Ausgabe- und Textfelder enthalten sein können. Dieser Service wird im allgemeinen zur Datenerfassung oder Präsentation genutzt. 366 REXX unter MVS-TSO/E REXX und DMS Selection Service Hier wird grundsätzlich ebenfalls eine Bildschirmmaske angezeigt. Im Unterschied zum Display Service handelt es sich aber um sogenannte Auswahlmenüs (vergleichsweise Menü 0 aus ISPF/PDF), bei denen durch Eingabe eines Auswahlkriteriums nachfolgende Aktivitäten aus dem Panel heraus gesteuert werden. Variablen Service Mit dem Variablen Service wird uns die Möglichkeit gegeben, die Inhalte beliebiger Variablen über Programmende oder über LOGOFF hinaus festzuhalten und zu einem beliebigen späteren Zeitpunkt wieder zur Verfügung zu haben. Für das Ablegen von Variablen nutzt der Dialog Manager drei verschiedene Variablen-Pools: ● Function Pool ● Shared Pool ● Profile Pool Table Service Mit dem Tabellen Service wird ein Werkzeug angeboten, das Tabellenverarbeitung auf einer kaum vorstellbaren Komfortstufe ermöglicht. Bei kleineren Anwendungen (bis etwa 20.000 Datensätze) ersetzt dieser Service im Regelfall den Einsatz von Datenbanken. Die einzelnen Datenfelder der Tabellensätze müssen weder von ihrer Länge her, noch in Bezug auf den Datentyp identisch sein. Darüber hinaus können auch im nachhinein für einzelne oder alle Tabellensätze Felder hinzugefügt werden, die in ihrem Aussehen ebenfalls vollkommen flexibel sein können. Durch die Definition von Schlüsselfeldern kann das doppelte Führen von Datensätzen ausgeschlossen werden. Die Prüfung auf Vorhandensein übernimmt der Service selbst. Über Sortierbefehle kann die Tabelle, nach beliebigen Feldern sortiert, aufbereitet werden. File Tailoring Service Bietet im wesentlichen die Möglichkeit, vorbereitete Datengerippe zusammenzuführen und in eine gemeinsame Datei auszugeben. Dabei können sowohl Variablen substituiert als auch Tabellen des Dialog Managers implementiert werden. Eine klassische Anwendung des File Tailoring wäre beispielsweise die Druckausgabe einer DMSTabelle durch JCL (gegebenenfalls auch nur selektierte Sätze), die durch das File Tailoring vervollständigt wird. Anhang - B 367 REXX und DMS Wird ein Service des DMS beendet, reicht er einen Returncode an das aufrufende Programm zurück. Die möglichen Returncodes sind 0, 4, 8, 12, 16 und 20. Der jeweilige Hintergrund ist abhängig von den entsprechenden Services und kann bei der dazugehörenden Syntaxbeschreibung nachgelesen werden. In einem REXX-Programm liegt der Returncode in der Variablen RC, bei CLIST in &LASTCC vor, sobald die Steuerung über den weiteren Ablauf von DMS wieder an das Programm zurückgegeben wird. Tritt im Service ein Returncode bis kleiner als 12 auf, wird mit dem nächsten Befehl im Programm die Verarbeitung fortgesetzt. Um in der Entwicklungsphase eines Dialoges mit möglichst viel Komfort unterstützt zu werden, empfiehlt es sich, mit dem EDIT-Befehl MODEL zu arbeiten. Über die Befehlskombination "MODEL-A/B" werden die Befehle der jeweils aktiven ModelKlasse (abhängig vom letzten Dateinamens-Qualifier) angezeigt. Nach Auswahl eines Befehles wird die komplette Befehlssyntax mit diversen Erläuterungen (Notes) und den jeweiligen Returncodes an der vorgesehenen Stelle eingefügt. Wird im Dateiprofil "NOTES OFF" gesetzt, werden die Erläuterungen nicht angezeigt. Soll eine andere Model-Klasse angesteuert werden als die zur Zeit aktuelle, kann diese über den Befehl "MODEL CLASS" eingestellt werden. Um einen Dialog zu testen (gleichgültig welche Komponenten aus DMS er enthält), sollte grundsätzlich die PDF-Option 7 genutzt werden, da andernfalls beispielsweise Veränderungen an Panels nicht registriert werden (ein Panel wird beim ersten Aufruf in den Adreßraum gelesen und nicht erneut von der Platte geladen, solange es im Speicher vorhanden ist). Für das Austesten eines Dialoges bieten sich an: 7.1 7.2 7.3 7.4 Select Services (Programme und Panels) Display Services (Panels und Messages) Manipulation des Profile-Variablenpools Arbeiten an DMS-Tabellen Die folgenden Seiten zeigen kurz die möglichen Anwendungen der Dialog Manager Services und deren Einbindung in REXX-Programme. Des besseren Verständnisses wegen halten wir ein 100%-iges REXX-Beispiel dagegen. Ich bitte um Nachsicht, wenn hier nicht auf alle Details eingegangen werden kann, aber es würde den Rahmen dieses Buches sprengen, und wer weiß, vielleicht gibt es in absehbarer Zeit ja auch zu diesem Thema mal ein Buch. Wird Dialog Manager in ein REXX-Programm eingebunden, bezieht sich die überwiegende Anzahl der Befehle an das Umfeld von REXX auf den Dialog Manager. Um hier nun nicht jeden einzelnen Befehl adressieren zu müssen, kann das Standardumfeld zu Dialog Manager hingestellt werden, indem der ADDRESS-Befehl auf dieses Umfeld zeigt und hinter dem Befehl keine Instruktion an das jeweilige Umfeld folgt. 368 REXX unter MVS-TSO/E REXX und DMS Variablenaustausch Erinnern Sie sich noch? Tauschen zwei REXX-Programme Daten aus kann es mitunter kompliziert werden. Unterstellen wir folgendes: PROGA übernimmt drei Variablen aus dem Startaufruf und muß sie an PROGB weiterreichen. PROGB könnte die Inhalte der Variablen, wie auch die Anzahl Worte in den Variablen verändern. Ein Beispiel mit REXX-Native möchte ich Ihnen hier ersparen. So wäre es möglich: /* REXX * PROGA *******/ address ispexec arg var1 var2 var3 . /* Verarbeitung (Variablenmanipulationen wären denkbar */ "vput (var1 var2 var3) shared" call progb "vget (var1 var2 var3) shared" /* Weitere Verarbeitung von PROGA */ exit /* REXX * PROGB *******/ address ispexec "vget (var1 var2 var3) shared" /* Verarbeitung (Variablenmanipulationen wären denkbar */ "vput (var1 var2 var3) shared" return Sich Werte über LOGOFF hinaus festzuhalten, ist auch kein Problem. Nehmen wir an, ein Programm muß wissen, zum wievielten Mal es läuft: /* REXX * PROGB *******/ address ispexec "vget (runcnt) profile" if length(runcnt) = 0 then runcnt = 0 runcnt = runcnt + 1 "vput (runcnt) profile" : Formatierte Bildschirm-Ein-/Ausgaben Sehr lästig in REXX-Native ist die Aufbereitung von Bildschirmdaten. Sei es, weil man nicht in der Lage ist, Eingaben hinter einem erklärenden Text zu ermöglichen (PARSE erzeugt einen Zeilentransport), oder daß es nicht möglich ist, eine Zeilen-/ Spalten-Koordinate am Terminal anzusteuern (gerade bei Eingabewiederholung we- Anhang - B 369 REXX und DMS gen Falscheingaben wäre dies sehr angenehm). Prüfungen diverser Eingaben verlangen unter REXX eine oft komplexe Logik und verkomplizieren das Programm beim ersten Hinsehen ganz enorm. Sehen wir uns kurz an, was Dialog Manager an dieser Stelle in Form der Datenpanels (Bildschimmasken) zu bieten hat. Ein Panel ist die programmierte Form der Bildschirmmaske, die für den Anwender sichtbar wird. Es wird in mehrere Bereiche untergliedert, von denen nur )BODY und )END zwingend kodiert werden müssen. Alle anderen Bereiche sind wahlfrei. Abhängig vom gewünschten Ergebnis wird entschieden, ob sie kodiert werden oder nicht. Wir wollen uns hier im Überblick ansehen, aus welchen Sektionen ein Panel bestehen kann. Die Reihenfolge ist bindend. )ATTR Bestimmt Attributszeichen, die im )BODY-Teil umgesetzt werden (Feldtypen, Farben, etc). )BODY Beschreibt das Aussehen der Bildschirmmaske )MODEL Wird nur in Tabellenpanels benötigt und beschreibt die Abbildung eines Tabellensatzes. )AREA bereichsname Beschreibt einen Bereich, den man als "Maske innerhalb der Maske" bezeichnen und innerhalb dessen mit den SCROLL-Tasten UP und DOWN geblättert werden kann. )INIT Enthält Instruktionen, die vor Anzeige des Panels ausgeführt werden. )REINIT Diese Section wird durchlaufen, bevor nach Erkennen eines Fehlers im )PROC-Teil, der )BODY-Teil aufs neue angesteuert wird. )PROC Wird durchlaufen, wenn der Bediener E drückt. Hier werden Plausibilitätsprüfungen der )BODY-Felder durchgeführt. Ist alles OK, wird das Panel über )END verlassen. )HELP Hier werden feldbezogene HELP-Panels definiert. )END Panelende. Diese Section kennt keine weiteren Angaben. 370 REXX unter MVS-TSO/E REXX und DMS Die Verarbeitung des Panels geschieht nicht in linearer Reihenfolge und wird in der folgenden Graphik verdeutlicht: Panelaufruf aus Programm INIT Vorlauf BODY aufbereiten und am Terminal anzeigen REINIT Aktualisierung Warten auf ENTER oder PFK PROC ohne Beanstandung zurück zum Programm, sonst REINIT Anhang - B 371 REXX und DMS Ohne nun im Detail auf das Panel eingehen zu wollen, versuchen wir eine Lösung mit und ohne Dialog Manager. Setzen wir folgendes voraus: In Schleife soll eine Terminaleingabe für die Erfassung eines Datensatzes ermöglicht werden. Dabei sollen die Inhalte folgenden Felder erfaßt werden: Feldname Länge Feldprüfungen NAME 25 Ist zwingend anzugeben und darf weder Zahlen noch Sonderzeichen enthalten. VNAME 20 Ist wahlfrei. Wird das Feld gefüllt, darf es weder Zahlen noch Sonderzeichen enthalten. KURZ 4 Muß angegeben werden (Großbuchstaben). TELINT 4 Pflichtfeld, numerisch zwischen 1000 und 9999. ABT 4 Muß angegeben werden und einer der folgenden großgeschriebenen Werte sein: GL, PERS, PLAN, PROD, EXP LAND 3 Wahlfrei. Wenn angegeben, muß es aus Buchstaben bestehen und großgeschrieben sein. PLZ 7 Wahlfrei. Wird das Feld gefüllt, muß es numerisch sein. ORT 25 Siehe LAND. STR 25 Wahlfrei. TELEXT 15 Wahlfrei. Lassen wir es dabei. Versuchen wir auch ohne Dialog Manager etwas Komfort für unseren Anwender zu liefern. Wird beispielsweise ein Eingabefehler im Abteilungsfeld erkannt, sollte der Bediener nicht wieder bei der Erfassung des Namensfeldes beginnen müssen. Um es nicht zu übertreiben, verzichten wir auf der REXX-Seite auf detaillierte Fehlernachrichten, wenn ein Eingabefehler erkannt wurde. Daß bei Falscheingabe und Eingabewiederholung REXX-seitig immer zwei zusätzliche Bildschirmzeilen benötigt werden, wollen wir dem Interpreter hier auch nicht ankreiden. Sehen wir uns zunächst mal die REXX-pur-Lösung unkommentiert an: 372 REXX unter MVS-TSO/E REXX und DMS /* REXX *********************************************/ do forever clear say center("< Erfassen Mitarbeitersatz >",79,"-") say;say; do until length(name) > 0 & char_chk(name) = "OK" say "Name? (nur Buchstaben, ENTER=Programmende)" parse external name if length(name) = 0 then exit end do until length(vname) = 0 ! char_chk(vname) = "OK" say "Vorname? (nur Buchstaben, Angabe wahlfrei)" parse external vname end do until length(kurz) = 4 say "Kurzzeichen? (4-stellig)" parse upper external kurz end do until telint >= 1000 & telint <=9999 say "Telefon Intern? (1000 bis 9999)" parse external telint end telint=trunc(telint) do until wordpos(abt,"GL PERS PLAN PROD EXP") > 0 say "Abteilung? (GL, PERS, PLAN, PROD oder EXP)" parse upper external abt end do until length(land) = 0 ! char_chk(land) = "OK" say "Land? (nur Buchstaben, Angabe wahlfrei)" parse upper external land end do until length(plz) = 0 ! char_chk(plz,n) = "OK" say "Postleitzahl? (numerisch, Angabe wahlfrei)" parse external plz end do until length(ort) = 0 ! char_chk(ort) = "OK" say "Ort? (nur Buchstaben, Angabe wahlfrei)" parse external ort end Anhang - B 373 REXX und DMS say "Strasse? (Angabe wahlfrei)" parse external str say "Telefon privat? (Angabe wahlfrei)" parse upper external telext end exit /* UPROG CHAR_CHK ***********************************/ /* Prueft Feldinhalt auf Buchstaben oder Zahlen */ char_chk:procedure arg parm,typ msg="OK" if length(parm) > 0 then do if typ = "N" then good="0123456789" else good="ABCDEFGHIJKLMNOPQRSTUVWXYZ" if verify(parm,good) > 0 then msg="Falsche Zeichen" end return msg Sehen wir uns zunächst die Optik an, mit der sich die Bildschirmmaske des Dialog Managers präsentieren wird (verzeihen Sie das Fehlen der Farben): Erfassen Mitarbeitersatz Command ==> Name....: ......................... Vorname.: ......................... Kurz-Z..: Land....: PLZ/Ort.: Strasse.: .... TEL intern: .... Abteilung: .... ... .... ......................... ......................... TEL priv: ............... ENTER = Satz erfassen, END Programmende 374 REXX unter MVS-TSO/E REXX und DMS Und nun zum Vergleich die REXX-Seite mit Einsatz eines Panels: /* REXX *********************************************/ address ispexec "display panel(erfass)" do while RC = 0 "display panel(erfass)" end exit Hierzu ein paar erklärende Bemerkungen: Der erste Befehl im Programm wechselt das Standardumfeld von TSO zu Dialog Manager. Aus diesem Grund müssen wir die Dialog-Manager-Befehle im Programm nicht mehr explizit adressieren. Der DisplayService ruft die Bildschirmmaske auf und erhält die Steuerung über den weiteren Ablauf. Der Service kann über zwei Aktionen beendet werden: Der Anwender drückt die END-Taste (der Service meldet Returncode 8), oder er drückt E und alle im )PROC-Teil liegenden Prüfungen enden gut (der Service meldet Returncode 0). Wird bei einer Prüfung im )PROC-Teil ein Fehler erkannt, behält der Service die Kontrolle. Der )REINIT-Teil wird angesprungen. Dort wird das Attribut des fehlerverursachenden Feldes auf ROT-LEUCHTEND gesetzt. Der Cursor wird in das entsprechende Feld gesetzt und eine Fehlernachricht erscheint in der obersten Zeile des Bildschirmes außen rechts (Wir alle kennen dieses Verfahren aus PDF. PDF ist mit den Werkzeugen des Dialog Managers (auch ISPF) programmiert). Gelingt es dem Anwender, alle Felder der Maske richtig auszufüllen und das Panel mit E zu verlassen, liegen im Variablenbereich unseres REXX-Programmes die entsprechenden Variablen vor. Da bei Returncode 0 des Services alle Prüfungen im Panel erfolgreich absolviert wurden, brauchen wir uns um die Inhalte der Variablen unter REXX nicht mehr weiter zu kümmern. Liefert der DISPLAY-Service die 0, ist alles OK. Anhang - B 375 REXX und DMS Das Panel selbst sieht folgendermaßen aus: )ATTR DEFAULT(!+_) [ TYPE(TEXT) CAPS(OFF) COLOR(TURQ) ] TYPE(TEXT) CAPS(OFF) COLOR(YELLOW) $ TYPE(INPUT) CAPS(OFF) COLOR(YELLOW) PADC('.') § TYPE(INPUT) CAPS(ON) COLOR(YELLOW) PADC('.') )BODY EXPAND(\\) +\ \Erfassen Mitarbeitersatz\ \ +Command ==>_ZCMD + [Name....: $name + [Vorname.: $vname + [ [Kurz-Z..: §kurz[ TEL intern:$z [ Abteilung:§abt + [Land....: §z + [PLZ/Ort.: §plz [$ort + [Strasse.: $str + [ [TEL priv: $telext + [ [ ENTER = Satz erfassen, ]END[ Programmende )INIT .zvars='(telint land)' )REINIT .attr(.cursor)='color(red) intens(high)' )PROC ver (&name,nb,alphab) ver (&vname,alphab) ver (&kurz,nb) ver (&telint,nb,range,1000,9999) ver (&abt,nb,list,GL,PERS,PLAN,PROD,EXP) ver (&land,alphab) ver (&plz,num) ver (&ort,alphab) )END In dieser Form hätte das Panel ein kleines Manko. Wird es in Schleife immer wieder aufgerufen, werden die eingegebenen Werte vom jeweils letzten Durchlauf in den 376 REXX unter MVS-TSO/E REXX und DMS einzelnen Feldern wieder vorgelegt (dies kann natürlich in bestimmten Situationen auch gewollt sein). Wir könnten zwingend für leere Felder sorgen, indem wir alle Felder im )INIT-Teil auf Blank setzen. Wir werden dieses Problem später anders lösen. Die nächste Aufgabe wäre nun, aus den empfangenen Variablen einen Datensatz zu bilden und wegzuschreiben. Mit Dialog Manager gehen wir davon aus, daß eine Tabelle existiert, die namensgleiche Felder zu jeder Variablen führt. Im puren REXXBeispiel unterstellen wir, daß eine Datei PERSONAL.DIVERS.DATA mit Satzlänge 132 existiert, in die unsere erfaßten Daten im Mitglied MA fortgeschrieben werden. Ergänzen wir das pure REXX-Programm: /* REXX *********************************************/ "newstack" "alloc dd(ma) da('personal.divers.data(ma)') shr reuse" if sysdsn("'personal.divers.data(ma)'")="OK" then "execio * diskr ma (finis" do cnt=1 clear say center("< Erfassen Mitarbeitersatz >",79,"-") say;say; do until length(name) > 0 & char_chk(name) = "OK" say "Name? (nur Buchstaben, ENTER=Programmende)" parse external name if length(name) = 0 then leave cnt end do until length(vname) = 0 ! char_chk(vname) = "OK" say "Vorname? (nur Buchstaben, Angabe wahlfrei)" parse external vname end do until length(kurz) = 4 say "Kurzzeichen? (4-stellig)" parse upperexternal kurz end do until telint >= 1000 & telint <=9999 say "Telefon Intern? (1000 bis 9999)" parse external telint end telint=trunc(telint) do until wordpos(abt,"GL PERS PLAN PROD EXP") > 0 Anhang - B 377 REXX und DMS say "Abteilung? (GL, PERS, PLAN, PROD oder EXP)" parse upper external abt end do until length(land) = 0 ! char_chk(land) = "OK" say "Land? (nur Buchstaben, Angabe wahlfrei)" parse upper external land end do until length(plz) = 0 ! char_chk(plz,n) = "OK" say "Postleitzahl? (numerisch, Angabe wahlfrei)" parse external plz end do until length(ort) = 0 ! char_chk(ort) = "OK" say "Ort? (nur Buchstaben, Angabe wahlfrei)" parse external ort end say "Strasse? (Angabe wahlfrei)" parse external str say "Telefon privat? (Angabe wahlfrei)" parse upper external telext satz=left(name,25)!!left(vname,20)!!left(kurz,4) satz=satz!!left(telint,4)!!left(abt,4)!!left(land,3) satz=satz!!left(plz,7)!!left(ort,25)!!left(str,25) satz=satz!!left(telext,15) queue satz end queue "execio * diskw ma (finis" exit /* UPROG CHAR_CHK ***********************************/ /* Prueft Feldinhalt auf Buchstaben oder Zahlen */ char_chk:procedure arg parm,typ msg="OK" if length(parm) > 0 then do if typ = "N" then good="0123456789" else good="ABCDEFGHIJKLMNOPQRSTUVWXYZ" if verify(parm,good) > 0 then msg="Falsche Zeichen" end return msg 378 REXX unter MVS-TSO/E REXX und DMS Die Ergänzung der DMS-Variante sieht folgendermaßen aus: /* REXX *********************************************/ address ispexec "tbopen ma write" "tbvclear ma" "display panel(erfass)" do while RC = 0 "tbadd ma" "tbvclear ma" "display panel(erfass)" end "tbclose ma" exit Hat was für sich, oder? Ohne Aufwand könnte geprüft werden, ob der Satz eingetragen werden soll oder nicht, weil er unter Umständen bereits existiert. Läge die Tabelle sortiert vor, könnte der Satz gemäß der Sortfolge eingetragen werden. Auf diese und ähnliche Dinge verzichten wir an dieser Stelle, da gleiches unter REXX-pur ein gigantischer Aufwand wäre und wir hier nur erkennen sollten, wie schön die Einbindung von DMS ist. Nur noch soviel: Wir würden neben dem Erfassen eines Datensatzes noch Bedarf an Funktionen wie Anzeige, Löschen und Ändern eines Datensatzes haben. In REXX-pur wären diese Funktionen über eigene Programme zu lösen. Die DMS-Lösung würde im wesentlichen darin bestehen, das Datenpanel so intelligent zu machen, daß es erkennen kann, ob es für erfassen, ändern, zeigen oder löschen eingesetzt werden soll. Das Programm im Hintergrund, das dann entsprechend alles kann, wäre etwa eine gute halbe Seite lang. Wenn wir nun den Inhalt unserer Daten ansehen wollten, wäre REXX-pur das SHOWProgramm aus Kapitel 2 hilfreich. Zur besseren Gegenüberstellung zeigen wir es hier noch einmal: /* REXX *********************************************/ "alloc dd(les) da('PERSONAL.DIVERS.DATA(MA)') shr reuse" "execio * diskr les (stem satz. finis" "free dd(les)" x=1 do forever clear say center('< Anzeige Mitarbeiter >',79,'-');say do y=x to x+17 Anhang - B 379 REXX und DMS say right(y,4,0)'..'left(satz.y,73,) if y >= satz.0 then leave end say;say 'F<oreward> B<ack> E<nd>' do until ant = 'F' ! ant = 'B' ! ant = 'E' pull ant end select when ant='F' then x=y-1 when ant='B' then do x=y-35 if x < 1 then x=1 end otherwise leave end end exit Alternativ dazu die DMS-Variante. Hier wollen wir zunächst im Überblick die Abteilung, das Kurzzeichen, die interne Telefonnummer, Namen und Vornamen zeigen. Die Anzeige wird vergleichsweise wie im Edit aussehen. Mit den SCROLL-Tasten kann vor- und rückwärts geblättert werden. Wie im Edit kann das SCROLL-Amount verändert werden. Wir legen aber noch eins drauf. Die angezeigte Datei kann nach Name, Kurzzeichen oder Abteilung sortiert werden. Scannen von Datensätzen wäre auch keine große Sache, aber irgendwo muß ja mal Schluß sein. Zunächst das Tabellen-Anzeigepanel: )ATTR DEFAULT(!+_) { TYPE(OUTPUT) CAPS(OFF) COLOR(TURQ) )BODY EXPAND(\\) +\ \Anzeige Mitarbeiterdaten\ \ +Command ==>_ZCMD \ \ +SCROLL ==>_SAMT+ + +ABT KURZ TEL Name )MODEL {ABT {KURZ {Z {Name )INIT .ZVARS='(TELINT)' IF (&SAMT,=,&Z) &SAMT='PAGE' )END Vorname {vname 380 REXX unter MVS-TSO/E REXX und DMS Das REXX-Programm für die Steuerung des Ablaufes sieht dann so aus: /* REXX *********************************************/ address ispexec "tbopen ma nowrite" "tbdispl ma panel(tbanz)" do while RC <= 4 if translate(word(zcmd,1))="SORT" then call sort "tbdispl ma panel(erfass)" end "tbclose ma" exit /* Subroutine SORT * Sortierung der DMS-Tabelle ******/ SORT: sk=translate(word(zcmd,2)) select when sk="ABT" then fld="ABT,C,A,NAME,C,A,VNAME,C,A" when sk="KURZ" then fld="KURZ,C,A,NAME,C,A" when sk="NAME" then fld="NAME,C,A,VNAME,C,A,ABT,C,A" when sk="VNAME" then fld="VNAME,C,A,NAME,C,A,ABT,C,A" otherwise do "setmsg msg(err001a)" return end end "tbsort ma fields("sk")" return In der Praxis würde das Panel geringfügig erweitert und vor jedem gezeigten Datensatz ein Eingabefeld positioniert werden. Diese Eingabefelder könnten wie im Edit als Zeilenbefehlsfelder eingesetzt werden. Wollte der Anwender nun einen Satz anschauen, löschen, ändern oder einfügen, müßte er nur ein vereinbartes Kürzel vor den Datensatz schreiben. Als nächstes wollen wir versuchen, Datensätze aufgrund bestimmter Kriterien zu suchen. REXX-native wollen wir unsere Anforderungen etwas zurückschrauben. Das Programm sollte einen Datensatz finden können, wenn der Anwender Name, Vorname, Abteilung und/oder Kurzzeichen vorgibt. Werden zu einem Kriterium keine Angaben gemacht, soll es bei der Suche nicht berücksichtigt werden. Wie gehabt, zunächst die Lösung REXX-pur: Anhang - B 381 REXX und DMS /* REXX *********************************************/ "alloc dd(les) da('PERSONAL.DIVERS.DATA(MA)') shr reuse" "execio * diskr les (stem satz. finis" "free dd(les)" do forever clear say center('< Datensuche >',79,'-');say say "Name (oder Namensbeginn, *=ENDE)" parse external name if name="*" then leave say "Vorname (oder Vornamensbeginn)" parse external vname say "Abteilung (oder Beginn der Abteilung)" parse upper external abt say "Kurzzeichen (oder Beginn des Kurzzeichens)" parse upper external kurz c_found=0 do x=1 to satz.0 select when length(name) > 0 & , name >< left(satz.x,length(name)) then nop when length(vname) > 0 & , vname >< substr(satz.x,26,length(vname)) , then nop when length(kurz) > 0 & , kurz >< substr(satz.x,46,length(kurz)) , then nop when length(abt) > 0 & , abt >< substr(satz.x,54,length(abt)) , then nop otherwise do say left(satz.x,79) c_found=c_found + 1 end end end say "Saetze gefunden:" c_found " weiter mit ENTER" parse external dmy end exit 382 REXX unter MVS-TSO/E REXX und DMS Die DMS-Variante nutzt zur Abfrage nach den Suchkriterien ein kleines Panel. Für die Anzeige gefundener Datensätze nutzen wir das Datenpanel von Seite 373 (Wir könnten erreichen, daß das Panel bei Datenanzeige keine beschreibbaren Felder führt. Aber lassen wir das). Das Panel zur Kriterienabfrage sähe so aus: )ATTR DEFAULT(!+_) [ TYPE(TEXT) CAPS(OFF) COLOR(TURQ) ] TYPE(TEXT) CAPS(OFF) COLOR(YELLOW) $ TYPE(INPUT) CAPS(OFF) COLOR(YELLOW) PADC('.') § TYPE(INPUT) CAPS(ON) COLOR(YELLOW) PADC('.') )BODY EXPAND(\\) +\ \Suchkriterien für Mitarbeitersätze\ \ +Command ==>_ZCMD + [Name.....:$name + [Vorname..:$vname + [ [Kurz-Z...:§kurz+ [Abteilung:§abt + [ [ ENTER = Satz suchen, ]END[ Programmende )END Hier kommt uns zugute, was im Dialog Manager GENERIC SEARCH heißt. Wird im Namensfeld beispielsweise Me* eingetragen, ist der Vergleich positiv, sofern das entsprechende Tabellenfeld mit Me beginnt. Das Steuerprogramm folgt: /* REXX *********************************************/ address ispexec "tbopen ma nowrite" do forever "display panel(show)" if rc = 8 then leave "tbsarg ma" "tbscan ma" do while RC = 0 "display panel(erfass)" "tbscan ma" end "tbvclear ma" end exit Anhang - B 383 REXX und DMS In unserem Beispiel gehen wir bei der Selektion der Datensätze immer von einer Übereinstimmung mit den Suchkriterien aus. Es ist selbstverständlich auch möglich, für die Selektion Vergleichsoperationen wie UNGLEICH, GRÖSSER, KLEINER und all die anderen zu nutzen. Anders als im Beispiel benötigen wir dann keinen TBSARG-Befehl, dafür aber einen anders aufgebauten TBSCAN. Sehen wir uns ein kleines Beispiel für Job-Control-Verarbeitung über den File-Tailoring-Service des Dialog Managers an. Als Basis zunächst nochmal das Beispiel aus Kapitel 2, wobei wir auf die Prüfung der Attribute der Eingabedatei verzichten wollen. /* REXX * JCLPRT1 ***********************************/ CLEAR dmy=msg("OFF") say 'Abrechnungsnummer (JOB-ACCOUNT) angeben:' pull actnum do forever say 'Druckdatei vollqualifiziert (ENTER = Ende)' pull datei if length(datei) = 0 then exit if sysdsn("'"datei"'") = "OK then leave say 'Datei nicht verfuegbar, Eingabe wiederholen." end say 'Ausgabeklasse angeben (A, R oder X - ENTER=X)' pull okl if okl >< 'A' & okl >< 'R' then okl='X' if okl = "A" then do say "JES-Local-Drucker (ENTER = SPOOL)" pull rmt if length(rmt) > 0 then okl = okl",DEST="rmt end say 'Druckzeilen je Seite (40 bis 72, ENTER = 60):' pull zeilen if zeilen < 40 ! zeilen > 72 then zeilen=60 say 'Anzahl Exemplare (1 - 99, ENTER = 1):' pull anz_ausg if anz_ausg < 1 ! anz_ausg > 99 then anz_ausg = 1 "newstack" name=userid()!!substr(time(),8,1) queue "//"name" JOB ("actnum"),NOTIFY="userid() queue "/*JOBPARM LINECT="zeilen 384 REXX unter MVS-TSO/E REXX und DMS queue "//DRUCK EXEC PGM=IEBGENER" queue "//SYSUT1 DD DSN="datei",DISP=SHR" queue "//SYSUT2 DD SYSOUT="okl",COPIES="anz_ausg queue "//SYSIN DD DUMMY" queue "//SYSPRINT DD DUMMY" queue "XX" "submit * end(XX)" say 'Job' name 'gestartet um' substr(time(),1,5) "delstack" exit Mit Dialog Manager setzen wir voraus, daß die folgende Job-Control im Mitglied GENPRT einer Datei vorliegt. Dieses Mitglied ist dem Dialog Manager unter dem DDNamen ISPSLIB bekannt ist. //&zuser.1 JOB (&zactnum),NOTIFY=&zuser /*JOBPARM LINECT=&zeilen //DRUCK EXEC PGM=IEBGENER //SYSUT1 DD DSN=&datei,DISP=SHR //SYSUT2 DD SYSOUT=&okl,COPIES=&ausg //SYSIN DD DUMMY //SYSPRINT DD DUMMY Dann brauchen wir natürlich ein Panel zur Datenerfassung: )ATTR DEFAULT(!+_) )BODY EXPAND(\\) +\ \JCL-Druckausgabe\ \ +Command ==>_ZCMD + +Druckdatei.....: _datei + +Zeilen je Seite: _z+ (40 bis 65) +Outputklasse...: _z+ (A, R, oder X) +Local Printer..: _rmt + (nur bei Outputklasse A) +Anzahl Ausgaben: _z + (maximal 99) + + + ENTER = Start JCL, !END+ Programmende )INIT .zvars='(zeilen okl ausg)' Anhang - B 385 REXX und DMS if (&first,=,1) &datei=&z &zeilen=60 &okl='R' &rmt=&z &ausg=1 )PROC ver (&datei,nb) ver (&zeilen,range,40,65) ver (&okl,LIST,A,R,X) if (&okl,EQ,A) if (&rmt,NE,&z) &okl=&okl.,DEST=&rmt else )END Das REXX-Programm zur Steuerung des Ganzen wäre wie folgt: /* REXX * JCLPRT1 ***********************************/ address ispexec first=1 do forever "display panel(jclprt)" if RC = 8 then exit if sysdsn("'"datei"'") = "OK" then leave first=0 "setmsg msg(err003a)" end "ftopen" "ftincl genprt" "ftclose name(tmpprt)" edit dataset(mvs.skels(tmpprt))" address tso "del mvs.skels(tmpprt)" exit Es ist schwierig, den richtigen Zeitpunkt zum Aufhören zu finden. Mit Dialog Manager gerät man immer ins Schwärmen. Ich hoffe, es ist erkennbar, welch gewaltiges Werkzeug sich hinter Dialog Manager verbirgt. Mehr war nicht gewollt und ist an dieser Stelle auch nicht möglich. 386 REXX und DMS REXX unter MVS-TSO/E 387 Anhang - C REXX und Edit-Macros 388 REXX und Edit-Macros REXX unter MVS-TSO/E Anhang - C 389 REXX und Edit-Macros Edit-Macros bilden eine ideale Ergänzung zur Leistungsfähigkeit des PDF-Editors. Über kleine Programme läßt sich der Befehlsumfang des Editors beliebig ergänzen Auch hier bietet sich REXX als steuerndes Element an. Ein Edit-Macro muß, damit es gefunden werden kann, als Mitglied der SYSPROC/SYSEXEC-Verkettung hinterlegt werden. Das Macro kann unter seinem Mitgliedsnamen wie ein Befehl in der COMMAND-Zeile des Editors aufgerufen werden. Die erste Befehlszeile im Macro muß ein Hinweis sein, daß es sich hierbei um ein Macro handelt. Auch hier wollen wir nicht auf die Details der Macrosyntax eingehen oder die einzelnen Macrobefehle aufzählen. Sehen wir uns drei Beispiele an und lassen diese für sich selbst sprechen. Das erste Beispiel erstellt ein Profil, wie ich es am liebsten unter Edit habe. Unabhängig von den aktuellen Einstellungen des Profiles werden diverse Änderungen am Profil des Editors durchgeführt. Nachdem die Profilwerte gesetzt wurden, wird eine Nachricht in der ersten Zeile des Editors außen rechts ausgegeben und mitgeteilt, ob das Profil dauerhaft (sofern es nicht gesperrt war) oder temporär für die Edit-Session geändert wurde. /* REXX * EDIT MACRO ***********************************/ /* */ /* Macroname.: $STDPROF */ /* Zweck.....: Erzeugt Standard-Profil */ /* */ /* Erstellt..: 01.94 Wittemann */ /* */ /* Geaendert.: mm.jj name grund */ /* address isredit "macro" "(lockmode) = profile" In der Variablen LOCKMODE wird der Lockmodus des Profiles (LOCK oder UNLOCK) hinterlegt. "autolist off" "autonum off" "autosave on" "caps off" "hex off" "nulls on" "number off" 390 REXX unter MVS-TSO/E REXX und Edit-Macros "recovery on" "stats on" "tabs off" Die diversen Arbeitsmodi des Editors werden auf bestimmte Aussagen gesetzt. if lockmode = "UNLOCK" then do status = "mit Standardwerten gespeichert" end Sofern das PROFILE nicht gesperrt ist (UNLOCK), wird es bei Verlassen des Editors über die Funktion END zusammen mit den Daten abgespeichert. Dementsprechend wird in der Longmessage ein Hinweis ausgegeben. else status = "temporaer veraendert" Ist das PROFILE gesperrt (LOCK), wird der Hinweis auf temporäre Veränderung ausgegeben. zedsmsg="Profile O.K." zedlmsg="Profile" status address ispexec "setmsg msg(isrz000)" Die vorbereitete Nachricht wird im Editpanel ausgegeben. exit Das zweite Beispiel ermittelt den Datei- und Membernamen, in dem editiert wird und führt mit diesen Informationen den TSO-EXEC-Befehl aus. Dieses Macro ist sehr hilfreich, wenn die Datei, in der editiert wird, nicht unter SYSPROC/SYSEXEC verkettet ist und erspart das immer wiederkehrende Eingeben des Befehles (ist ja ziemlich lang - spare jede Kalorie, die möglich ist). /* REXX * EDIT MACRO ***********************************/ /* */ /* Macroname.: $RUN */ /* Zweck.....: Ermittelt den Membernamen, fuehrt */ /* den TSO-EXEC-Befehl aus */ /* */ /* Erstellt..: 01.94 Wittemann */ /* */ /* Geaendert.: mm.jj name grund */ /* */ address isredit Anhang - C 391 REXX und Edit-Macros "macro (params)" Erlaubt dem Macro Parameter beim Startaufruf zu übernehmen. So können Startinformationen, die auf diese Weise übernommen werden, beim Programmstart über den TSO-EXECBefehl an das REXX-Programm oder die CLIST weitergegeben werden. "(dsn) = dataset" Die Variable DSN enthält den vollqualifizierten Namen der Datei, in der das aktive Programm Mitglied ist. "(mem) = member" Die Variable MEM enthält den Mitgliedsnamen des PO-Members, in dem gerade editiert wird (REXX-Programm oder CLIST). address tso "ex '"dsn"("mem")' '"params"' EXEC" Im TSO-Hintergrund wird das Mitglied zur Ausführung gebracht. Sofern das Macro über PARAMS Daten empfangen hat, werden diese als Parameter an das zu startende Programm übergeben. exit Im dritten Beispiel haben wir einen Helfer vor uns, der sehr häufig zum Einsatz kommt. Es ist sinnvoll, vor Start eines jedem Programmes einen kleinen Programmkopf zu kodieren, in dem die wichtigsten Informationen zum Programm stehen, wie Autor, Erstellungsdatum, Zweck des Programmes, und dergleichen mehr. Das Macro liefert das Grundgerippe, wenn in der COMMAND-Line des Editors $HEAD getippt wird. /* REXX * EDIT /* /* Macroname.: /* Zweck.....: /* /* /* /* /* /* /* /* /* /* /* MACRO ********************************/ */ $HEAD */ Einfuegen des Programmkopfes am */ Dateianfang. Das Macro prueft den */ Dateinamen und schreibt davon ab*/ hängig unterschiedliche Kopfzeilen */ */ ?.MACRO.CLIST * CLIST * EDIT MACRO */ ?.MACRO.EXEC * REXX * EDIT MACRO */ ?.?????.CLIST * CLIST * PROGRAMM */ ?.?????.EXEC * REXX * PROGRAMM */ */ Monat/Jahr der Erstellung werden aus */ dem Systemdatum gesetzt. Als Pro*/ 392 REXX unter MVS-TSO/E REXX und Edit-Macros /* grammname wird der Membername einge/* setzt. Die ersten Statements /* werden in Abhaengigkeit gesetzt: /* /* CLIST MACRO: /* ISREDIT MACRO (TEST) /* ISPEXEC CONTROL ERRORS CANCEL /* IF &TEST = T THEN DO /* CONTROL CONLIST /* ISPEXEC CONTROL ERRORS RETURN /* END /* CLIST PGM: /* PROC 0 DEBUG /* IF &DEBUG = T THEN CONTROL CONLIST /* REXX MACRO: /* ADDRESS ISREDIT /* "MACRO (TEST)" /* IF TEST = "T" THEN DO /* TRACE "?R" /* ADDRESS ISPEXEC "CONTROL ERRORS RETURN" /* END /* REXX PGM: /* ARG TEST /* IF TEST = "T" THEN TRACE "?R" /* /* Erstellt..: 02.94 Wittemann /* Geaendert.: mm.jj name grund /* */ address isredit "macro" "(progname) = member" */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ */ Der Mitgliedsname des aktiven Members wird ermittelt. "(dsn) = dataset" Der Name der aktiven Datei wird der Variablen DSN zugewiesen. parse upper value dsn with project "." group "." type Die einzelnen Namensteile der Datei werden auf die Variablen PROJECT, GROUP und TYPE aufgeteilt. Anhang - C 393 REXX und Edit-Macros select when group = "MACRO" then do Ist der zweite Namensteil der Datei MACRO, wird von einem EDIT MACRO ausgegangen. Abhängig vom letzten Namensteil der Datei kann festgestellt werden, ob das Macro in CLIST, REXX oder einer anderen Sprache erstellt wurde. Davon abhängig werden die ersten Statements nach dem Kommentar und die Titelzeile erstellt. Die maximale Anzahl der im Kopf zu erzeugenden Zeilen wird bestimmt. select when type = "EXEC" then do Hier ist gesichert, daß ein REXX-EDIT-Macro erstellt werden soll. titel='REXX * EDIT MACRO' k.10='address isredit' k.11='"macro (test)"' k.12='address ispexec "CONTROL ERRORS CANCEL"' k.13='if test = "T" then do' k.14 =' trace "?r"' k.15 =' address ispexec "CONTROL ERRORS RETURN"' k.16 = 'end' k.max=16 end when type = "CLIST" then do Ein CLIST-EDIT-MACRO wird vorbereitet. titel = "CLIST * EDIT MACRO" k.10 = "ISREDIT MACRO (TEST)" k.11 = "ISPEXEC CONTROL ERRORS CANCEL" k.12 = "IF &TEST = T THEN DO" k.13 = " CONTROL CONLIST" k.14 = " ISPEXEC CONTROL ERRORS RETURN" k.15 = "END" k.max=15 end otherwise do Es soll ein EDIT-Macro in einer Sprache anders als CLIST oder REXX vorbereitet werden. titel = "????? * EDIT MACRO" 394 REXX unter MVS-TSO/E REXX und Edit-Macros k.max=9 end end /* zu SELECT Erkennung CLIST, REXX, etc. */ end /* zu WHEN zur Erkennung GROUP="MACRO" */ when type = "EXEC" then do Ein REXX-Programm wird erstellt. titel = "REXX * PROGRAMM" k.10 = "arg test ." k.11 = 'if test = "T" then trace "?r"' k.max=11 end when type = "CLIST" then do Ein CLIST-Programm wird erstellt. titel = "CLIST * PROGRAMM" k.10 = "PROC 0 DEBUG" k.11="IF &DEBUG=T THEN CONTROL CONLIST LIST MSG" k.max= 11 end otherwise do Ein Programm anderen Ursprungs wird erstellt. titel = "????? * PROGRAMM" k.max=9 end end edat=translate(right(date("E"),5),’.’,’/’) Nach EDAT werden die letzten 5 Byte des umgewandelten Datums (tt.mm.jj) übernommen (entspricht mm.jj). if pos("MACRO",titel) > 0 then pgmtyp="Macroname.:" else pgmtyp="PGM-Name..:" Kommt in der Variablen TITEL das Wort MACRO vor, wird in die Variable PGMTYP "Macroname.:", ansonsten "Programmname..:" übertragen. pname=userid() Als Programmierername wird zunächst die Benutzerkennung aus LOGON hinterlegt. if wordpos(pname,"XWIH XHZ9001") > 0 then , Anhang - C 395 REXX und Edit-Macros pname="Wittemann" Entspricht die Benutzerkennung einem der Werte in der Klammer, wird als Name "Wittemann" angenommen. k.1='/*' titel right('*/',67-length(titel),'*') k.2='/*' right('*/',68) k.3='/*' pgmtyp progname right('*/',67-length(pgmtyp progname)) k.4='/* Zweck.....: xxxxxxxxxxxxxxxxxxx' right('*/',36) k.5=k.2 k.6='/* Erstellt..:' edat left(pname,47) '*/' k.7=k.2 k.8='/* Geaendert.: mm.jj name grund' right('*/ ',34) k.9=k.2 Über die ersten neun Variablen des K-Stammes wird der Programmkopf als Kommentarblock erzeugt, wobei die erste Zeile unterschiedliche Inhalte, abhängig von den Ergebnissen der Untersuchung des Dateinamens, aufweisen kann. s_insert=0 Der Schalter S_INSERT wird auf 0 (nein) gesetzt. Über den Inhalt des Schalters kann später ermittelt werden, ob das Member leer war, und bei Macrostart zunächst eine Leerzeile eingefügt wurde. 'locate .zfirst' Die erste Zeile wird aufgesucht. if rc = 8 then do "line_after 0 = ' '" s_insert=1 Wird von LOCATE RC 8 ausgegeben, ist das Member leer. In diesem Fall wird eine Leerzeile eingefügt, und der Schalter S_INSERT auf 1 (ja) gesetzt. end Der Cursor zeigt auf die erste Datenzeile. do cnt=1 to k.max "line_before" cnt "= '"k.cnt"'" In der Schleife wird der vorbereitete K-Variablenstamm vor der ersten Datenzeile des Members eingearbeitet. end 396 REXX unter MVS-TSO/E REXX und Edit-Macros if s_insert = 1 then do "delete .zlast" "insert .zlast" Ist der Schalter S_INSERT auf 1 gesetzt (Member war bei Start des Macros leer, Zeile wurde eingefügt), wird die letzte Datenzeile (die zu Beginn eingefügte) gelöscht und eine neue letzte Zeile eingefügt, die dem Anwender als Angebot zur Dateneingabe zur Verfügung gestellt wird. end "up max" Es wird an den Dateianfang zurückverzweigt. zedsmsg="Kopf uebertragen" zedlmsg="Programmkopf am Dateianfang eingefuegt" address ispexec "setmsg msg(isrz000)" Eine Nachricht wird im Editpanel ausgegeben. exit 397 Anhang - D REXX und NetView 398 REXX und NetView REXX unter MVS-TSO/E Anhang - D 399 REXX und NetView Obwohl der Titel des Buches REXX unter MVS-TSO/E lautet, wollen wir hier doch ganz kurz auf die Möglichkeiten von REXX unter NetView eingehen. Ich bitte um Nachsicht, wenn hier nur ein kleiner Ausschnitt dessen gezeigt werden kann, was an Leistungsstärke unter REXX und NetView verborgen liegt. Im Zuge immer weiter fortschreitender Automation kann REXX als steuerndes Element in viele Automationstools integriert werden. Ob nun zur Automation Produkte von Fremdanbietern wie CANDLE eingesetzt werden, oder NetView genutzt wird, REXX ist immer dabei. Der Anreiz, REXX unter NetView einzusetzen, liegt in erster Linie in der Möglichkeit, MVS- oder VTAM-Kommandos aus einem REXX-Programm heraus abzusetzen und die Anworten auf die Befehle hin unmittelbar in das Programm zurückzuleiten und entsprechend auszuwerten. Darüber hinaus sind natürlich eine Vielzahl von Funktionen unter NetView verfügbar, die wir unter TSO nicht nutzen können (umgekehrt sind unter NetView die ganzen erweiterten TSO-Funktionen unmöglich). Sehen wir uns im Anschluß die NETVIEW-REXX-Befehle an, die wir zur Steuerung des Nachrichtenflußßes benötigen: ● FLUSHQ (Löschen der Nachrichten-Warteschlange) ● TRAPPING (Einfangen von Nachrichten) ● WAIT (Warten auf Nachrichten) ● MSGREAD (Einlesen von Nachrichten) ● GETMxxxx (Auswerten von Nachrichten) FLUSHQ Löscht die in der Nachrichtenwarteschlange stehenden Nachrichten. TRAP Beschreibt die Nachricht(en), die eingefangen werden soll(en). Dabei kann mitgeteilt werden, ob die Nachrichten gezeigt oder unterdrückt werden sollen. Unterdrückte Nachrichten werden in der Message-Queue (Nachrichten-Warteschlange) hinterlegt. 400 REXX unter MVS-TSO/E REXX und NetView WAIT Unterbricht das Programm zunächst bis zum Eintreffen einer Nachricht oder bis zum Ablauf des angegebenen Zeitintervalles. Im Anschluß an WAIT kann über die Funktion EVENT() festgestellt werden, durch welches Ereignis der Wartezustand des Programmes beendet wurde. MSGREAD Liest die eingetroffene Nachricht aus der Message-Queue und stellt sie zur Verfügung. Dabei sind über eine Reihe von NETVIEW-spezifischen Funktionen Informationen verfügbar (nachzulesen bei MSGREAD im Instruktionen-Teil). WAIT CONTINUE Bewirkt die Fortsetzung des vorausgegangenen WAIT bis zum Ablauf des vorgegebenen Zeitintervalles, sofern noch Wartezeit verfügbar oder eine Nachricht in der Message-Queue eingetroffen ist. Multiline-Messages Sind Nachrichten, die aus mehreren Textzeilen bestehen, in NETVIEW aber als eine Nachricht behandelt werden. Das erste Token dieser Nachricht ist der sogenannte Message-Identifier. Über einen Header-Message-Type kann festgestellt werden, von welcher Komponente die Nachricht kommt. Dabei bedeuten: ' Multiline-Message von NETVIEW " Multiline-Message von einem anderen IBM-Produkt = Benutzereigene Multiline-Message Über Lesebefehle kann die Nachricht verarbeitet werden. GETMSIZE Liefert die Anzahl Zeilen, die nach WAIT mit MSGREAD aus der Nachrichtenwarteschlange ausgelesen wurde und übergibt diesen Wert der angegebenen Variablen. Anhang - D 401 REXX und NetView GETMLINE Übergibt eine beliebige Zeile einer Multiline-Message, die durch MSGREAD nach WAIT aus der Nachrichtenwarteschlange gelesen wurde und stellt sie in der angegebenen Variablen zur Verfügung. GETMTYPE Hinterlegt in der angegebenen Variablen den Nachrichtentyp einer bestimmten Zeile einer Multiline-Message, die durch MSGREAD nach WAIT aus der Nachrichtenwarteschlange gelesen wurde. Die möglichen Zeilentypen sind: blank Singleline-Message C Erste Zeile einer Multiline-Message (Control) L Überschrift (maximal 2 Label-Zeilen) D Datenzeile (nicht die letzte) DE Letzte Datenzeile E Letzte Zeile (enthält keine Dateninformation) Mit diessen Instrumenten haben wir die Möglichkeit, Nachrichtenverarbeitung zu betreiben. Natürlich gibt es hierbei viele Facetten in der Programmierung. Wir wollen uns aber ein Verfahren ansehen, daß für nahezu alle Varianten gleichermaßen gut eingesetzt werden kann. Um eine Nachricht auf einen Befehl hin vernünftig auswerten zu können, ist zunächst einmal nötig, genau zu wissen, wie die Nachricht aufgebaut ist, und über welchen Nachrichtenkopf die entsprechende Meldung ausgegeben wird. Sehen wir uns hierzu zunächst einmal eine ganz simple Variante an. Über den MVS-Befehl "D A" wird eine Kurzübersicht über die Aktivitäten des Systemes ausgegeben. die Nachricht wird über den Nachrichtenvorspann IEE104I geroutet und hat folgendes Aussehen: IEE104I 14.30.34 94.108 ACTIVITY 546 JOBS M/S TS USERS SYSAS INITS ACTIVE/MAX VTAM OAS 00000 00009 00001 00009 00007 00101/00240 0000 Diese Meldung wird als ein Meldungspaket mit Multiline-Message in der Größe von drei Zeilen verschickt. Nehmen wir an, unser REXX-Programm würde über einen Automatismus gestartet (in NetView können Befehle (auch Programmstarts) in einem bestimmten Zeitintervall über die Anweisung EVERY erfolgen) und soll erkennen, ob die Anzahl der TSO-Benutzer im LOGON bereits an den Grenzwert maximaler TSO-Benutzer heranreicht. Unterstellen wir, daß eine Nachricht ausgegeben werden soll, wenn die Auslastung 90% überschreitet. Die beiden für uns wichtigen Aus- 402 REXX unter MVS-TSO/E REXX und NetView sagen stehen innerhalb der Meldung in Zeile drei im vorletzten Wort. Dieses Wort enthält nun aber beide Werte (aktive und maximale VTAM-Benutzer), die wir trennen müssen, um sie zu verarbeiten. Wenn wir davon ausgehen können, daß das Meldungsausgabeformat immer gleich ist, können wir in unserer Multiline-Message direkt auf die dritte Zeile greifen, nachdem das Paket empfangen wurde. Beispiel für eine Multiline-Message-Verarbeitung fester Größe: /** REXX ********************************************/ "trap and suppress message IEE114I" Die Falle für Nachrichten wird aufgestellt. Nachrichten mit dem Prefix IEE104I werden eingefangen. "mvs d a" Der MVS-Befehl, der die Nachricht liefern wird, wird abgesetzt. "wait for messages" Das Ereignis "Nachricht eingetroffen" wird abgewartet. "trap no messages" Es sollen keine weiteren Nachrichten mehr eingefangen werden. "msgread" Die Nachrichten-Warteschlange unseres Programmes wird ausgelesen. Die dreizeilige Nachricht ist verfügbar. "getmline msg 3" Die dritte Zeile des Nachrichtenpaketes wird der Variablen MSG zugewiesen. parse value word(msg,words(msg)-1) with akt "/" max Die Variable MSG wird aufgesplittet. Das letzte Wort der Variablen wird am Schrägstrich getrennt, was davor liegt, wird in der Variablen AKT, was dahinter liegt, in der Variablen MAX hinterlegt. Der Schrägstrich selbst wird ignoriert. prozwert= (100 / max) * akt In PROZWERT wird berechnet, wieviele Prozent der Wert in AKT zu MAX entspricht. Anhang - D 403 REXX und NetView if prozwert > 90 then do Wird erkannt, daß die Anzahl aktiver VTAM-Benutzer 90% der maximal möglichen VTAMBenutzer übersteigt, wird eine entsprechende Meldung am Terminal ausgegeben. clear say left("VTAM-Benutzer-Abfrage ",55,"*") say say akt "von" max "VTAM-Benutzern im LOGON." say prozwert"% Auslastung erreicht" say say end exit Beispiel für eine Multiline-Message-Verarbeitung , bestehend aus einem Nachrichtenpaket unterschiedlicher Größe: Nicht ganz so einfach ist es, wenn die Nachricht, auf die wir warten nicht in einem gleichbleibend großen Nachrichtenpaket geliefert wird. Wir wollen über eine MVSAbfrage die TSO-Benutzer im LOGON ermitteln und prüfen, ob ein bestimmter Benutzer im LOGON ist. Die TSO-Benutzerkennung ist bei Programmstart mit anzugeben. Natürlich gibt es in der Praxis unter Umständen andere Möglichkeiten. Wir wollen hier aber nur veranschaulichen, wie das Hantieren mit Multiline-Nachrichtenpaketen in der Nachrichtenverarbeitung aussehen kann. Der MVS-Befehl, der uns die gewünschte Nachricht liefern wird, heißt: D A,L. Sehen wir uns das Programm dazu an: /* REXX *********************************************/ /* Erstellt: 05.94 Wittemann */ /* Zweck: Prueft, ob ein Benutzer im LOGON ist */ /* */ /* Aufruf: progname userid */ /* */ clear arg user . Der Parameter, der hinter dem Programmnamen beim Aufruf des Programmes getippt wurde, wird der Variablen USER überstellt. Wurde nichts angegeben, ist die Variable USER ein Nullstring. 404 REXX unter MVS-TSO/E REXX und NetView if length(user)=0 then do do i=1 while strip(left(sourceline(i),2),"L")='/*' say left(strip(sourceline(i),"L"),55) end exit Sofern kein Parameter empfangen wurde, wird der Programmkopf ausgegeben. Der Anwender sieht dann, wie er das Programm zu bedienen hat. Nach Ausgabe der Hilfestellung wird das Programm beendet. end 'flushq' Die Nachrichtenwarteschlange des Programmes wird vorsorglich gelöscht. 'trap and suppress messages IEE104I' Die Falle für die Meldung mit dem Vorspann IEE104I wird aufgestellt. 'mvs d a,l' Der MVS-Befehl, der die Nachricht liefern wird, wird abgesetzt. 'wait for messages' Das Ereignis "Nachricht angekommen" wird abgewartet. 'trap no messages' Weitere Nachrichten sollen nicht mehr eingefangen werden. 'msgread' Die Nachrichtenwarteschlange wird ausgelesen. 'getmsize zeilen' In der Variablen ZEILEN wird hinterlegt, aus wievielen Zeilen die Multiline-Message des Befehles besteht. msg=user "nicht" Meldungstext wird vorbereitet und negativ besetzt. do idx=1 to zeilen Das Nachrichtenpaket wird Zeile für Zeile abgearbeitet. 'getmline zeil' idx Die Zeile IDX der Multiline-Message wird in die Variable ZEIL übertragen. if pos(user,zeil) > 0 then do Anhang - D 405 REXX und NetView msg=strip(delword(msg,2)) leave War die IF-Bedingung erfüllt, wurde der Name des gesuchten Benutzers in einer Nachrichtenzeile gefunden. Dementsprechend wird der Meldungstext manipuliert, die Schleife kann verlassen werden. end end Es gibt nun zwei Gründe, warum wir im Programmverlauf diese Stelle erreichen. Entweder, die komplette Multiline-Message wurde verarbeitet und der gesuchte Anwendername wurde nicht gefunden, oder wir waren bei unserer Suche erfolgreich und haben die Schleife durch LEAVE verlassen (in diesem Fall wäre das Wörtchen nicht entfernt worden). say msg 'im LOGON' exit Beispiel einer Multiline-Message-Verarbeitung mit mehreren Nachrichtenpaketen unterschiedlicher Größe. Die letzte Variante wäre eine Nachrichtenverarbeitung, bei der eine Nachricht in mehreren Abschnitten geliefert wird (mehrere Nachrichtenpakete), die zudem noch unterschiedlich und variabel in ihrer Größe sind. Auch hierzu ein Verfahren, das in den meisten Fällen gleichermaßen gut funktioniert. Um ein wenig Pep in das ganze zu bringen, gehen wir von folgender Aufgabenstellung aus: Wir wollen einen VTAMDisplay auf eine bestimmte LU absetzen. Der Zustand der LU ist festzustellen und mit Datum und Uhrzeit der Abfrage in einer bestehenden sequentiellen Datei fortzuschreiben. Achtung: Der im Programm vorkommende ALLOC-Befehl ist ein NetView-Kommando. Er sieht dem TSO-Kommando zum verwechseln ähnlich, verfügt aber im Detail über einige andere Parameter. /* REXX *********************************************/ /* Erstellt: 05.94 Wittemann */ /* Zweck: VTAM-Display auf LU. LU-Name und */ /* -Status werden mit Datum und Uhrzeit */ /* in Statistikdatei fortgeschrieben */ /* */ datei="'xwitt.statist.vtamlu'" Der Name der Datei für die Statistik-Fortschreibung wird in der Variablen DATEI hinterlegt. 406 REXX unter MVS-TSO/E REXX und NetView "flushq" "trap and suppress messages CNM272I" "alloc da("datei") mod" "wait 1 seconds for messages" "trap no messages" "msgread" "getmline msg" 1 sysdd = word(msg,2) Im NetView-ALLOC-Befehl muß kein DD-Name angegeben werden. Der DD-Name wird von NetView dynamisch vergeben und würde normalerweise am Terminal über eine entsprechende Nachricht ausgegeben werden. Der Name entspricht in der Nachricht dem zweiten Wort der ersten Zeile. Die Nachricht wird über den Nachrichtenvorspann CNM272I geroutet. Auf diese Weise können wir den dynamisch vergebenen DD-Namen von NetView in unserem Programm einfangen und ihn zu einem späteren Zeitpunkt wieder verwenden. say "GO luname" parse upper external lu Hier mal eine Variante, den LU-Namen über die Instruktion PARSE zu ermitteln. Der Anwender kann den Namen der zu prüfenden LU am Terminal eintippen. Ohne hier näher darauf eingehen zu wollen: Soll der Anwender eine Eingabe am Terminal durchführen, muß diese im Anschluß an den Befehl GO vom Anwender getippt werden (anders als unter TSO). if length(lu)=0 then signal ende Endlich haben wir auch mal eine Anwendung für den Sprungbefehl. Wurde Nullstring empfangen, hat eine VTAM-Anfrage keinen Sinn. Trotzdem wäre es falsch, das Programm an dieser Stelle unmittelbar zu beenden. Um die bereits zugewiesene Datei und den dazugehörenden DD-Namen wieder freigeben zu können, führen wir einen Sprung zum Programmende durch, wo diese Dinge geregelt werden. In dieser Form ist nichts gegen SIGNAL einzuwenden. "flushq" Löschen der Nachrichtenwarteschlange. "trap and suppress messages IST*" Die Nachrichten, die eingefangen werden sollen, werden über mehrere Nachrichtenpakete geliefert. Alle diese Nachrichtenpakete haben unterschiedliche Prefixe. Wir bauen unsere Falle deshalb über IST* auf. Das heißt, alle Nachrichten, deren Prefix mit IST beginnt, gleichgültig, wie der genaue Prefix lautet, werden eingefangen. "d net,id="lu Der VTAM-Befehl, der uns die Information bringen soll, wird abgesetzt. wait 2 seconds Auch hier mal eine andere Variante. Wir warten 2 Sekunden, bevor das Programm weiterläuft. In dieser Zeit kann VTAM die Nachrichten auf unsere Abfrage hin zurückliefern. Anhang - D 407 REXX und NetView "trap no messages" Weitere Nachrichten sollen nicht mehr eingefangen werden. s_fehler=0 Ein Fehlerschalter wird auf NEIN gesetzt. do forever In einer Endlosschleife werden die einzelnen Nachrichten-Päckchen über MSGREAD aus der Nachrichtenwarteschlange ausgelesen. "msgread" if rc > 0 then leave War der Returncode des MSGREAD-Befehles größer 0, waren keine Nachrichtenpakete mehr in der Nachrichtenwarteschlange. Die Schleife kann verlassen werden. if msgid() = "IST453I" then do txt="Falsche Angabe, LU unbekannt" fehler=1 leave Wird ein Nachrichtenpäckchen mit dem Prefix IST453I erkannt, war der Name der gesuchten LU in VTAM nicht bekannt. In diesem Fall aktivieren wir den Fehlerschalter und springen aus der Schleife. end "getmsize zeilen" Befinden wir uns immer noch hier, wird die Größe des gelesenen Nachrichtenpaketes festgestellt und der Variablen ZEILEN übergeben. do i=1 to zeilen "getmline zeil" i Die einzelnen Zeilen der Multiline-Message werden der Reihe nach aus der Nachrichtenwarteschlange genommen und überprüft. if word(zeil,1)="IST486I" then do txt=translate(date('E'),'.','/') '-' , left(time(),5) '--- LU-Name:' lu ' subword(zeil,2) leave ' , Ist das erste Wort einer Zeile der Hinweis IST486I, wird in dieser Zeile der Status der LU ausgegeben. Wir bauen uns eine Variable auf, welche die LU, deren Status, Datum und Uhrzeit (in gut lesbarer Form) enthält. Nachdem unsere Suche erfolgreich war, können wir die Programmschleife an dieser Stelle ebenfalls verlassen. 408 REXX unter MVS-TSO/E REXX und NetView end end end if s_fehler=0 then do say lu 'gefunden' queue txt address mvs "execio 1 diskw" sysdd "(finis" Ist der Inhalt des Fehlerschalters eine 0, war unsere Programmverarbeitung erfolgreich. Wir haben den Zustand der gesuchten LU ermittelt. Dementsprechend erfolgt eine Ausgabe am Terminal und ein Statistiksatz wird an das Ende der Statistikdatei angehängt. end else say txt ende: "free fi("sysdd") da("datei")" DD-Name und Dateiname werden freigegeben. exit Mehr ist hier leider nicht möglich. Ich denke aber, daß zu erkennen ist, welche Möglichkeiten in der Kombination aus REXX und NetView liegen. In ähnlicher Form, manchmal noch komfortabler, sieht das ganze in Verbindung mit anderen Automationstools aus. Viel Spaß dabei. 409 Anhang - E StichwortVerzeichnis 410 REXX unter MVS-TSO/E 411 Anhang - E A ABBREV() .......................................................................................................... 199 Abfragetechniken ................................................................................................. 40 Ablaufverfolger ............................................................................................. 35, 107 ABS() .................................................................................................................. 200 Addition mit Datumsfeld ...................................................................................... 185 ADDRESS .......................................................................................................... 201 ADDRESS() ....................................................................................................... 202 ALLOC .......................................................................................................... 6, 203 ARG() ................................................................................................................. 207 Arithmetik ..................................................................................................10, 19, 21 Arithmetische Funktionen ............. 200, 225, 246, 247, 249, 273, 274, 300, 310, 334 ATTRIB .............................................................................................................. 208 Aufruf als Kommando ........................................................................................... 99 Aufruf als Unterprogramm .................................................................................... 99 B Batchablauf ........................................................................................................ 102 Befehlsausführung unter einem Interpreter .......................................................... 12 Befehlsauswertung (TSO) ................................................................... 130, 132, 135 Befehlsbegrenzer ................................................................................................. 24 Befehlsübergabe an Systemumgebung ................................................................ 25 Bibliotheksname ..................................................................................................... 5 Blindanweisung .................................................................................................. 277 Bool'sche Operanden ........................................................................................... 23 BSORT (UDF, Sortieren Wortkette) ................................................................... 183 C CALL (REXX) ..................................................................................................... 210 CALL (TSO) ........................................................................................................ 211 CENTER() .......................................................................................................... 212 Charakteristiken von REXX .................................................................................... 9 CLEAR ............................................................................................................... 213 COMPARE() ....................................................................................................... 214 Compound-Variablen ............................................................. 19, 120, 124, 145, 177 COPIES() ........................................................................................................... 215 C2D() .................................................................................................................. 216 C2X() .................................................................................................................. 217 412 REXX unter MVS-TSO/E D DATATYPE() ...................................................................................................... 218 DATE() ............................................................................................................... 219 Date Julian TO Date Normal .............................................................................. 190 DATECNT (UDF, Addition und Subtraktion mit Datumsfeld) .............................. 185 DATEDIFF (UDF, Datums-Differenzberechnung) ............................................... 187 Datei-Update ........................................................................................................ 81 Dateiattribute ...................................................................................................... 208 Dateiverarbeitung ................................................................................................. 68 Dateiverkettung ...................................................................................................... 7 DATEOSO (UDF, Ostersonntags-Berechnung) ................................................. 188 DATETRUE (UDF, Plausibilitätsprüfung für Datumsfeld) ................................... 189 Datum ................................................................................................................. 219 Datums-Differenzberechnung ............................................................................. 187 Datumsprüfung ................................................................................................... 189 Day of Week ....................................................................................................... 191 DD-Namen für Programmaufruf .............................................................................. 6 DELETE ............................................................................................................. 221 DELSTACK ........................................................................................................ 222 DELSTR() ........................................................................................................... 223 DELWORD() ...................................................................................................... 224 Dialog mit dem Anwender .................................................................................... 39 DIGITS() ............................................................................................................. 225 DJ2DN (UDF, Date Julian TO Date Normal) ...................................................... 190 DO FOREVER.............................................................................................. 50, 228 DO UNTIL bedingung ................................................................................... 53, 229 DO WHILE bedingung .................................................................................. 55, 230 DO anzahl .................................................................................................... 46, 226 DO variable = startwert TO endwert BY ± schrittweite ................................. 47, 227 DOW (UDF, Day Of Week) ................................................................................. 191 DROP ................................................................................................................. 231 DROPBUF .......................................................................................................... 232 Dynamische Zuweisungen .......................................................................... 132, 135 D2C() .................................................................................................................. 233 D2X() .................................................................................................................. 234 E Endlosschleife ...................................................................................................... 50 Einfache Abfragen ........................................................................................ 40, 230 Einfache Schleife .......................................................................................... 46, 226 Eingebettete Funktionen ....................................................................................... 12 Endlosschleife .............................................................................................. 50, 228 Environment ........................................................................................................ 23 Anhang - E 413 ERRORTEXT() ................................................................................................... 235 EXEC ................................................................................................................. 236 EXECIO .............................................................................................................. 237 EXECUTIL ...................................................................................................... 6, 242 EXIT ................................................................................................................... 244 Explizite Programmaufrufe ..................................................................................... 9 Externe Unterprogramme ............................................................................... 92, 99 F Fehlerbehandlung ................................................................................................. 35 Fehlermeldungen ............................................................................... 235, Anhang A Feiertagsermittlung ............................................................................................. 192 FIND() ................................................................................................................ 245 FOREVER ............................................................................................................ 50 FORM() .............................................................................................................. 246 FORMAT() .......................................................................................................... 247 Formate .................................................................................................................. 9 FREE .................................................................................................................. 248 Freies Format ....................................................................................................... 11 Freigabe Dateien, Attribute und symbolische Namen ......................................... 248 FTAGE (UDF, Feiertagsermittlung) .................................................................... 192 Funktionen ......................................................................................... 10, 25, 99, 100 FUZZ() ................................................................................................................ 249 H High Value .......................................................................................................... 183 Historisches ............................................................................................................ 6 I IF - THEN - ELSE ......................................................................................... 40, 250 Implizierter Programmaufruf ................................................................................... 9 INDEX() .............................................................................................................. 251 INSERT() ............................................................................................................ 252 Instruktionen ......................................................................................................... 25 Interne und externe Unterprogramme ................................................................... 92 INTERPRET ....................................................................................................... 253 Interpreter ............................................................................................................. 12 ITERATE ...................................................................................................... 49, 254 Iterative Schleife ................................................................................................... 47 414 REXX unter MVS-TSO/E J JUSTIFY() .......................................................................................................... 255 Job-Control .................................................................... 84, 164, 166, 171, 317, 327 K Kommandoaufruf .................................................................................................. 99 Kommentare ......................................................................................................... 24 Komponenten in einem REXX-Programm ............................................................ 14 L LASTPOS() ........................................................................................................ 256 LEAVE .......................................................................................................... 49, 257 Leichte Anwendung .............................................................................................. 11 LEFT() ................................................................................................................ 258 LENGTH() .......................................................................................................... 259 Lesehilfe für Syntaxdiagramme .......................................................................... 197 Lesen aus einer Datei .................................................... 73, 137, 138, 139, 142, 145 Lesen und Schreiben in eine Datei ........................................................ 81, 156, 158 Lesen und Schreiben aus/in mehrere Dateien .................................................... 149 LINESIZE() ......................................................................................................... 260 LISTA ................................................................................................................. 261 LISTC ................................................................................................................. 263 LISTDS ............................................................................................................... 264 LISTDSI() ........................................................................................................... 266 Literale ................................................................................................................. 15 Literaturhinweise .................................................................................................... 5 Löschen einer Datei ............................................................................................ 221 Logische Verknüpfungen ...................................................................................... 23 Low Value ........................................................................................................... 183 M MAKEBUF .......................................................................................................... 272 MAX() ................................................................................................................. 273 Mehrfach-Abfragen ....................................................................................... 44, 306 Merkmale von REXX ............................................................................................ 11 MIN() .................................................................................................................. 274 Modularisierung .................................................................................................... 89 MSG() ................................................................................................................. 275 Anhang - E 415 N Namenskonventionen für Variablen ...................................................................... 17 Namensvergabe ..................................................................................................... 7 NEWSTACK ....................................................................................................... 276 NOP ................................................................................................................... 277 NUMERIC ........................................................................................................... 278 O Operanden ........................................................................................................... 21 OUTTRAP() ................................................................................. 130, 132, 135, 281 Ostersonntags-Berechnung ................................................................................ 188 OVERLAY() ........................................................................................................ 286 P PA-1-Taste ........................................................................................................... 35 PARSE ......................................................................................................... 27, 287 Parsing (Zerlegen von Wort- oder Zeichenketten) ........................................ 27, 287 Platzhalter ...................................................................................................... 33, 34 Plausibilitätsprüfungen ................................................................................... 59, 60 POS() ................................................................................................................. 291 POST-abweisende Schleife .......................................................................... 55, 229 PRE-abweisende Schleife ............................................................................ 53, 230 PROCEDURE .................................................................................................... 290 PROFILE ............................................................................................................ 292 Programm-Variablen ...................................................................................... 16, 17 Programmablauf im Batch .................................................................................. 102 Programmaufruf .................................................................................. 6, 7, 210, 211 PROMPT() ......................................................................................................... 293 Punkt .............................................................................................................. 33, 34 PUSH ................................................................................................................. 294 Q QBUF ................................................................................................................. QELEM ............................................................................................................... QSTACK ............................................................................................................ QUEUE .............................................................................................................. QUEUED() ......................................................................................................... 295 296 299 297 298 416 REXX unter MVS-TSO/E R RANDOM() ......................................................................................................... 300 Rechenoperationen .............................................................................................. 12 RENAME ............................................................................................................ 301 RETURN ............................................................................................................ 302 REVERSE() ........................................................................................................ 303 REXX im Batch ............................................................................................ 102, 103 REXX und SAA (System Application Architecture) ............................................... 13 RIGHT() .............................................................................................................. 304 Rücksetzen von Variablen .................................................................................... 19 RXSTRU (UDF, Strukturprüfung in REXX-Source) ............................................ 177 S SAA (System Applikation Architecture) ................................................................ 13 SAY .................................................................................................................... 305 Schleifenkombinationen ....................................................................................... 57 Schleifensteuernde Befehle .................................................................................. 49 Schleifenverarbeitung .................................... 46, 116, 120, 132, 135, 145, 181, 183 Schreiben in eine Datei ........................................................................................ 76 Schreibweise .......................................................................................................... 9 SELECT ....................................................................................................... 44, 306 SEND ................................................................................................................. 308 SIGN() ................................................................................................................ 310 SIGNAL .............................................................................................................. 311 SORT (UDF, Sortieren Wortkette) ...................................................................... 181 Sortieren Wortkette .....................................................................................181, 183 SPACE() ............................................................................................................. 314 Spezielle Variablen ............................................................................................... 18 Sprachkomponenten ............................................................................................ 14 Stack ...... 61, 137, 138, 139, 142, 145, 177, 222, 232, 272, 294, 295, 296, 297, 298, 299 String-Manipulation .............................................................................................. 12 STRIP() .............................................................................................................. 315 SUBCOM ........................................................................................................... 316 SUBMIT .............................................................................................................. 317 Subroutine ............................................................................................................ 91 SUBSTR() .......................................................................................................... 318 Subtraktion mit Datumsfeld ................................................................................ 185 Suche nach REXX-Programmen ......................................................................... 7,8 SUBWORD() ...................................................................................................... 319 SYMBOL() .......................................................................................................... 320 Symboliken für REXX-Programmaufrufe ................................................................ 8 Symbolische Variablen ................................................................................... 16, 17 Syntaxdiagramme, Lesehilfe für ......................................................................... 197 Anhang - E 417 SYSDSN() .......................................................................................................... 321 SYSEXEC .............................................................................................................. 6 SYSVAR() .......................................................................................................... 324 Systemumgebungen ............................................................................................. 26 T Tabellenverarbeitung ................................................... 111, 120, 124, 132, 135, 183 Testhilfen ............................................................... 9, 11, 33, 35, 105, 311, 328, 332 TIME() ................................................................................................................ 326 TRACE ............................................................................................................... 328 TRACE() ............................................................................................................. 332 TRANSLATE() .................................................................................................... 333 TRUNC() ............................................................................................................ 334 TSO-Befehlsauswertung ..................................................................... 130, 132, 135 U Umwandlungsfunktionen ............................................. 216, 217, 233, 234, 345, 346 Unterprogramme ............................................................................................ 92, 99 UNTIL ........................................................................................................... 55, 229 Update in Datei ..................................................................................................... 81 UPPER ............................................................................................................... 335 USERID() ........................................................................................................... 336 V VALUE() ............................................................................................................. 337 Variablen ........................................................................... 9, 11, 16, 17, 18, 19, 231 Vergleichsoperanden ............................................................................................ 22 VERIFY() ............................................................................................................ 338 Verknüpfungen ..................................................................................................... 23 W Week Of Year ..................................................................................................... 194 Wertzuweisungen ................................................................................................. 18 WHILE 53, 228 Wochentagsermittlung ........................................................................................ 191 WORD() ............................................................................................................. 339 WORDINDEX() ................................................................................................... 340 WORDLENGTH() ............................................................................................... 341 WORDPOS() ...................................................................................................... 342 WORDS() ........................................................................................................... 343 418 REXX unter MVS-TSO/E Wort-Funktionen ........................... 199, 207, 224, 245, 319, 339, 340, 341, 342, 343 Worte .................................................................................................................... 16 Wortketten-Manipulation ..................................................................................... 128 WOY (UDF, Week Of Year) ................................................................................ 194 X XRANGE() .......................................................................................................... 344 X2C() .................................................................................................................. 345 X2D() ................................................................................................................. 346 Z Zählschleife (Iteratives DO) .......................................................................... 47, 227 Zeichenketten ....................................................................................................... 15 Zeichenketten-Funktionen .................... 212, 214, 215, 218, 223, 251, 252, 255, 256 ..................................................... 258, 259, 286, 291, 303, 304, 314, 315, 318, 333 Zeichenketten-Manipulation ................................................................................. 12 Zeit ..................................................................................................................... 326 Zerlegen von Wort- oder Zeichenketten ............................................................... 25 Zielgruppe .............................................................................................................. 1 Zufallsgenerator .......................................................................................... 230, 300 Zuweisungen (Dateien, dynamisch) ............................................................ 132, 135