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.
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).
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:
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.
The most common pattern is:
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'.
12OUTREC 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.
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.
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.
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.
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:
123OUTREC 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.
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.
1. When is WHEN=INIT processed relative to other IFTHEN WHEN types?
2. What is a typical use of WHEN=INIT?
3. Does WHEN=INIT apply to every record?
4. Can you use OVERLAY in WHEN=INIT?
5. If you omit WHEN=INIT and only use WHEN=(logexp) and WHEN=NONE, what happens to records that match a WHEN=(logexp)?