Text in einer Datei durch Konstante ersetzen

Mittels dieses SORT-Steps in einem Job, kann in einer Datei an einer bestimmten Stelle, ein Text durch eine Konstante ersetzt werden.

//S01SORT EXEC PROC=SORTX
//SORTIN DD DSN=USER.TEST.SORT,
// DISP=SHR
//SORTOUT DD DSN=USER.TEST.SORT.OUT,
// DISP=(NEW,CATLG,DELETE),
// UNIT=WRK,
// SPACE=(CYL,(160,50),RLSE),
// LRECL=407,RECFM=FB
//SYSIN DD *
INCLUDE COND(1,1,CH,EQ,C'0')
INREC FIELDS=(1,95,
C'ASTERIX UND OBELIX ',
X'00',
C'GALLIEN ',
X'00',
162,245)
SORT FIELDS=COPY

Die Include Condition stellt dabei die Bedingung dar. In diesem Beispiel werden Char-Strings und HEX-Werte als Konstante in die Datei eingestellt.

Mit ICETOOL Datensätze in Dateien zählen

Im Rahmen von Testaktivitäten ist immer wieder Vollständigkeit von Datensätzen in Datasets zu überprüfen. Mit dem DFSORT-Tool ICETOOL lassen sich auf einfache Art und Weise eine große Anzahlen von Dateien zählen. Mit der folgenden JCL kann dies in einem JOB auf bis 255 Dateien erweitert werden:

//NZSCNTAU JOB (666045,BA),                     
//         'MOELLER',                           
//         CLASS=K,                             
//         NOTIFY=&SYSUID,                      
//         MSGCLASS=T                           
//RESTART EXEC PGM=IEFBR14                      
//ALT     DD DSN=&SYSUID..NZSCOUNT.AUSUEB,      
//           DISP=(MOD,DELETE,DELETE)           
//        SET VAR1='$150529'                    
//ICETOOL EXEC PGM=ICETOOL                      
//TOOLMSG DD SYSOUT=*                           
//DFSMSG  DD SYSOUT=*                           
//IN001   DD DSN=BAT.PO.&VAR1..ZH.AL.GDG.AUSUEB,
//           DISP=SHR                           
//OUT001  DD DSN=&SYSUID..NZSCOUNT.TMPAU,       
//           DISP=(MOD,CATLG,DELETE),           
//           RECFM=FB,                          
//           LRECL=80,                              
//           BLKSIZE=800,                           
//           SPACE=(80,(1,10000),RLSE)              
//TOOLIN  DD *                                      
COUNT FROM(IN001) WRITE(OUT001) -                   
TEXT('BAT.PO.&VAR1..ZH.AL.GDG.AUSUEB,            :')
/*                                                  
//ICETOOL EXEC PGM=ICETOOL                
//TOOLMSG DD SYSOUT=*                     
//DFSMSG  DD SYSOUT=*                     
//IN001   DD DSN=&SYSUID..NZSCOUNT.TMPAU, 
//           DISP=SHR                     
//OUT001  DD DSN=&SYSUID..NZSCOUNT.AUSUEB,
//           DISP=(MOD,CATLG,DELETE),     
//           RECFM=FB,                    
//           LRECL=80,                    
//           BLKSIZE=800,                 
//           SPACE=(80,(1,10000),RLSE)    
//TOOLIN  DD *                            
  DISPLAY FROM(IN001) LIST(OUT001) -      
  HEADER('DATEINAME') ON(1,35,CH) -       
  HEADER('ANZAHL RECORDS') ON(45,15,UFF) -
  TOTAL('SUMME AUSUEB: ')                 
/*                                        
//RESTART EXEC PGM=IEFBR14                
//ALT     DD DSN=&SYSUID..NZSCOUNT.TMPAU, 
//           DISP=(MOD,DELETE,DELETE)    )

Beschreibung der einzelnen Zeilen:

Zeile 01: Aufruf des Programmes ICETOOL

Zeile 02 und 03: Umleitung an die Standard-Ausgabe der Meldungen die durch das Programm ICETOOL und DFSORT erzeugt werden

Zeile 04 und 05: Einzulesende Datei (mit Variablennamen für das Fachbestandsdatum), DISP=SHR beschreibt lesenden Zugriff

Zeile 06 bis 11: Auszugebende Datei (mit System-Variablennamen für die User-ID), DISP=(MOD,CATLG,DELETE) beschreibt den schreibenden Zugriff auf eine bereits vorhandene Datei. Jede Ergebniszeile wird an die vorhandene Datei unten angehängt. Achtung: Die erzeugte Datei ist eine temporäre Datei, die im letzten Step des Jobs wieder gelöscht wird. Im letzten Step des Jobs wird aus jeder temporären Datei die Summe je Entität berechnet und in die endgültige Ausgabedatei geschrieben.

Zeile 12 bis 14: Hierbei handelt es sich um die Eingabeparameter für das Programm ICETOOL. COUNT zählt aus der und IN001 angegebenen Datei und schreibt unter die mit OUT001 benannte Datei. Das Minuszeichen am Ende der Zeile ist der Identifikator für eine weitere Parameter-Zeile. TEXT gibt einen konstanten String aus (in diesem Fall den Namen der einzulesenden Datei)

Beschreibung des Outputs

Je Job/Entität wird unter der eigenen User-ID eine Ausgabedatei erzeugt. Jedes Ausgabedatei enthält zwei Spalten (Spalte 1 = Dateiname, Spalte 2 = Anzahl der Zeilen je Datei) und eine Summenzeile.

Beispiel (Auszug):

DATEINAME                             ANZAHL RECORDS
---------------------------------   ----------------
BAT.PO.&VAR1..ZH.AL.GDG.AUSUEB,     +000000000000000
BAT.PO.&VAR1..ZH.A2.GDG.AUSUEB,     +000000000007468
BAT.PO.&VAR1..ZH.BL.GDG.AUSUEB,     +000000000000000
BAT.PO.&VAR1..ZH.DR.GDG.AUSUEB,     +000000000027352
…
SUMME AUSUEB:                       +000000000161479

Extrahieren/Sortieren aus einem „variable blocked“ Dataset mit JCL

In meinem aktuellen Projekt werden die Eingangsdaten auf dem Mainframe in einem VB-Dataset (variable blocked) Dataset bereitgestellt. Das Dataset enthält Datensätze mit unterschiedlich langen Satzarten und einem einheitlichen Header. Anhand der im Headerbereich verfügbaren Information zu einer „Satzart“ kann mit der unten angeführten JCL eine (oder mehrere) bestimmte Satzarten aus diesem Dataset extrahiert/sortiert werden.

Im ersten SORT-Step werden die Satzarten BETRT2, BETRT3 und BETRT4 aus dem Dataset BAT.PO.K.KE.BEST.N0202.V0204001 in die Ergebnisdatei Y0E6844.EMKSORT.OUT geschrieben. Zu beachten ist hier, dass die Eingangs-Dataset keine FB-Datei (fixed blocked), sondern eine HOST-Datei im VB-Format (variable blocked) ist. Das führt dazu, dass in der INCLUDE-Bedingung die Stelle 72 angegeben ist (wenn man sich das Dataset im browse-mode ansieht, dann zeigt die Spaltenposition an der die Satzart im Dataset steht aber ab Position 68 – man muss bei einer VB-Datei also immer 4 Byte dazuzählen). Wäre es eine FB-Datei müsste im Job die tatsächliche Position angegeben werden – also 68.

---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----
******************************** Top of Data *********************************
14002015020220150203KDINFO                                   00001DINFO     01
14002015020220150203K000000000000400020                      00001KONT01    02
14002015020220150203K000000000000400021                      00002KONT02    12
14002015020220150203K000000000001700100                      00003BETRT2    08
14002015020220150203K000000000002500200                      00004GPKT01    03
14002015020220150203K000000000000300030                      00005ANTR      04
14002015020220150203K000000000000900040                      00006BETRT4    01

Im zweiten SORT-Step (der ist optional falls man ihn braucht) werden aus den extrahierten Satzarten nur die eindeutigen Kontrakt-Nummern extrahiert und in das Dataset Y0E6844.EMKSORT.OUT2 geschrieben. Dies ist speziell für diese Satzarten gedacht, da hier in den Eingangsdaten Duplikate enthalten sind.

Quellcode:

//EMKSRT JOB (666045,BA), 
//       'MOELLER', 
//       CLASS="K",
//       NOTIFY=&SYSUID,
//       MSGCLASS=T 
//SORT EXEC PGM=SORT
//SYSPRINT DD SYSOUT=* 
//SORTIN   DD DSN=BAT.PO.K.KE.BEST.N0202.V0204001,DISP=SHR
//SORTOF01 DD DSN=Y0E6844.EMKSORT.OUT, 
//            DISP=(,CATLG,DELETE) 
//* 
//SYSIN DD * 
    SORT FIELDS=COPY 
       OUTFIL FILES=01, 
       INCLUDE=((72,6,CH,EQ,C'BETRT2'),OR, 
                (72,6,CH,EQ,C'BETRT3'),OR, 
                (72,6,CH,EQ,C'BETRT4')) 
//* 
//SORT EXEC PGM=SORT
//SYSOUT DD SYSOUT=* 
//SORTIN DD DSN=Y0E6844.EMKSORT.OUT,DISP=SHR
//SORTOUT DD DSN=Y0E6844.EMKSORT.OUT2, 
// DISP=(,CATLG,DELETE) 
//* 
//SYSIN DD * 
    SORT FIELDS=(28,18,CH,A) 
     SUM FIELDS=NONE 
//* 
.