A conditional transform in DFSORT means applying different reformatting to different records depending on a condition—for example, record type, a field value, or whether a field is blank. You might want header records in one format, detail records in another, or to mask a field only when it contains a sentinel value. You implement conditional transforms with IFTHEN in INREC or OUTREC: multiple WHEN= clauses (WHEN=INIT, WHEN=(logical expression), WHEN=NONE, WHEN=ANY) and either BUILD= (full record) or OVERLAY= (change only specific positions). This page focuses on patterns and strategies: when to use one base layout with OVERLAY vs multiple BUILD branches, how to combine conditions, and when to do conditional transform in INREC vs OUTREC.
In a simple INREC or OUTREC, the same BUILD or FIELDS applies to every record. A conditional transform means "if this record meets condition A, apply layout A; if it meets condition B, apply layout B; otherwise apply default layout." The condition is usually based on a field value (e.g. first 2 bytes = '01' for header, '02' for detail) or a numeric test (e.g. amount > 1000). The result is that different record types or values get different output layouts or overlays without needing a separate sort step per type. Conditional transforms are done with IFTHEN; the same WHEN types (INIT, logexp, NONE, ANY, GROUP) and BUILD/OVERLAY apply in both INREC and OUTREC.
You can structure conditional logic in a few common ways. Choosing the right one keeps control statements simple and maintainable.
| Strategy | Meaning | When to use |
|---|---|---|
| WHEN=INIT + OVERLAY | Build one base record for all; overlay only the fields that differ by condition | Same layout for all, with a few conditional changes |
| Multiple WHEN=(logexp) + BUILD | Each record type or value gets a full BUILD | Completely different layouts per type |
| WHEN=(logexp) + WHEN=NONE | One or more conditions with a default (NONE) for the rest | Binary or few-way split with default |
| INCLUDE/OMIT + IFTHEN | Filter first, then conditionally format surviving records | Only format certain records and still need different layouts among them |
WHEN=INIT + OVERLAY: Build one base record (e.g. copy 1–80) for everyone in WHEN=INIT. Then use WHEN=(logexp) only to OVERLAY the positions that must change (e.g. mask bytes 45–47 when dept = 'dept1'). You avoid repeating the full BUILD in every branch. Multiple WHEN=(logexp) + BUILD: Use when each record type has a completely different layout (different fields, order, or length). Each branch has its own BUILD. WHEN=NONE is the default for records that did not match any WHEN=(logexp). INCLUDE/OMIT + IFTHEN: First filter which records are kept; then apply IFTHEN to format the survivors differently by type or value.
A common case is a record type code in the first few bytes (e.g. 1–2). Headers (e.g. 'H1') get one layout, details ('D1') another, trailers ('T1') another. You implement this with multiple IFTHEN clauses, one per type, and WHEN=NONE for unknown types.
1234OUTREC IFTHEN=(WHEN=(1,2,CH,EQ,C'H1'),BUILD=(1,10,C'HEADER',11,70)), IFTHEN=(WHEN=(1,2,CH,EQ,C'D1'),BUILD=(1,5,21,50,6,15)), IFTHEN=(WHEN=(1,2,CH,EQ,C'T1'),BUILD=(1,10,C'TRAILER',11,70)), IFTHEN=(WHEN=NONE,BUILD=(1,80))
The first clause applies when bytes 1–2 are 'H1'; the output is 10 bytes from input, then 'HEADER', then 70 bytes from input. The second applies for 'D1' (different BUILD), the third for 'T1', and WHEN=NONE copies the full record for any other type. Order of WHEN=(logexp) matters if a record could match more than one; the first match wins unless you use HIT=NEXT.
When all records share the same layout and only a few fields change by condition (e.g. mask a field for a certain department), use WHEN=INIT to build the full record once, then OVERLAY in WHEN=(logexp) to change only those positions.
123OUTREC IFTHEN=(WHEN=INIT,BUILD=(1:1,80)), IFTHEN=(WHEN=(30,5,CH,EQ,C'dept1'),OVERLAY=(45:C'***')), IFTHEN=(WHEN=(30,5,CH,EQ,C'dept2'),OVERLAY=(45:C'XXX'))
Every record gets the base 80-byte layout from WHEN=INIT. Records with dept1 get bytes 45–47 overwritten with '***'; records with dept2 get 'XXX'; others keep the original bytes 45–47. You do not duplicate the 80-byte BUILD in each branch.
You can drive the transform from a numeric field—for example, a 4-byte packed amount at position 20. Records with amount > 1000 get one overlay, others get another.
123OUTREC IFTHEN=(WHEN=INIT,BUILD=(1,80)), IFTHEN=(WHEN=(20,4,PD,GT,1000),OVERLAY=(1:C'HIGH ')), IFTHEN=(WHEN=(20,4,PD,LE,1000),OVERLAY=(1:C'LOW '))
Base record is 1–80. When the packed decimal at 20 is greater than 1000, positions 1–7 are set to 'HIGH '; when it is less than or equal to 1000, they are set to 'LOW '. So the same record layout is used; only the label in the first 7 bytes changes.
Use INREC IFTHEN when the transformed record must be used for sorting or INCLUDE/OMIT. For example, you might build a sort key in different ways for different record types (header vs detail), or overlay a field so that INCLUDE COND= can filter on the new value. Because INREC runs before the sort, the sort and filter see the conditionally reformatted record. If you only need different formats in the final output file and the sort key is the same for all, use OUTREC IFTHEN.
You can filter with INCLUDE or OMIT and still apply conditional formatting with IFTHEN. For example: INCLUDE only records where region = 'EAST', then in OUTREC use IFTHEN to format records with amount > 1000 differently from those with amount ≤ 1000. The INCLUDE reduces which records are processed; OUTREC IFTHEN then formats each surviving record based on amount. So filter and conditional transform work together: first reduce the set, then format by type or value.
Imagine you have red cards and blue cards. For red cards you want to write "RED" at the top; for blue cards, "BLUE". A conditional transform is the rule: "Look at the card. If it's red, do this; if it's blue, do that." So the computer looks at each card and does the right action. Sometimes we do the same thing to every card first (like copy it), then only change one spot for red or blue. That way we don't have to write a whole new card for each color—we just change the part that's different.
1. What is a conditional transform in DFSORT?
2. When should you use multiple IFTHEN WHEN=(logexp) clauses instead of one WHEN=NONE?
3. What is the advantage of OVERLAY over a full BUILD in a conditional branch?
4. Can you combine INCLUDE/OMIT with conditional OUTREC?
5. Why use conditional transform in INREC instead of OUTREC?