I am sharing the best DFSORT example on conditional sort for quick reference.
INPUT: Three fixed-length record data sets
OUTPUT: Fixed-length record data set
WORK DATASETS: Dynamically allocated (by default)
USER EXITS: None
How to Use IFTHEN
//EXAMP JOB A400,PROGRAMMER 01
//S1 EXEC PGM=SORT 02
//SYSOUT DD SYSOUT=A 03
//SORTIN DD DSN=INPUT.FILE1,DISP=SHR 04
// DD DSN=INPUT.FILE2,DISP=SHR 05
// DD DSN=INPUT.FILE3,DISP=SHR 06
//SORTOUT DD DSN=OUTPUT.FILE,DISP=(NEW,CATLG,DELETE), 07
// SPACE=(CYL,(5,5)),UNIT=SYSDA 08
//SYSIN DD * 09
INREC IFTHEN=(WHEN=(1,3,CH,EQ,C'HDR'), 10
SORT FIELDS=(81,1,CH,A,8,5,CH,A) 16
OUTFIL REMOVECC, 17
Step By Step Explanation
This example shows how you can use three input files, each with a header record (‘HDR’), detail records (‘DTL’) and a trailer record (‘TRL’), and create an output file with one header record with the current date, the sorted detail records, and one trailer record with the current date.
01 – JOB statement. Introduces this job to the operating system.
02 – EXEC statement. Calls DFSORT directly by its alias name SORT.
03 – SYSOUT DD statement. Directs DFSORT messages and control statements to sysout class A.
04-06 – SORTIN DD statement. Consists of a concatenation of three input data sets: INPUT.FILE1, INPUT.FILE2 and INPUT.FILE3. DFSORT determines from the data set labels that each data set has RECFM=FB and LRECL=80. The BLKSIZEs vary. Each input data set has a header record, detail records, and a trailer record.
07-08 – SORTOUT DD statement. Creates a new output data set: OUTPUT.FILE. DFSORT sets RECFM=FB, LRECL=80 and selects an appropriate BLKSIZE. The output data set will have one header record, the sorted detail records, and one trailer record.
09 – SYSIN DD statement. DFSORT control statements follow.
10-15 – INREC statement.
How IFTHEN WHEN Works
The first IFTHEN WHEN=(logexp) clause identifies and operates on header records (‘HDR’ in positions 1-3); OVERLAY puts today’s date in the form ‘ddd/yyyy’ in positions 6-13, adds a ‘0’ in position 81, adds a ZD sequence number in positions 82-83 and does not affect the rest of the record.
The second IFTHEN WHEN=(logexp) clause identifies and operates on trailer records (‘TRL’ in positions 1-3); OVERLAY puts today’s date in the form ‘ddd/yyyy’ in positions 11-18, adds a ‘9’ in position 81, adds a ZD sequence number in positions 82-83 and does not affect the rest of the record.
The IFTHEN WHEN=NONE clause identifies and operates on detail records (not ‘HDR’ or ‘TRL’ in positions 1-3); OVERLAY adds a ‘1’ in position 81 and does not affect the rest of the record.
DFSORT extends the reformatted input records from 80 bytes to 83 bytes to accommodate the identifier byte added in position 81 and the sequence number added in positions 82-83.
The ‘0’, ‘1’ or ‘9’ identifier byte added in position 81 allows us to sort the header records (‘0’) first, followed by the detail records (‘1’), and then the trailer records (‘9’).
The sequence number added in positions 82-83 will allow us to keep only the first header record and the first trailer record.
The sequence number will be 1 for the first header record, 2 for the second header record and 3 for the third header record. Likewise, the sequence number will be 1 for the first trailer record, 2 for the second trailer record and 3 for the third trailer record. Since the sequence number is not specified for the detail records, it will be blank.
16 -SORT statement. FIELDS specifies an ascending 1-byte character control field at position 81 (the identifier byte added by INREC), and an ascending 5-byte character control field starting at position 8 (the key for the detail records).
17-19 – OUTFIL statement. REMOVECC removes the ANSI carriage control characters and ensures that the RECFM is FB rather than FBA. OMIT specifies that reformatted output records with ‘0’ or ‘9’ in position 81 (header or trailer records) and a sequence number in positions 82-83 greater than 1 (second and subsequent header or trailer records), are omitted.
OUTREC keeps only positions 1-80 for the OUTFIL output records, thus removing the identifier byte and sequence number we added in positions 81-83 with the INREC statement (we do not want these temporary fields in the OUTFIL output records).