Post-sort record formatting means changing the layout and content of each record after the sort (or merge) has run, when DFSORT is writing records to SORTOUT. At that point the order of records is already fixed; formatting does not change order or record count—it only changes what is written in each record: which fields appear, in what order, with what padding, and with what conversions (e.g. edit masks, character translation). You do post-sort formatting with the OUTREC control statement (or with build options in OUTFIL). This page explains when and why to format after the sort, how it fits with INREC and the sort phase, what you can do (reorder columns, insert constants, edit numbers, add sequence numbers), and how the SORTOUT record length is determined.
The DFSORT pipeline is: read SORTIN → (optional) INCLUDE/OMIT → (optional) INREC → SORT or MERGE → (optional) SUM → (optional) OUTREC → write SORTOUT. Post-sort formatting happens in the step just before write: OUTREC is applied to each record as it is about to be written. So the record OUTREC sees is the one that came out of the sort (or merge), or the INREC record if INREC was used—already in final order. OUTREC does not see the original SORTIN layout unless you did not use INREC; and OUTREC cannot add or remove records or change their order. It only changes the content and length of each record that is written.
You typically want two different things: (1) Sort order based on real data (or on a key built in INREC). (2) Output layout suited to a report, a downstream program, or a file format. If you did all formatting in INREC, the sort would run on the reformatted record—which is sometimes what you want (e.g. sort by an edited or converted field). Often you want the sort to use the original (or INREC) data and only the written file to have a new layout. That is exactly what post-sort formatting does: the sort phase uses one record layout; the write phase uses OUTREC to produce another. So you get correct order and a report-ready or program-ready output without affecting how the sort compared records.
OUTREC FIELDS= or BUILD= (and OVERLAY, IFTHEN) support:
| Use case | Meaning | How |
|---|---|---|
| Report columns | Reorder and align fields for a readable report | FIELDS=(col1, col2, nX, col3, ...) |
| Formatted numbers | Show amounts with commas and decimals | Edit masks (EDIT= or predefined M masks) in FIELDS= |
| Sequence numbers | Add line or record numbers in output | OVERLAY or BUILD with SEQNUM |
| Shorter output | Drop unneeded fields for downstream | FIELDS= with only the positions you need |
| Constants and labels | Insert fixed text or blanks | C'...', nX, nZ in FIELDS= |
You can also use TRAN= for character conversion (e.g. LTOU, UTOL, ETOA), OVERLAY to patch or mask specific positions, and IFTHEN to apply different formatting by record type. So post-sort formatting covers report columns, formatted numbers, sequence numbers, shorter records, constants, and conditional layouts. The related tutorials (field reordering, numeric formatting, edit masks, headers/trailers) go into each in depth.
INREC runs before the sort. So the sort key and INCLUDE/OMIT see the INREC record. If you shorten the record in INREC, less data is sorted and you may save time and space. If you build a sort key in INREC, the sort uses that key. OUTREC runs after the sort. So the sort has already produced the final order; OUTREC only shapes what gets written. If you use both, the record that OUTREC sees is the INREC record (after sort), not the original SORTIN. So OUTREC positions in FIELDS= or BUILD= refer to that post-INREC, post-sort record. For example if INREC produced a 50-byte record, OUTREC (1,10) means the first 10 bytes of that 50-byte record. Plan your positions accordingly.
Sorted record: bytes 1–10 = id, 11–30 = name, 31–38 = amount (PD). You want output: id, 5 spaces, name, 5 spaces, amount edited with commas (e.g. 1,234.56). You sort on the original (or INREC) record; then OUTREC builds the report line:
123SORT FIELDS=(1,10,CH,A) OUTREC FIELDS=(1,10,5X,11,20,5X,31,4,PD,EDIT=(TTTT,TTT.TT), SIGNS=(,-))
The sort order is by bytes 1–10 (id). The written record has id, 5 blanks, 20 bytes of name, 5 blanks, then the amount in edited form. So you get the right order and a readable layout. SORTOUT LRECL must match the total length of the OUTREC output.
The length of each record written to SORTOUT is the length of the record that OUTREC builds. So you must set the SORTOUT dataset LRECL (and RECFM) to match. If OUTREC FIELDS= produces 100 bytes, use LRECL=100. If you use variable-length OUTREC (e.g. with VB), the RDW is handled by the product. Do not allocate SORTOUT with a fixed length smaller than the OUTREC output or you will get truncation or errors.
Use INREC when the reformatted data must be used for sorting or filtering: e.g. build a composite key, shorten the record for sort, or normalize a field so INCLUDE/OMIT can compare it. Use OUTREC when you only need the new layout in the output file: report columns, edit masks, sequence numbers, or a shorter record for a downstream program. If you need both—e.g. INREC to build a sort key and shorten the record, OUTREC to add report formatting and sequence numbers—use both; the sort sees INREC, and SORTOUT gets the OUTREC record.
Imagine you have sorted a pile of cards by name. The order is done. Now you want to write the list on a new sheet of paper in a nice format: first the name, then a few spaces, then the number, with commas in the number. You don’t change the order of the cards—you just copy each card onto the sheet in that pretty format. Post-sort record formatting is like that: the sort already decided the order; we only change how each line looks when we write it. We might put columns in a different order, add spaces, or turn a number like 1234567 into "1,234,567" so it’s easier to read.
1. When is post-sort record formatting applied in DFSORT?
2. Why use OUTREC for report layout instead of INREC?
3. What can you do with post-sort formatting (OUTREC)?
4. Does post-sort formatting change the number or order of records?
5. If you use both INREC and OUTREC, what does OUTREC see?