MainframeMaster

Conditional Transforms

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.

INREC Processing
Progress0 of 0 lessons

What Is a Conditional Transform?

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.

Strategies for Conditional Transforms

You can structure conditional logic in a few common ways. Choosing the right one keeps control statements simple and maintainable.

Conditional transform strategies
StrategyMeaningWhen to use
WHEN=INIT + OVERLAYBuild one base record for all; overlay only the fields that differ by conditionSame layout for all, with a few conditional changes
Multiple WHEN=(logexp) + BUILDEach record type or value gets a full BUILDCompletely different layouts per type
WHEN=(logexp) + WHEN=NONEOne or more conditions with a default (NONE) for the restBinary or few-way split with default
INCLUDE/OMIT + IFTHENFilter first, then conditionally format surviving recordsOnly 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.

Record Type in First Bytes: Multiple Branches

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.

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

One Base Layout, Selective Overlay

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.

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

Numeric Condition: Different Label by Amount

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.

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

Conditional Transform in INREC

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.

Combining Filter and Conditional Format

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.

Explain It Like I'm Five

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.

Exercises

  1. Input has record type in bytes 1–2 ('01', '02', or '99'). You want type 01 to get BUILD=(1,20,C'TYPE01',21,60), type 02 the same but C'TYPE02', and type 99 to copy 1–80. Write the IFTHEN clauses (conceptually).
  2. When is it better to use WHEN=INIT + OVERLAY instead of a full BUILD in each WHEN=(logexp)?
  3. You need to sort by a key that is built differently for header vs detail records. Should the conditional transform be in INREC or OUTREC? Why?
  4. Give an example where INCLUDE and OUTREC IFTHEN are both used: what does INCLUDE do, and what does IFTHEN do?

Quiz

Test Your Knowledge

1. What is a conditional transform in DFSORT?

  • A sort key
  • Applying different BUILD or OVERLAY to records depending on a condition (e.g. record type or field value)
  • Only INCLUDE
  • A type of merge

2. When should you use multiple IFTHEN WHEN=(logexp) clauses instead of one WHEN=NONE?

  • Never
  • When you have several distinct conditions, each requiring a different BUILD or OVERLAY (e.g. record type A, B, C each with its own layout)
  • Only for WHEN=INIT
  • When=NONE is always enough

3. What is the advantage of OVERLAY over a full BUILD in a conditional branch?

  • OVERLAY is always faster
  • OVERLAY changes only specified positions; the rest of the record is unchanged, so you avoid repeating the whole record layout
  • BUILD cannot be used in IFTHEN
  • Only BUILD supports constants

4. Can you combine INCLUDE/OMIT with conditional OUTREC?

  • No
  • Yes—INCLUDE/OMIT filter which records are processed; OUTREC IFTHEN then formats each surviving record conditionally
  • INCLUDE replaces OUTREC
  • Only OMIT works with OUTREC

5. Why use conditional transform in INREC instead of OUTREC?

  • You cannot use conditional transform in INREC
  • When the transformed record must be used for sorting or INCLUDE/OMIT (INREC runs before sort)
  • OUTREC is always better
  • Only for MERGE