PUSH defines the input field, sequence number, or identifier that will be overlaid for each group’s records. For fixed-length records, the first input and output data byte start at position 1. For variable-length records, the first input and output data byte start at position 5, after the RDW in positions 1-4.
PUSH=(c:item,…)
You can use the following in PUSH:
c Specifies the output position (column) to be overlaid. If you do not specify c: for the first item, it defaults to 1:. If you do not specify c: for any other item, it starts after the previous item. You can specify items in any order and overlap output columns. c can be 1 to 32752. If you specify an item that extends the output record beyond the end of the input record, the record length is automatically increased to that length, and blanks are filled in on the left as needed. For variable-length records, the RDW length is increased to correspond to the larger record length after all of the items are processed. Missing bytes in specified input fields are replaced with blanks so the padded fields can be processed.
p,m Specifies a field in the first input record of each group to be propagated to every record of the group. p specifies the starting position of the field in the input record and m specifies its length. A field must not extend beyond position 32752.
ID=n Specifies a printable Zoned Decimal (ZD) identifier n bytes long. It will be added to every record of each group. For the first group, the identifier will start at 1. and for each subsequent group, it will be increased by 1. The number n can be from 1 to 15.
SEQ=n Specifies a printable ZD sequence number n bytes long. It will be added to every record of each group. For the first record of each group, the identifier will start at 1. and for each subsequent record, it will be increased by 1. The number n can be from 1 to 15.
Let’s say each transaction at a store generates a series of unlike records. All the records are collected in a file that needs to be sorted by date and register number, WHEN=GROUP can generate appropriate sort keys for each record in the group.
For detailed information on syntax and a better understanding of IFTHEN usage click here
Example of PUSH – ID – SEQ
A header record (code ‘H’) with a register number and date, detailed SKU records (code ’S’) with an SKU number, unit price, and quantity, and a trailer total record (code ’T’) are generated for each transaction. A file with 20-byte fixed-length records for three transactions might look like
H 0003 2008/08/17
S 872567 0010.22 001
S 510945 0001.99 003
S 734018 0003.98 002
T 0024.15
H 0005 2008/08/16
S 013298 0000.69 004
S 510945 0017.03 001
T 0019.79
H 0002 2008/08/17
S 212134 0003.49 003
T 0010.47
INREC WHEN=GROUP can be used with BEGIN to identify a header record starting a group and END to identify a trailer record ending a group. PUSH extends each record by placing the date and register number from the header record at the end of each record in the group, followed by a 5-byte group number and a 3-byte record sequence number. All the records in a group will sort together.
INREC IFTHEN=(WHEN=GROUP,BEGIN=(1,1,CH,EQ,C’H’), END=(1,1,CH,EQ,C’T’), PUSH=(21:8,10,31:3,4,35:ID=5,SEQ=3))
Output
H 0003 2008/08/17 2008/08/17000300001001
S 872567 0010.22 0012008/08/17000300001002
S 510945 0010.99 0032008/08/17000300001003
S 734018 0003.98 0022008/08/17000300001004
T 0024.15 2008/08/17000300001005
H 0005 2008/08/16 2008/08/16000500002001
S 013298 0000.69 0042008/08/16000500002002
S 510945 0017.03 0012008/08/16000500002003
T 0019.79 2008/08/16000500002004
H 0002 2008/08/17 2008/08/17000200003001
S 212134 0003.49 0032008/08/17000200003002
T 0010.47 2008/08/17000200003003
The new PUSH data will sort the records
SORT FIELDS=(21,10,CH,A,31,4,CH,A,35,8,CH,A)
The data added by PUSH can be eliminated from the output data with a simple OUTREC statement for the original 20 bytes of the record. It can be eliminated by specifying LRECL=20 on the SORTOUT DD statement. It will create the following correctly sorted output.
H 0005 2008/08/16
S 013298 0000.69 004
S 510945 0017.03 001
T 0019.79
H 0002 2008/08/17
S 212134 0003.49 003
T 0010.47
H 0003 2008/08/17
S 872567 0010.22 001
S 510945 0001.99 003
S 734018 0003.98 002
T 0024.15
Scenario -1
If desired, a simple report can be created using OUTFIL IFTHEN to identify each different record type, format it appropriately, and remove the data added by PUSH. SECTIONS is used to generate a report header for each transaction.
OUTFIL SECTIONS=(35,5,HEADER3=(’ DATE REG# ID’),SKIP=L), IFTHEN=(WHEN=(1,1,CH,EQ,C’H’), FOR HEADER RECORDS: BUILD=(21,10,2X,3,4,2X,3,4,2X,35,5)), DATE, REG NUM, TRAN ID IFTHEN=(WHEN=(1,1,CH,EQ,C’S’), BUILD=(C’SKU#: ’,3,6,C’ PRICE: $’,10,7, C’ QUANTITY: ’,18,3)), IFTHEN=(WHEN=(1,1,CH,EQ,C’T’), FOR TRAILER RECORDS: BUILD=(C’TOTAL: $’,3,7))
The report produced is
DATE REG# ID 2008/08/16 0005 00002 SKU#: 013298 PRICE: $0000.69 QUANTITY: 004 SKU#: 510945 PRICE: $0017.03 QUANTITY: 001 TOTAL: $0019.79 DATE REG# ID 2008/08/17 0002 00003 SKU#: 212134 PRICE: $0003.49 QUANTITY: 003 TOTAL: $0010.47 DATE REG# ID 2008/08/17 0003 00001 SKU#: 872567 PRICE: $00010.22 QUANTITY: 001 SKU#: 510945 PRICE: $0001.99 QUANTITY: 003 SKU#: 734018 PRICE: $0003.98 QUANTITY: 002 TOTAL: $0024.15
Scenario -2
This example illustrates how you can SORT and INCLUDE groups of FB records depending on a value in the first record of each group. We propagate the value in the first record of the group to every record of the group, SORT and INCLUDE on the value, and then remove it.
INREC IFTHEN=(WHEN=GROUP,BEGIN=(2,4,CH,EQ,C’RPT.’), PUSH=(31:6,8)) OPTION EQUALS SORT FIELDS=(31,8,CH,A) OUTFIL INCLUDE=(31,8,CH,EQ,C’FRANK’,OR, 31,8,CH,EQ,C’SRIHARI’),BUILD=(1,30)
The 30-byte FBA input records might look like this:
1RPT.SRIHARI LINE 1 FOR REPORT 1 LINE 2 FOR REPORT 1 ... 1RPT.VICKY LINE 1 FOR REPORT 2 LINE 2 FOR REPORT 2 ... 1RPT.FRANK LINE 1 FOR REPORT 3 LINE 2 FOR REPORT 3 ... 1RPT.DAVID LINE 1 FOR REPORT 4 LINE 2 FOR REPORT 4 ...
Each report starts with ‘RPT.reptname’ in positions 2-13. In the output data set we only want to include records for reports with specific reptname values, and the reptname values we want can change from run to run. We also want to sort by the reptname values in ascending order. For this example, let’s say we just want the SRIHARI and FRANK reports.
We use an IFTHEN WHEN=GROUP clause to propagate the reptname value to each record of the group. BEGIN indicates a group starts with ‘RPT.’ in positions 2-5. PUSH overlays the reptname value from the first record of the group (the ‘RPT.reptname’ record) at positions 31-38 (after the end of the record) in each record of the group including the first. After the IFTHEN GROUP clause is executed, the intermediate records look like this:
1RPT.SRIHARI LINE 1 FOR REPORT 1 SRIHARI LINE 2 FOR REPORT 1 SRIHARI … SRIHARI 1RPT.VICKY VICKY LINE 1 FOR REPORT 2 VICKY LINE 2 FOR REPORT 2 VICKY … VICKY 1RPT.FRANK FRANK LINE 1 FOR REPORT 3 FRANK LINE 2 FOR REPORT 3 FRANK … FRANK 1RPT.DAVID DAVID LINE 1 FOR REPORT 4 DAVID LINE 2 FOR REPORT 4 DAVID … DAVID
Note that the records of each group have the reptname value from the first record of that group in positions 31-38.
We use a SORT statement to sort ascending on the reptname in positions 31-38. We use the EQUALS option to ensure that records in the same group (that is, with the same reptname value) are kept in their original order. After the SORT statement is executed, the intermediate records look like this:
1RPT.DAVID DAVID LINE 1 FOR REPORT 4 DAVID LINE 2 FOR REPORT 4 DAVID … DAVID 1RPT.FRANK FRANK LINE 1 FOR REPORT 3 FRANK LINE 2 FOR REPORT 3 FRANK … FRANK 1RPT.SRIHARI SRIHARI LINE 1 FOR REPORT 1 SRIHARI LINE 2 FOR REPORT 1 SRIHARI … SRIHARI 1RPT.VICKY VICKY LINE 1 FOR REPORT 2 VICKY LINE 2 FOR REPORT 2 VICKY …. VICKY
We use an OUTFIL statement to only INCLUDE the records with a reptname of FRANK or SRIHARI in positions 31-38, and to remove the reptname from positions 31-38 so the included output records will be identical to the input records. After the OUTFIL statement is executed, the final output records look like this:
1RPT.FRANK LINE 1 FOR REPORT 3 LINE 2 FOR REPORT 3 ... 1RPT.SRIHARI LINE 1 FOR REPORT 1 LINE 2 FOR REPORT 1
Scenario -3
This example illustrates how you can INCLUDE specific relative records from groups of VB records. We insert a sequence number between the RDW and the first data byte of each record. The sequence number restarts at 1 for the first record in each group. We INCLUDE the sequence number and then remove it.
OPTION COPY OUTREC IFTHEN=(WHEN=INIT,BUILD=(1,4,8:5)), IFTHEN=(WHEN=GROUP,BEGIN=(8,5,CH,EQ,C'PAGE:'), PUSH=(5:SEQ=3)) OUTFIL INCLUDE=(5,3,ZD,EQ,2,OR,5,3,ZD,EQ,3), BUILD=(1,4,5:8)
The VB input records might look like this:
Len|Data 12|PAGE: 1 22|LINE 1 OF REPORT A 22|LINE 2 OF REPORT A 22|LINE 3 OF REPORT A 22|LINE 4 OF REPORT A |... 12|PAGE: 2 23|LINE 66 OF REPORT A 23|LINE 67 OF REPORT A 23|LINE 68 OF REPORT A 23|LINE 69 OF REPORT A |... 12|PAGE: 3 24|LINE 131 OF REPORT A 24|LINE 132 OF REPORT A 24|LINE 133 OF REPORT A 24|LINE
Note that positions 5-7 are blank and the ‘PAGE:’ characters have been shifted over to positions 8-12.
We use an IFTHEN WHEN=GROUP clause to put a 3-byte sequence number in each record. BEGIN indicates a group starts with a record that has ‘PAGE:’ in positions 8-12. PUSH overlays a 3-byte sequence number at positions 5-7 of each record. The sequence number starts at 1 for the ®rst record of a group and is incremented by 1 for each subsequent record of the group. After the IFTHEN GROUP clause is executed, the intermediate records look like this:
Len|Data 15|001PAGE: 1 25|002LINE 1 OF REPORT A 25|003LINE 2 OF REPORT A 25|004LINE 3 OF REPORT A 25|005LINE 4 OF REPORT A |006... 15|001PAGE: 2 26|002LINE 66 OF REPORT A 26|003LINE 67 OF REPORT A 26|004LINE 68 OF REPORT A 26|005LINE 69 OF REPORT A |006... 15|001PAGE: 3 27|002LINE 131 OF REPORT A 27|003LINE 132 OF REPORT A 27|004LINE 133 OF REPORT A 27|005LINE 134 OF REPORT A |006…
Note that the records in each group are numbered starting with 001 for the ®rst record of each group. The records we want have sequence numbers 002 and 003. We use an OUTFIL statement to only INCLUDE the records with sequence number 002 or 003, and to remove the sequence numbers so the included output records will be identical to the input records. After the OUTFIL statement is executed, the ®nl output records look like this:
Len|Data 22|LINE 1 OF REPORT A 22|LINE 2 OF REPORT A 23|LINE 66 OF REPORT A 23|LINE 67 OF REPORT A 24|LINE 131 OF REPORT A 24|LINE 132 OF REPORT A
Scenario -4
This example illustrates how you can INCLUDE groups of FB records between a header and a trailer. We add an ID after the end of each record to indicate whether it’s part of a group or not, INCLUDE on the ID, and then remove it.
OPTION COPY OUTREC IFTHEN=(WHEN=GROUP,BEGIN=(1,3,CH,EQ,C'HDR'), END=(1,3,CH,EQ,C'TRL'),PUSH=(31:ID=1)) OUTFIL INCLUDE=(31,1,CH,NE,C' '),BUILD=(1,30)
The 30-byte FB input records might look like this:
C33 Not in a group HDR Start Group 1 A01 Group 1 record B02 Group 1 record C03 Group 1 record TRL End Group 1 R24 Not in a group T02 Not in a group HDR Start Group 2 D04 Group 2 record E05 Group 2 record TRL End Group 2 F97 Not in a group
In the output data set we only want to include groups of records that start with ‘HDR’ and end with ‘TRL’.
We use an IFTHEN WHEN=GROUP clause to put a non-blank character in each record that is part of a group. BEGIN indicates a group starts with a record that has ‘HDR’ in positions 1-3. END indicates a group ends with a record that has ‘TRL’ in positions 1-3. PUSH overlays a 1-byte ID character at position 31 in each record of a group (after the end of the record). After the IFTHEN GROUP clause is executed, the intermediate records look like this:
C33 Not in a group HDR Start Group 1 1 A01 Group 1 record 1 B02 Group 1 record 1 C03 Group 1 record 1 TRL End Group 1 1 R24 Not in a group T02 Not in a group HDR Start Group 2 2 D04 Group 2 record 2 E05 Group 2 record 2 TRL End Group 2 2 F97 Not in a group
Note that the records within a group have a non-blank character in position 31 whereas the records outside groups have a blank character in position 31. The ID starts at 1 for the first group and is incremented by 1 for each subsequent group. Since we are only allowing one character for the ID, when the ID counter gets to 10, a ‘0’ will appear in position 31. That’s fine since we are just looking for a nonblank to indicate a record within a group, or a blank to indicate a record outside of a group. We use an OUTFIL statement to only INCLUDE records with a non-blank in position 31, and to remove the ID character so the included output records will be identical to the input records. After the OUTFIL statement is executed, the final output records look like this:
HDR Start Group 1 A01 Group 1 record B02 Group 1 record C03 Group 1 record TRL End Group 1 HDR Start Group 2 D04 Group 2 record E05 Group 2 record TRL End Group 2
Scenario -5
This example illustrates how you can INCLUDE groups of VB records between a header and a trailer. It’s similar to Example 16, but here the records are variable-length. For the FB records, we could add the ID after the end of each record and then remove it without changing the records. But we can’t add the ID at the end of each VB record because that would pad all of the records to a fixed length. So, instead we insert the ID between the RDW and the first data byte of each record, and later remove it.
OPTION COPY OUTREC IFTHEN=(WHEN=INIT,BUILD=(1,4,6:5)), IFTHEN=(WHEN=GROUP,BEGIN=(6,3,CH,EQ,C'HDR'), END=(6,3,CH,EQ,C'TRL'),PUSH=(5:ID=1)) OUTFIL INCLUDE=(5,1,CH,NE,C' ‘),BUILD=(1,4,5:6)
The VB input records might look like this:
Len|Data 23|C33 Not in a group 23|HDR Start Group 1 25|A01 Group 1 record 25|B02 Group 1 record 25|C03 Group 1 record 21|TRL End Group 1 23|R24 Not in a group 23|T02 Not in a group 23|HDR Start Group 2 25|D04 Group 2 record 25|E05 Group 2 record 21|TRL End Group 2 25|F97 Not in a group
In the output data set we only want to include groups of records that start with ‘HDR’ and end with ‘TRL’. We use an IFTHEN WHEN=INIT clause to reformat each record so it has room for the ID byte between the RDW and the first data byte. After the WHEN=INIT clause is executed, the intermediate records look like this:
Len|Data 24| C33 Not in a group 24| HDR Start Group 1 26| A01 Group 1 record 26| B02 Group 1 record 26| C03 Group 1 record 22| TRL End Group 1 24| R24 Not in a group 24| T02 Not in a group 24| HDR Start Group 2 26| D04 Group 2 record 26| E05 Group 2 record 22| TRL End Group 2 26| F97 Not in a group
Note that position 5 is blank and the ‘HDR’ and ‘TRL’ characters have been shifted over to positions 6-8.
We use an IFTHEN WHEN=GROUP clause to put a non-blank character in each record that is part of a group. BEGIN indicates a group starts with a record that has ‘HDR’ in positions 6-8. END indicates a group ends with a record that has ‘TRL’ in positions 6-8. PUSH overlays a 1-byte ID character at position 5 in each record of a group. After the IFTHEN GROUP clause is executed, the intermediate records look like this:
Len|Data 24| C33 Not in a group 24|1HDR Start Group 1 26|1A01 Group 1 record 26|1B02 Group 1 record 26|1C03 Group 1 record 22|1TRL End Group 1 24| R24 Not in a group 24| T02 Not in a group 24|2HDR Start Group 2 26|2D04 Group 2 record 26|2E05 Group 2 record 22|2TRL End Group 2 26| F97 Not in a group
Note that the records within a group have a non-blank character in position 5 whereas the records outside groups have a blank character in position 5. The ID starts at 1 for the first group and is incremented by 1 for each subsequent group. Since we are only allowing one character for the ID, when the ID counter gets to 10, a ‘0’ will appear in position 5. That’s fine since we are just looking for a non-blank to indicate a record within a group, or a blank to indicate a record outside of a group. We use an OUTFIL statement to only INCLUDE records with a non-blank in position 5, and to remove the ID character so the included output records will be identical to the input records. After the OUTFIL statement is executed, the final output records look like this:
Len|Data 23|HDR Start Group 1 25|A01 Group 1 record 25|B02 Group 1 record 25|C03 Group 1 record 21|TRL End Group 1 23|HDR Start Group 2 25|D04 Group 2 record 25|E05 Group 2 record 21|TRL End Group 2