Numeric formatting in DFSORT means converting internal numeric values—packed decimal (PD), zoned decimal (ZD), or binary (BI)—into a human-readable form in the output record. Internal formats are efficient for sorting and arithmetic but not readable when printed; formatting adds commas, decimal points, signs, and optional leading zero suppression so that numbers appear as "1,234.56" or "-12,345". When you do this in OUTREC, the sort has already run on the internal value, so the order is correct and only the written record shows the formatted number. This page focuses on using edit masks and predefined masks in OUTREC for report-style output: syntax, format (PD/ZD/BI), SIGNS=, how the edited length affects the output record, and when to use OUTREC vs INREC for numeric formatting.
The sort phase compares internal numeric values (PD, ZD, BI). If you edit a numeric field in INREC, the sort sees the character result (e.g. "1,234.56"), which may not sort numerically as intended. For reports you usually want: (1) sort order based on the real number, (2) output that shows the number in a readable form. So you keep the numeric field as-is through the sort and apply numeric formatting only in OUTREC. Then the sort order is correct and the written file has comma-separated, signed, and decimal-aligned values for display or printing.
In OUTREC FIELDS= or BUILD=, an edited numeric field is specified as (position,length,format,EDIT=(pattern),SIGNS=(x,y) or (position,length,format,MaskName). Position and length are the location and size of the numeric field in the record at output time (the sorted record or INREC record). Format must be PD, ZD, or BI so DFSORT interprets the bytes correctly. EDIT=(pattern) uses I (leading digit, blank for zero), T (significant digit 0–9), S (sign), and literals (comma, period). SIGNS=(x,y) specifies the character for positive (x) and negative (y), e.g. SIGNS=(,-) for blank/plus and minus. Alternatively use a predefined mask (e.g. M11, M12) instead of EDIT=.
You must tell DFSORT how to interpret the input bytes before editing:
| Format | Meaning | When to use |
|---|---|---|
| PD | Packed decimal; compact internal form | Most common for amounts and counts |
| ZD | Zoned decimal; one digit per byte with zone | When input is zoned |
| BI | Binary (fullword/halfword) | Integer values in binary |
PD is the most common for amounts and quantities. Wrong format (e.g. specifying PD when the field is ZD) produces incorrect or garbage output. The length (e.g. 4 for a 4-byte PD) must match the actual field size.
With EDIT=(pattern), the pattern defines the output layout: I = leading insignificant digit (1–9 or blank); T = significant digit (always 0–9); S = sign (leading or trailing); commas and period are literals. Example: EDIT=(SII,III.IIT) gives a leading sign, then digits with possible leading zero suppression, comma, then three digits, period, then two digits (e.g. " 1,234.56" or "-1,234.56"). Predefined masks (M0 through M26 in many products) are shorthand: e.g. M12 for comma-separated thousands with leading sign. Use the mask name in place of EDIT=; the manual lists each mask’s pattern and length. For report output, M11 (leading zeros) or M12 (commas and sign) are often used.
The length of the edited output is the length of the pattern: each I, T, S, comma, period, or space in the pattern usually produces one byte. So the total length of the record built by OUTREC includes this edited length. You must set SORTOUT LRECL to match the total. If the pattern is 12 characters and you have 20 bytes of other data, the output is 32 bytes. Some products support LENGTH=n on the edited field to pad or truncate to n bytes; check your manual.
Sorted record: 1–10 id, 11–30 name, 31–34 amount (4-byte PD, 2 decimal places). You want output: id, 3 spaces, name, 3 spaces, amount with comma and decimal (e.g. 1,234.56).
12OUTREC FIELDS=(1,10,3X,11,20,3X,31,4,PD, EDIT=(SII,III.IIT),SIGNS=(,-))
The edited amount has a leading sign (or blank), digits with comma and decimal. Total length: 10+3+20+3+length(edited). The EDIT pattern (SII,III.IIT) is 12 characters, so total 10+3+20+3+12 = 48 bytes. SORTOUT should have LRECL=48 (or use the actual pattern length from your product).
Instead of EDIT=(...), use the mask name. For example M12 for comma-separated thousands with leading sign:
1OUTREC FIELDS=(1,10,3X,11,20,3X,31,4,PD,M12)
The output length for the amount is determined by the M12 mask definition. Check your DFSORT manual for the exact length and pattern of M12 and other masks. SIGNS= may be implied by the mask or can be specified if supported.
Use INREC when the formatted value must be used for sorting or INCLUDE/OMIT (e.g. sort by the display value or filter on "1,234"). Use OUTREC when you only need the number to look readable in the final file and the sort should use the internal value. For most report jobs, numeric formatting belongs in OUTREC so that sort order is numeric and the output is human-readable.
Imagine you have a list of numbers that the computer keeps in a special short form (like 1234567). When you sort the list, the computer uses that short form so the order is correct. When you write the list on a piece of paper for people to read, you want to write the numbers the long way: "1,234,567" with commas so it’s easy to read. Numeric formatting in OUTREC is like that: we sort using the short form, and only when we write the line do we turn the number into the pretty form with commas and a decimal point. So the order is right and the printed line looks nice.
1. Why is numeric formatting often done in OUTREC rather than INREC?
2. What does the predefined mask M12 typically produce?
3. When specifying an edited field in OUTREC FIELDS=, what must you include?
4. How does an edited field affect the output record length?
5. Can you mix copied character fields and edited numeric fields in one OUTREC?