MainframeMaster

INCLUDE/OMIT Within OUTFIL

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.

OUTFIL Advanced
Progress0 of 0 lessons

Why Filter Per OUTFIL?

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)

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':

text
1
OUTFIL 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)

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):

text
1
OUTFIL 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.

Condition Syntax in Detail

The condition is (position, length, format, operator, value):

  • Position — Starting byte of the field (1-based). This refers to the record at output time (after INREC and sort).
  • Length — Length of the field in bytes.
  • Format — How to interpret the bytes: CH (character), ZD (zoned decimal), PD (packed decimal), BI (binary), etc. Use the format that matches your data so comparisons are correct (e.g. numeric order for ZD/PD, character order for CH).
  • Operator — EQ (equal), NE (not equal), GT (greater than), LT (less than), GE (greater or equal), LE (less or equal).
  • Value — Constant to compare against: C'...' for character, numeric literal for ZD/PD/BI (e.g. 100, 0).
Common format codes in INCLUDE/OMIT conditions
FormatUseExample
CHCharacter. Compare as EBCDIC character(1,10,CH,EQ,C'ABC')
ZDZoned decimal. Signed numeric comparison(20,4,ZD,GT,100)
PDPacked decimal. Signed numeric comparison(24,4,PD,LE,500)
BIBinary. Fullword or halfword comparison(30,4,BI,NE,0)

Numeric Comparisons

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:

text
1
OUTFIL 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.

Multiple OUTFILs with Different Conditions

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:

text
1
2
3
4
OUTFIL 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.

Record Layout: Output Phase

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.

Explain It Like I'm Five

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.

Exercises

  1. Write an OUTFIL that writes only records where bytes 40–44 (character) equal 'NORTH' to DD name REGIONN.
  2. Write an OUTFIL that writes all records except those where byte 1 is '*' (comment records). Use OMIT=.
  3. You have record types in bytes 1–2: '01' header, '02' detail, '03' trailer. Write three OUTFILs (one per type) and a fourth with SAVE. Where do records with '04' go?
  4. Why use ZD instead of CH for a numeric field in an INCLUDE condition?

Quiz

Test Your Knowledge

1. What is INCLUDE= on an OUTFIL used for?

  • To include all records
  • To write only records that satisfy the condition to this OUTFIL's dataset
  • To include the DD name
  • To include BUILD

2. What is the difference between INCLUDE= and OMIT= on OUTFIL?

  • They are the same
  • INCLUDE= writes records that match the condition; OMIT= writes records that do not match the condition
  • OMIT= is for SORTOUT only
  • INCLUDE= is for reports only

3. Do INCLUDE/OMIT on OUTFIL use the same condition syntax as the INCLUDE/OMIT control statements?

  • No
  • Yes. (position,length,format,operator,value) e.g. (30,5,CH,EQ,C'DEPT1')
  • Only for SORT
  • Only numeric

4. Can two different OUTFILs have different INCLUDE conditions?

  • No
  • Yes. Each OUTFIL has its own INCLUDE= or OMIT=; so one can select DEPT1, another DEPT2, etc.
  • Only the first OUTFIL
  • Only with SAVE

5. When are record positions in INCLUDE= evaluated—before or after INREC/OUTREC?

  • Before only
  • After INREC and sort; INCLUDE/OMIT on OUTFIL see the record as it is at output time (after INREC and any OUTREC)
  • Only after OUTREC
  • Positions are always input