You can use SUM FIELDS= and OUTFIL in the same DFSORT step. SUM runs after the sort and produces one record per group (summary records); that output is then what OUTFIL sees. So you can write the summary records to SORTOUT and at the same time use OUTFIL to add headers and trailers (e.g. TRAILER1 with COUNT= and TOTAL=) and write to one or more report datasets. This page explains the order of processing (sort → SUM → OUTFIL), what SORTOUT and OUTFIL FNAMES= receive, and how to combine SUM with OUTFIL for both a summary dataset and a report in one step.
When both SUM and OUTFIL are present, DFSORT runs: (1) Sort (and optional INREC), (2) SUM (collapse each group to one record), (3) OUTFIL (format and write to FNAMES=). So OUTFIL never sees the original detail records; it sees the summary records (one per group). SORTOUT also receives the summary records unless you use OUTFIL FNAMES=SORTOUT to replace what goes to SORTOUT with the OUTFIL output (e.g. summary records plus TRAILER1).
A common pattern is: sort by key, SUM to get one record per group, then OUTFIL to write that summary to SORTOUT and to a report DD with a header and trailer:
1234567SORT FIELDS=(1,5,CH,A) SUM FIELDS=(20,6,PD) OUTFIL FNAMES=(SORTOUT,REPORT), HEADER1=(1:'Summary by Department',/,5:DATE=(MD4-)), OUTREC=(1,80), TRAILER1=(1:'Groups: ',COUNT=(M11,LENGTH=6), ' Grand total: ',TOTAL=(20,6,PD,LENGTH=12))
SORTOUT and REPORT both get the summary records (one per department) plus the header and trailer. COUNT= in TRAILER1 is the number of summary records (groups). TOTAL= sums the 6-byte PD field at 20 across those records—which is the same as the grand total of the original amount field because each summary record holds the group total.
You can split outputs: one DD gets only the summary records (no header/trailer), another gets the report (summary records + HEADER1 + TRAILER1). Use two OUTFIL statements with different FNAMES= and different options:
12345OUTFIL FNAMES=SUMMARY,OUTREC=(1,80) OUTFIL FNAMES=REPORT, OUTREC=(1,80), HEADER1=(1:'Report',/), TRAILER1=(1:'Total groups: ',COUNT=(M11,LENGTH=6))
SUMMARY gets 80-byte summary records only. REPORT gets the same records plus a one-line header and a trailer with the count of groups.
After SUM, the record stream has one record per group. So COUNT= in TRAILER1 is the number of groups (summary records), not the original input record count. TOTAL= sums the specified field across the summary records. If that field in the summary record is the group total (from SUM), then the TRAILER1 total is the grand total across all groups. So for “grand total of amount,” TOTAL= is correct; for “total number of original records,” you would need a different approach (e.g. a separate step without SUM that only counts).
First we sort the cards and then we squish each pile (group) into one card that has the total for that pile. That’s SUM. Then we take those squished cards and we can put them in one box (SORTOUT) and also write a little title on top and a line at the bottom that says “how many piles” and “big total.” That’s OUTFIL. So one step: sorted, squished, and then either just the squished cards or the squished cards with a header and footer.
1. When you use both SUM FIELDS= and OUTFIL in the same step, what does SORTOUT receive?
2. Can OUTFIL FNAMES= point to the same dataset as SORTOUT?
3. What is the order of processing when both SUM and OUTFIL are present?
4. If you want both a detail report (all records + trailer) and a summary dataset (one per group), can you do it in one step?
5. What does TRAILER1 show when you use SUM and OUTFIL together?