INCLUDE and OMIT within OUTFIL let you filter which records go to each output file. Each OUTFIL can have INCLUDE=(condition) so that only records that satisfy the condition are written to that OUTFIL's dataset, or OMIT=(condition) so that only records that do not satisfy the condition are written. The condition uses the same syntax as the standalone INCLUDE/OMIT control statements: (position, length, format, operator, value). So you can split one sorted stream into many files by department, by record type, by key range, or by any test you can express. Records that do not match any OUTFIL's condition are not written to any of those OUTFILs unless you add an OUTFIL with SAVE to capture them. This page covers INCLUDE= and OMIT= on OUTFIL, condition syntax, format types (CH, ZD, PD, BI), and how to combine multiple OUTFILs with SAVE for a complete split.
When you have multiple OUTFIL statements, you often want different records in different files. For example: header records (type '01') to one file, detail records (type '02') to another; or records for region North to one file, South to another. Without per-OUTFIL filtering, every OUTFIL would get the same set of records (or you would rely on BUILD= only to change layout). INCLUDE= and OMIT= on each OUTFIL let you say "this output gets only records where this condition is true" (INCLUDE) or "this output gets only records where this condition is false" (OMIT). So one sort step can produce one file per department, one file per record type, or one file per key range, without separate sort runs.
INCLUDE=(condition) on an OUTFIL means: write to this OUTFIL only records for which the condition evaluates to true. The condition has the form (start, length, format, operator, value). Example: write only records where bytes 30–34 equal the character constant 'DEPT1':
1OUTFIL FNAMES=DEPT1,INCLUDE=(30,5,CH,EQ,C'DEPT1'),BUILD=(1,50)
Records that do not have 'DEPT1' in positions 30–34 are not written to DEPT1. They can still be written to another OUTFIL (with a different INCLUDE or with SAVE) or to SORTOUT.
OMIT=(condition) means: write to this OUTFIL only records for which the condition is false. So OMIT is the opposite of INCLUDE. Use OMIT when it is easier to say "exclude these" than "include only those." Example: write all records except those where bytes 1–2 are '99' (e.g. trailer records):
1OUTFIL FNAMES=DETAIL,OMIT=(1,2,CH,EQ,C'99'),BUILD=(1,80)
Every record except those with '99' in 1–2 goes to DETAIL. You cannot use both INCLUDE= and OMIT= on the same OUTFIL; choose one.
The condition is (position, length, format, operator, value):
| Format | Use | Example |
|---|---|---|
| CH | Character. Compare as EBCDIC character | (1,10,CH,EQ,C'ABC') |
| ZD | Zoned decimal. Signed numeric comparison | (20,4,ZD,GT,100) |
| PD | Packed decimal. Signed numeric comparison | (24,4,PD,LE,500) |
| BI | Binary. Fullword or halfword comparison | (30,4,BI,NE,0) |
For numeric fields use ZD, PD, or BI so that the comparison is numeric, not character. Example: write only records where a 4-byte zoned decimal at position 20 is greater than 1000:
1OUTFIL FNAMES=HIGH,INCLUDE=(20,4,ZD,GT,1000),BUILD=(1,80)
With CH, the comparison would be character (e.g. '9999' vs '1000' in EBCDIC order), which can give wrong results for numbers. Always use the correct format for the field type.
You can combine several OUTFILs, each with its own INCLUDE (or OMIT). Records are evaluated against OUTFILs in order. The first OUTFIL whose condition is satisfied can write the record. So you might have:
1234OUTFIL FNAMES=HEADER,INCLUDE=(1,2,CH,EQ,C'01'),BUILD=(1,80) OUTFIL FNAMES=DETAIL,INCLUDE=(1,2,CH,EQ,C'02'),BUILD=(1,80) OUTFIL FNAMES=TRAILER,INCLUDE=(1,2,CH,EQ,C'99'),BUILD=(1,80) OUTFIL FNAMES=OTHER,SAVE,BUILD=(1,80)
Records with '01' in 1–2 go to HEADER; '02' to DETAIL; '99' to TRAILER; any other value goes to OTHER because of SAVE. So you split by record type into four files.
The positions and lengths in INCLUDE= and OMIT= refer to the record as seen in the output phase. That is the record after INREC (if present) and after the sort. If you used INREC to reorder or shorten the record, the control field may be in a different position in the output record. Use that position in OUTFIL INCLUDE/OMIT. If you use OUTREC for SORTOUT, the OUTFIL still sees the record before OUTREC unless the OUTFIL has its own BUILD=; the exact order (OUTREC vs OUTFIL BUILD) is product-dependent. In practice, treat the record layout after INREC and sort as the one to use for OUTFIL conditions.
You have three boxes. For the first box you say "only put in cards that have a red sticker" (INCLUDE). For the second box "only put in cards that have a blue sticker." For the third box "put in everything that's left" (SAVE). So each box gets only the cards that match its rule. INCLUDE/OMIT within OUTFIL is the same: each output file has a rule (condition), and only records that pass that rule go into that file.
1. What is INCLUDE= on an OUTFIL used for?
2. What is the difference between INCLUDE= and OMIT= on OUTFIL?
3. Do INCLUDE/OMIT on OUTFIL use the same condition syntax as the INCLUDE/OMIT control statements?
4. Can two different OUTFILs have different INCLUDE conditions?
5. When are record positions in INCLUDE= evaluated—before or after INREC/OUTREC?