MainframeMaster

WHEN=INIT

In DFSORT IFTHEN, WHEN=INIT is the clause that applies to all records and is processed before any other WHEN type. You use it to set a base record or common reformat for every record—for example, copy the full input record with BUILD=(1:1,80). Then other IFTHEN clauses (WHEN=(logical expression), WHEN=NONE, or WHEN=ANY) can overlay or modify only specific fields when conditions hold, without rebuilding the entire record in each branch. This page explains what WHEN=INIT does, when it runs, typical patterns (base BUILD plus conditional OVERLAY), and how it differs from other WHEN types.

Conditional Processing
Progress0 of 0 lessons

What WHEN=INIT Does

WHEN=INIT tells DFSORT: "Apply this action to every record, and do it first." There is no condition—no field comparison or record type check. So WHEN=INIT is your "initialize" or "base" step. Whatever you specify in BUILD=, OVERLAY=, or FINDREP= for the INIT clause is applied to all records before any other IFTHEN clause is evaluated. That makes it ideal for establishing a common layout (e.g. copy the full record) so that later clauses only need to change the parts that vary by condition.

If you did not have WHEN=INIT, you would have to repeat the same base BUILD in every WHEN=(logexp) and in WHEN=NONE. For example, if the base is "copy bytes 1–80," you would say BUILD=(1,80) in the first branch, BUILD=(1,80) in the second, and BUILD=(1,80) in WHEN=NONE. With WHEN=INIT you say it once: WHEN=INIT,BUILD=(1:1,80). Then the conditional clauses only overlay the bytes that differ (e.g. positions 1–9 with a label).

Processing Order

DFSORT processes IFTHEN WHEN types in a defined order. WHEN=INIT and WHEN=GROUP are processed first. So for every record, the INIT (and any GROUP) action runs. After that, WHEN=(logical expression), WHEN=NONE, and WHEN=ANY are evaluated in the order you write them. By default, often only the first matching WHEN=(logexp) or WHEN=NONE is applied (unless you use HIT=NEXT). So the sequence is:

  1. WHEN=INIT (and WHEN=GROUP if present) — applied to all records.
  2. WHEN=(logexp) and WHEN=NONE — evaluated in order; the first match (or NONE) applies.
  3. WHEN=ANY — if used, applied to records that matched at least one WHEN=(logexp).

Because INIT runs first, the record that the conditional clauses see is already the result of the INIT BUILD or OVERLAY. So a WHEN=(logexp) with OVERLAY=(72:C'0001-01-01') is overlaying on top of the record that INIT produced.

Typical Pattern: INIT Plus Conditional Overlay

The most common pattern is:

  • One IFTHEN with WHEN=INIT and BUILD=(1:1,n) (or the full build you want for the base record). That gives every record the same starting layout.
  • One or more IFTHEN with WHEN=(logexp) and OVERLAY=(position:value,...). When the condition is true, only the specified positions are changed; the rest of the record is unchanged.
  • Optionally WHEN=NONE with OVERLAY or BUILD for records that did not match any WHEN=(logexp).

Example: copy the full 80-byte record for everyone; when the 10 bytes at position 72 equal the invalid date '9999-99-99', replace them with '0001-01-01'.

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 1–80 copied (INIT). Then only records with the sentinel date at 72 get the overlay. You never rebuild the whole record in the second clause—you only patch 10 bytes.

INIT with BUILD: Full Base Record

In WHEN=INIT, BUILD=(...) defines the complete output record for this step. You can use any valid BUILD items: input positions (e.g. 1,80 or 1:1,80), constants (C'...'), edit masks, sequence numbers, etc. The result becomes the "current" record for any subsequent IFTHEN clauses. So BUILD=(1:1,80) means: take bytes 1–80 from the input (at this point the input is the record as read, or after INREC if you are in OUTREC) and make that the 80-byte base record.

If you are in INREC, the record built by WHEN=INIT (and any overlays from later clauses) is the record that INCLUDE/OMIT and the sort phase see. So INIT in INREC is the right place to establish the record layout that will be used for filtering and sorting.

INIT with OVERLAY

You can use OVERLAY= in WHEN=INIT as well. That would change specific positions for every record. For example, you might use WHEN=INIT with BUILD=(1:1,80) to copy the record, and in the same clause you could not normally add OVERLAY (BUILD and OVERLAY are alternatives in one clause). So typically WHEN=INIT has BUILD only. In a separate clause, WHEN=INIT with only OVERLAY could set certain positions to a constant for all records (e.g. clear a flag byte to zero). That is less common than INIT BUILD plus conditional OVERLAY in other clauses.

When to Omit WHEN=INIT

You do not have to use WHEN=INIT. If every record type has a completely different layout, you might use only WHEN=(logexp) and WHEN=NONE, each with its own full BUILD. For example: WHEN=(1,1,CH,EQ,C'1'),BUILD=(1,30) and WHEN=(1,1,CH,EQ,C'2'),BUILD=(1,80) and WHEN=NONE,BUILD=(1,20). There is no common base—each branch builds the whole record. WHEN=INIT is most useful when there is a common base and only some fields change by condition; then INIT builds the base once and you use OVERLAY in the conditional clauses.

Example: Label by Numeric Value

Copy the full record for everyone; then overlay the first 9 bytes with 'OVER_1000' when the 4-byte zoned decimal at position 10 is greater than 1000, and with 'UNDER_1000' otherwise. Using WHEN=NONE for the "otherwise" branch:

text
1
2
3
OUTREC IFTHEN=(WHEN=INIT,BUILD=(1:1,80)), IFTHEN=(WHEN=(10,4,ZD,GT,1000),OVERLAY=(1:C'OVER_1000 ')), IFTHEN=(WHEN=NONE,OVERLAY=(1:C'UNDER_1000'))

INIT builds 80 bytes for all. The first WHEN=(logexp) overlays 1–9 (or 10 bytes) for records with value > 1000. WHEN=NONE catches the rest and overlays with 'UNDER_1000'. Every record gets exactly one of the two overlays.

Explain It Like I'm Five

Imagine you have to prepare every card in a pile the same way first: copy the whole card onto a new sheet. That is WHEN=INIT—everyone gets that step. Then you look at each sheet: if it has a certain word, you stick a "HIGH" sticker in the corner; if not, you stick an "LOW" sticker. So the "copy the whole card" happens once for everybody (INIT), and the sticker (OVERLAY) only changes one spot and only for some cards. You don't copy the card again for the HIGH and LOW cases—you already have the copy from INIT.

Exercises

  1. Write an OUTREC with WHEN=INIT that copies 1–100, then a WHEN=(1,1,CH,EQ,C'H') that overlays position 1 with the constant 'HEADER ' (8 bytes).
  2. Why is it more efficient to use WHEN=INIT BUILD plus OVERLAY in conditional clauses than to repeat the same BUILD in every WHEN=(logexp) and WHEN=NONE?
  3. In what order does DFSORT process WHEN=INIT versus WHEN=(logexp)? What does that mean for the record that the conditional clauses see?

Quiz

Test Your Knowledge

1. When is WHEN=INIT processed relative to other IFTHEN WHEN types?

  • After WHEN=NONE
  • Only for the first record in the file
  • Before any other WHEN clause; it runs first and applies to all records
  • Only when no WHEN=(logexp) matches

2. What is a typical use of WHEN=INIT?

  • To filter out records
  • To apply a base BUILD (e.g. copy 1–80) for all records, then use OVERLAY in other clauses to change specific fields when conditions hold
  • To run only on the last record
  • To disable IFTHEN

3. Does WHEN=INIT apply to every record?

  • No; only to records that match a condition
  • Yes; WHEN=INIT applies to all records, regardless of record type or field values
  • Only to the first record of each group
  • Only when WHEN=NONE is not used

4. Can you use OVERLAY in WHEN=INIT?

  • No; WHEN=INIT only supports BUILD
  • Yes; WHEN=INIT can use BUILD, OVERLAY, or FINDREP like other WHEN types
  • Only in OUTREC
  • Only when WHEN=GROUP is also present

5. If you omit WHEN=INIT and only use WHEN=(logexp) and WHEN=NONE, what happens to records that match a WHEN=(logexp)?

  • They get no output
  • Only the BUILD or OVERLAY from the first matching WHEN=(logexp) is applied; there is no prior base record unless you build one in that clause
  • WHEN=INIT is required
  • They are deleted