MainframeMaster

IFTHEN Clauses

IFTHEN in DFSORT lets you apply conditional reformatting: different record layouts or overlays depending on whether each record meets specified conditions. Instead of one BUILD or FIELDS= that applies to every record, you can say "when bytes 1–3 equal 'HDR', build the record this way; when they equal 'DTL', build it that way; otherwise use a default." IFTHEN clauses are available in INREC, OUTREC, and OUTFIL. Each clause has a WHEN type (such as WHEN=INIT or WHEN=(logical expression)) and an action (BUILD, OVERLAY, or FINDREP). This page is an overview of what IFTHEN clauses are, where they can be used, and how they fit into the conditional processing topics (WHEN=INIT, WHEN=GROUP, WHEN=ANY, WHEN=NONE).

Conditional Processing
Progress0 of 0 lessons

What IFTHEN Clauses Do

Without IFTHEN, a single INREC or OUTREC specification (e.g. FIELDS= or BUILD=) applies the same reformatting to every record. That is fine when all records have the same layout. When different record types need different treatment—for example, header records get one format, detail records another, or records with an invalid date get a default value overlay—you need conditional logic. IFTHEN clauses provide that: each clause has a WHEN part (who gets this treatment) and an action part (what to do). DFSORT evaluates the WHEN conditions and applies the matching clause's BUILD, OVERLAY, or FINDREP. So IFTHEN is the way you implement "if this record matches condition A, reformat it one way; if it matches B, reformat it another way; else use a default."

IFTHEN does not remove records. Filtering is done by INCLUDE and OMIT. IFTHEN only changes the content or layout of records that pass through. Every record that reaches INREC or OUTREC is still written (unless you use other means to drop it); IFTHEN just decides how that record is built or overlayed.

Where IFTHEN Can Be Used

IFTHEN usage by control statement
StatementPhaseEffect
INRECInput phase (before sort)Reformatted record is used for INCLUDE/OMIT and for the sort. Use when the conditional layout must affect filtering or sort keys.
OUTRECOutput phase (after sort)Reformatted record is what is written to SORTOUT. Use when you only need conditional formatting in the final output.
OUTFILOutput phase (additional outputs)IFTHEN can be used in OUTFIL build/overlay for each FNAMES= file. Use for conditional formatting on report or split files.

Choosing INREC vs OUTREC matters when the result of the condition affects what you sort on or what you filter. For example, if you want to overlay a field that is part of the sort key, or if INCLUDE/OMIT must see the reformatted record, use INREC IFTHEN. If you only need to change the way the final output looks (e.g. add a label in the first 9 bytes based on a numeric field), OUTREC IFTHEN is enough.

Structure of an IFTHEN Clause

Each IFTHEN clause has two main parts: the WHEN type and the action. The WHEN type determines which records the clause applies to. The action is what to do: BUILD (construct a new record), OVERLAY (change specific positions), or FINDREP (find/replace). Syntax pattern:

text
1
2
IFTHEN=(WHEN=type,action), IFTHEN=(WHEN=type,action), ...

The WHEN types are:

  • WHEN=INIT — Apply to all records; processed first. Used to set a base record (e.g. copy 1–80) before any conditional overlays. See the WHEN=INIT tutorial for details.
  • WHEN=(logical expression) — Apply only when the condition is true (e.g. field EQ constant, or numeric GT value). Same style of conditions as INCLUDE/OMIT.
  • WHEN=NONE — Apply to records that did not match any preceding WHEN=(logexp). The "else" branch.
  • WHEN=ANY — Apply to records that did match at least one preceding WHEN=(logexp). Useful for adding something extra to any record that matched. See the WHEN=ANY tutorial.
  • WHEN=GROUP — Group-level operations (e.g. sequence numbers or field multiplication within control-break groups). Processed early like WHEN=INIT. See the WHEN=GROUP tutorial.

WHEN=INIT and WHEN=GROUP are processed before the others. Then DFSORT evaluates WHEN=(logexp) and WHEN=NONE (and WHEN=ANY) in order. By default, often only the first matching WHEN=(logexp) or WHEN=NONE is applied; HIT=NEXT allows subsequent IFTHEN clauses to be evaluated so that more than one overlay can apply to the same record.

BUILD vs OVERLAY

Inside a clause you specify the action:

  • BUILD=(...) — Constructs a new record from the items you list (input positions, constants, edit masks, etc.). The entire output record for that branch is defined by BUILD. Use when you want a completely different layout for records that match the condition.
  • OVERLAY=(...) — Does not rebuild the whole record. You specify one or more position:value pairs. Only those positions are changed; the rest of the record stays as it was. Use when you want to patch one or a few fields (e.g. replace an invalid date with a default) and leave the rest unchanged. OVERLAY is often used after WHEN=INIT has built a base record.
  • FINDREP — Find-and-replace within the record (when supported). Useful for replacing a string or pattern.

Example: "Copy the full record, but when the 4-byte zoned decimal at position 10 is greater than 1000, overlay position 1 with the constant 'HIGH'." You would use WHEN=INIT with BUILD=(1,80) to copy the record, then a second IFTHEN with WHEN=(10,4,ZD,GT,1000) and OVERLAY=(1:C'HIGH') to change the first bytes only when the condition holds.

Logical Expressions in WHEN=(logexp)

The condition in WHEN=(logexp) uses the same syntax as INCLUDE and OMIT: you specify the field (position, length, format), a comparison operator, and a value. Format can be CH (character), ZD (zoned decimal), PD (packed decimal), BI (binary), etc. Operators include EQ, NE, LT, LE, GT, GE. The value can be a constant (e.g. C'ABC' for character, or a number for numeric) or a reference to another field. Examples:

  • WHEN=(1,3,CH,EQ,C'HDR') — True when the first 3 bytes are the character constant 'HDR'.
  • WHEN=(10,4,ZD,GT,1000) — True when the 4-byte zoned decimal at position 10 is greater than 1000.
  • WHEN=(20,8,PD,LE,0) — True when the 8-byte packed decimal at position 20 is less than or equal to zero.

You can combine conditions with AND/OR in the logical expression when your DFSORT version supports it; see the comparison operators and complex conditional expressions tutorials for advanced logic.

Example: Two Record Types with WHEN=NONE

Suppose the first byte indicates record type: '1' for header, '2' for detail. You want headers to be 30 bytes (first 30 from input) and details to be 80 bytes (first 80 from input). Records that are neither get a default 20-byte layout. You can do this with three IFTHEN clauses:

text
1
2
3
OUTREC IFTHEN=(WHEN=(1,1,CH,EQ,C'1'),BUILD=(1,30)), IFTHEN=(WHEN=(1,1,CH,EQ,C'2'),BUILD=(1,80)), IFTHEN=(WHEN=NONE,BUILD=(1,20))

The first clause applies when byte 1 is '1'; the second when byte 1 is '2'; the third (WHEN=NONE) applies to any record that did not match the first two. So every record gets exactly one of the three layouts.

Example: Base Record Plus Conditional Overlay

A common pattern is WHEN=INIT to build a base record for everyone, then one or more WHEN=(logexp) with OVERLAY to change specific fields when conditions hold:

text
1
2
OUTREC IFTHEN=(WHEN=INIT,BUILD=(1:1,80)), IFTHEN=(WHEN=(72,10,CH,EQ,C'9999-99-99'),OVERLAY=(72:C'0001-01-01'))

Every record gets the full 80 bytes copied (WHEN=INIT). Then, if the 10 bytes at position 72 equal the invalid-date sentinel '9999-99-99', those 10 bytes are replaced with '0001-01-01'. So you get a default date for invalid values without rebuilding the whole record.

HIT=NEXT for Multiple Clauses on One Record

By default, after a WHEN=(logexp) or WHEN=NONE matches and its action is applied, DFSORT often does not evaluate further IFTHEN clauses for that record. If you need more than one clause to apply (e.g. overlay position 72 when one condition holds and position 82 when another holds), add HIT=NEXT to the first clause so that processing continues to the next IFTHEN. Then both overlays can be applied to the same record when both conditions are true.

Relationship to Other Conditional Topics

This page is the overview of IFTHEN clauses. The following pages go deeper into specific WHEN types and patterns:

  • WHEN=INIT — How to use INIT to set a base record for all records, and typical patterns with OVERLAY.
  • WHEN=GROUP — Group-level operations (sequence numbers, field multiplication within groups) and when to use GROUP.
  • WHEN=ANY — Applying formatting to any record that already matched a WHEN=(logexp).
  • Nested IFTHEN logic and Complex conditional workflows — Multiple conditions, AND/OR, and advanced patterns.

For detailed IFTHEN examples in INREC and OUTREC (BUILD, OVERLAY, and the five WHEN types), see the IFTHEN Logic in INREC tutorial in the INREC Processing section.

Explain It Like I'm Five

Imagine you have a pile of cards. Some cards have "A" at the top, some have "B," and some have something else. IFTHEN is like having different rules: "If the card has A, write the first 20 letters on a new card; if it has B, write the first 50 letters; if it has anything else, write the first 10 letters." So the computer looks at each card, checks which rule fits, and then does that rule. No cards are thrown away—every card gets a new version. WHEN=INIT is like saying "first, copy every card," and then the other rules only change some of the copies (e.g. add a sticker in one corner when the card has A). That way different cards get different treatment without needing a separate machine for each kind of card.

Exercises

  1. You want to overlay position 1 with 'HEADER' when byte 1 is 'H', and with 'DETAIL' when byte 1 is 'D'. Write two IFTHEN clauses for OUTREC (assume WHEN=INIT has already built the full record).
  2. When would you put IFTHEN in INREC instead of OUTREC? Give one concrete scenario.
  3. What is the purpose of WHEN=NONE? Write a one-line example (pseudocode) where it is used.
  4. What does OVERLAY do that BUILD does not? When would you choose OVERLAY over BUILD for a conditional clause?

Quiz

Test Your Knowledge

1. Where can IFTHEN clauses be used in DFSORT?

  • Only in OUTREC
  • Only in INREC
  • In INREC, OUTREC, and OUTFIL
  • Only in OUTFIL

2. What is the main purpose of an IFTHEN clause?

  • To filter out records (like INCLUDE/OMIT)
  • To apply different BUILD, OVERLAY, or FINDREP actions depending on whether a record meets a condition
  • To change sort order
  • To merge two files

3. What is the difference between BUILD and OVERLAY inside an IFTHEN clause?

  • BUILD is for INREC only, OVERLAY for OUTREC only
  • BUILD constructs a new record from scratch; OVERLAY modifies specific positions and leaves the rest unchanged
  • They are the same
  • OVERLAY is for headers only

4. When should you use IFTHEN in INREC rather than OUTREC?

  • Always use INREC; OUTREC does not support IFTHEN
  • When the conditionally reformatted record must be used for sorting or for INCLUDE/OMIT (INREC runs before sort)
  • Only when the file is very large
  • When you need OVERLAY

5. Which WHEN type is processed first for every record?

  • WHEN=NONE
  • WHEN=(logical expression)
  • WHEN=INIT (and WHEN=GROUP); they run before other WHEN types
  • WHEN=ANY