Conditional output formatting in DFSORT means applying different output layouts or overlays to different records when writing the final result—so the same sort step can produce one stream where record type A has one format, type B another, and everything else a default. You do this in two main ways: (1) OUTREC IFTHEN with WHEN=INIT, WHEN=(logical expression), WHEN=NONE, and WHEN=ANY, using BUILD or OVERLAY per branch; or (2) multiple OUTFIL statements, each with its own INCLUDE/OMIT and BUILD/FIELDS, so different record types go to different output files with different formats. This page focuses on the output side: when to use each WHEN type, how to combine WHEN=INIT with OVERLAY for maintainable layouts, and when to choose OUTFIL INCLUDE/OMIT vs a single stream with IFTHEN.
In many batch jobs, the input has mixed record types (e.g. headers, details, trailers) or values that require different display formats. You might want to mask a field only when it contains sensitive data, format amounts with commas only for detail records, or write headers to one file and details to another with different column layouts. Doing this in the same SORT step avoids multiple passes and keeps logic in one place. Conditional output formatting lets you choose the output layout or overlay based on a condition evaluated at output time (after the sort).
OUTREC IFTHEN takes a list of clauses. Each clause has a WHEN= part and an action (BUILD= or OVERLAY= or FINDREP=). The WHEN types are:
| WHEN type | Purpose | Order |
|---|---|---|
| WHEN=INIT | Apply BUILD/OVERLAY to all records first | Processed first (with WHEN=GROUP) |
| WHEN=(logexp) | Apply BUILD/OVERLAY if logical expression is true | Evaluated in order; first match typically wins |
| WHEN=NONE | Apply to records that matched no WHEN=(logexp) | Default/else branch |
| WHEN=ANY | Apply to records that matched at least one WHEN=(logexp) | After WHEN=(logexp) evaluation |
WHEN=INIT runs first and applies to every record. Use it to establish the base output (e.g. copy the full record or build a standard layout). Then add WHEN=(logexp) clauses for specific conditions—e.g. WHEN=(1,2,CH,EQ,C'01') for record type 01—with OVERLAY to change only the positions that differ, or BUILD to replace the whole record for that type. WHEN=NONE applies to records that did not match any WHEN=(logexp); it is the default branch. WHEN=ANY applies to all records that matched at least one WHEN=(logexp); use it to apply a common overlay (e.g. add a flag) to every record that "hit" any condition. Order of evaluation is INIT (and GROUP) first, then WHEN=(logexp) in order (first match often wins unless you use options like HIT=NEXT), then NONE and ANY as defined by the product.
Start with an 80-byte record for everyone; then overlay position 30–34 with '*****' only when position 5 is 'X':
12OUTREC IFTHEN=(WHEN=INIT,BUILD=(1,80)), IFTHEN=(WHEN=(5,1,CH,EQ,C'X'),OVERLAY=(30:C'*****'))
Every record gets 1–80 first. Records with byte 5 = 'X' then get the overlay at 30–34. Others are unchanged. Using OVERLAY in the WHEN clause avoids repeating the full BUILD.
Different output for different record types: first 3 bytes 'ABC' → append 'FOUND_ABC'; otherwise append 'NO_MATCH':
12OUTREC IFTHEN=(WHEN=(1,3,CH,EQ,C'ABC'),BUILD=(1,20,C'FOUND_ABC')), IFTHEN=(WHEN=NONE,BUILD=(1,20,C'NO_MATCH'))
Records matching the condition get 20 bytes from input plus 'FOUND_ABC'. All others get 20 bytes plus 'NO_MATCH'. You must specify the field type in the condition (e.g. CH for character); omitting it can cause format errors.
Format differently based on a numeric field (e.g. 4-byte zoned at position 10): over 1000 vs 1000 or less:
12OUTREC IFTHEN=(WHEN=(10,4,ZD,GT,1000),BUILD=(1,10,C'OVER_1000')), IFTHEN=(WHEN=(10,4,ZD,LE,1000),BUILD=(1,10,C'UNDER_1000'))
Each branch uses a full BUILD here; for long records you could use WHEN=INIT and OVERLAY to change only a small part.
When you want different record types in different files (not just different formats in one stream), use multiple OUTFIL statements. Each OUTFIL can have INCLUDE=(condition) or OMIT=(condition) so only matching records go to that output, and its own BUILD= or FIELDS= to format those records. Example: headers (type 01) to one file, details (type 02) to another, each with a different layout:
12OUTFIL FNAMES=HEADER,INCLUDE=(1,2,CH,EQ,C'01'),BUILD=(1,80) OUTFIL FNAMES=DETAIL,INCLUDE=(1,2,CH,EQ,C'02'),BUILD=(1,10,15,30,45,20)
Records with bytes 1–2 = '01' go to HEADER with 80-byte copy; records with '02' go to DETAIL with a shorter built layout. JCL must define HEADER and DETAIL. Records that match neither are not written to either OUTFIL (they may still go to SORTOUT if you have no INCLUDE/OMIT on SORTOUT; with OUTFIL only, often only matching records are written).
Use OUTREC IFTHEN when all records (or the subset you care about) go to a single output and you want different layouts or overlays by condition in that one stream. Use multiple OUTFIL with INCLUDE/OMIT when you want to split records by type (or value) into different files, each with its own format. You can combine both: one OUTFIL that uses IFTHEN to format different record types differently in the same file.
Imagine you have a stack of cards: some are blue, some red, some green. When you copy them onto a new sheet, you want blue cards to have a star at the top, red cards to have a circle, and green cards to look like the original. Conditional output formatting is the rule that says: "For each card, look at the color (the condition); then write it in the right way (the format)." WHEN=INIT is like drawing the same border for every card first; then we add the star or circle only for the right color. When we put blue cards in one pile and red in another, each with its own shape, that’s like multiple OUTFILs with INCLUDE—different piles (files) with different rules.
1. What is WHEN=INIT used for in OUTREC IFTHEN?
2. When is WHEN=NONE applied?
3. How can you write different record types to different output files with different formats?
4. What is WHEN=ANY used for?
5. In OUTREC IFTHEN, why use OVERLAY in a WHEN=(logexp) instead of a full BUILD?