Conditional sequencing in DFSORT means assigning sequence numbers only when a condition is true. For example, you might want line numbers 1, 2, 3, … only on detail records in a report, while header and trailer records show blanks or a fixed label in the sequence field. Or you might want different START= or INCR= values for different record types (e.g. type A numbered from 100, type B from 1000). You achieve this by combining SEQNUM with IFTHEN in OUTREC or INREC: the WHEN clause that matches the records you want numbered contains SEQNUM; other WHEN clauses overlay the sequence field with spaces or a constant so those records do not get a number. This page explains how to apply SEQNUM conditionally, how the counter behaves when some records are skipped, and when to use INREC vs OUTREC.
A single running sequence (1, 2, 3, … for every record) is what you get with a plain SEQNUM in OUTREC or INREC. In reports you often need:
Conditional sequencing uses IFTHEN to apply SEQNUM only in the WHEN clause(s) where you want a number; in other WHEN clauses you overlay the same output position with blanks or a constant so that the counter is not "used" for those records (or you use a separate counter per type).
Suppose the record type is in byte 1: H = header, D = detail, T = trailer. You want a 5-byte sequence number at position 21 only for detail records; headers and trailers should have blanks at 21–25. Sort first, then in OUTREC use IFTHEN so that only when byte 1 is "D" do you put SEQNUM there; otherwise overlay 21–25 with spaces.
12345SORT FIELDS=(2,10,CH,A) OUTREC IFTHEN=(WHEN=INIT,BUILD=(1:1,80)), IFTHEN=(WHEN=(1,1,CH,EQ,C'D'), OVERLAY=(21:SEQNUM,5,ZD)), IFTHEN=(WHEN=NONE,OVERLAY=(21:5C' '))
WHEN=INIT copies the full record (1–80). The second IFTHEN applies when byte 1 equals D: it overlays positions 21–25 with SEQNUM,5,ZD. The third IFTHEN, WHEN=NONE, catches any record that did not match the previous WHEN (i.e. H and T): it overlays 21–25 with five spaces. So only detail records get a number; the sequence counter increments only for those records. The first detail gets 1, the second gets 2, and a header or trailer in between does not get a number and does not advance the counter.
When SEQNUM appears inside a WHEN clause, only records that satisfy that WHEN receive a value from the counter and advance it. Records that hit WHEN=NONE or another WHEN that does not contain SEQNUM do not advance the counter. So you get one running sequence for all records that actually get SEQNUM—ideal for "number only the detail lines" in report order.
| Record | WHEN matched | Effect on sequence field and counter |
|---|---|---|
| Header (H) | WHEN=NONE | Overlay blanks; counter unchanged. |
| Detail 1 (D) | WHEN=(1,1,CH,EQ,C'D') | Gets 1; counter advances to 2. |
| Detail 2 (D) | WHEN=(1,1,CH,EQ,C'D') | Gets 2; counter advances to 3. |
| Trailer (T) | WHEN=NONE | Overlay blanks; counter unchanged (still 3). |
| Detail 3 (D) | WHEN=(1,1,CH,EQ,C'D') | Gets 3; counter advances to 4. |
If you want type A records numbered 100, 101, 102, … and type B records numbered 1000, 1001, 1002, …, use separate IFTHEN clauses. Each WHEN that contains its own SEQNUM maintains a separate counter. So one clause can have SEQNUM,5,ZD,START=100 and another SEQNUM,5,ZD,START=1000. Each applies only to its record type and increments independently.
1234OUTREC IFTHEN=(WHEN=INIT,BUILD=(1:1,80)), IFTHEN=(WHEN=(1,1,CH,EQ,C'A'),OVERLAY=(21:SEQNUM,5,ZD,START=100)), IFTHEN=(WHEN=(1,1,CH,EQ,C'B'),OVERLAY=(21:SEQNUM,5,ZD,START=1000)), IFTHEN=(WHEN=NONE,OVERLAY=(21:5C' '))
Type A records get 100, 101, 102, … in the order they appear. Type B records get 1000, 1001, 1002, … in the order they appear. Headers or other types (WHEN=NONE) get blanks. The two sequences are independent.
Use OUTREC when you want the sequence to reflect final output order—e.g. report line numbers only on detail lines after the sort. Use INREC when you need conditional numbering before the sort or filter: for example, only detail records get a sequence number in input order, and you later SORT by that number (and other keys) to restore or preserve order. For most "report with line numbers only on details," OUTREC with IFTHEN is the right choice.
| Phase | Use when |
|---|---|
| OUTREC | Sequence should reflect sorted/output order; e.g. line numbers only on detail lines in the report. |
| INREC | Numbering must be in input order or must be visible to INCLUDE/OMIT or SORT (e.g. preserve original order within a group). |
You can combine conditional SEQNUM with RESTART=. For example, only detail records get a sequence number, and that number resets when a control field (e.g. order id) changes. Use RESTART= in the same WHEN clause that contains SEQNUM: e.g. OVERLAY=(21:SEQNUM,5,ZD,RESTART=(2,10)) inside the WHEN for detail records. Then only details are numbered, and the sequence resets at each new value of bytes 2–11 (e.g. order id). The file must be sorted by that control field so groups are contiguous.
IFTHEN is evaluated in order. Typically you use WHEN=INIT first to establish the base record, then one or more WHEN=(condition) clauses for record types that get SEQNUM, and finally WHEN=NONE to handle any remaining records (e.g. headers/trailers) with blanks or a constant. Ensure the condition for "numbered" records is specific enough that only the intended records get SEQNUM; WHEN=NONE catches everything that did not match a previous WHEN.
Imagine numbering only the apples in a row that has apples, labels, and a "end of box" card. You do not want to put a number on the label or the end card—only on the apples. So you have a rule: "If it's an apple, give it the next number (1, 2, 3…). If it's not an apple, leave the number spot blank." Conditional sequencing is the same: only the records that match your "detail" rule get a number; the rest get a blank or a label so the printed list shows numbers only where you want them.
1. You want sequence numbers only on detail records (byte 1 = "D"), not on header or trailer records. How do you do it?
2. If you use IFTHEN WHEN=(1,1,CH,EQ,C'D') with SEQNUM for details and WHEN=NONE with OVERLAY=(21:20C' ') for others, what happens to the sequence counter for header records?
3. Where should you add conditional SEQNUM when you need final report order line numbers only on detail lines?
4. Can you use different START= or INCR= for different record types in one DFSORT step?
5. What is a typical use for conditional sequencing?