MainframeMaster

Subtotals

Subtotals in DFSORT reports are the per-group sums and counts that appear after each control-break section—for example, "Department SALES: 25 records, Total 15000" followed by the next department's subtotal. You get them by using SECTIONS= with TRAILER3= and, inside the trailer, COUNT= (number of records in the section) and TOTAL= (or TOT=) to sum a numeric field over that section only. The grand total (over all records) goes in TRAILER1. Data must be sorted by the section key so that each group's records are consecutive. This page explains how to add section subtotals, how to format subtotal lines (including labeling them with the section key), and how to combine subtotals with a final grand total. For control-break structure (HEADER3, TRAILER3, SKIP=P), see Control break reporting; for report-level totals and IFTRAIL, see Report totals.

Report Generation
Progress0 of 0 lessons

Subtotal vs Grand Total

A subtotal is a count or sum for a subset of the report—one section or group (e.g. one department, one region). It is printed after the last record of that group. A grand total is the count or sum over all records and is printed once at the end of the report. In DFSORT you use TRAILER3 for subtotals (one per section) and TRAILER1 for the grand total. Both can use the same kinds of built-in functions: COUNT= for record count and TOTAL= (or TOT=) for the sum of a numeric field. The difference is scope: TRAILER3 is evaluated per section; TRAILER1 is evaluated over the whole file.

COUNT= in Section and Report Trailers

COUNT= inserts the number of records in the current scope. In TRAILER3, that scope is the current section—so you get the number of records in that department (or whatever the section key is). In TRAILER1, the scope is the entire report—so you get the total record count. Syntax is often COUNT=(format,LENGTH=n) where the format (e.g. M11, M10) controls editing (commas, zero suppression) and LENGTH is the output width. Example:

text
1
2
TRAILER3=(1:'Records in section: ',COUNT=(M11,LENGTH=7)) TRAILER1=(1:'TOTAL RECORDS: ',COUNT=(M11,LENGTH=10))

The first line is repeated after each section (section count); the second appears once at the end (grand count). Exact format names (M11, etc.) are product-dependent; see your manual.

TOTAL= (or TOT=) for Summing a Numeric Field

TOTAL= (or TOT=) sums a numeric field over the current scope. You specify the field's position and length in the input record, its format (PD for packed decimal, ZD for zoned decimal, BI for binary), and the output length. In TRAILER3 that sum is over the section only; in TRAILER1 it is over all records. Example: sum a 5-byte zoned decimal amount at position 40, output 12 characters:

text
1
2
TRAILER3=(1:'Section total: ',TOTAL=(40,5,ZD,LENGTH=12)) TRAILER1=(1:'GRAND TOTAL: ',TOTAL=(40,5,ZD,LENGTH=12))

If the amount is packed decimal at position 40, use PD instead of ZD. The first two numbers in TOTAL=(start,len,...) are always the starting position and length of the field to sum; the format (ZD, PD, BI) must match the data. Wrong format can cause incorrect totals or abends.

Complete Example: Subtotals and Grand Total

Input: fixed-length records, department at 30,5 (character), sales amount at 40,6 (packed decimal). Sort by department, then use SECTIONS= with TRAILER3 for section count and section total, and TRAILER1 for grand count and grand total.

text
1
2
3
4
5
6
7
8
SORT FIELDS=(30,5,CH,A) OUTFIL FNAMES=REPORT, SECTIONS=(30,5,SKIP=2L, TRAILER3=(1:'Dept ',30,5,' Count: ',COUNT=(M11,LENGTH=6), ' Total: ',TOTAL=(40,6,PD,LENGTH=12))), OUTREC=(1,80), TRAILER1=(2/,1:'GRAND TOTAL Count: ',COUNT=(M11,LENGTH=10), ' Total: ',TOTAL=(40,6,PD,LENGTH=14))

After each department you get a line like "Dept SALES Count: 25 Total: 15000". The 30,5 in TRAILER3 prints the current department code. At the end of the report, TRAILER1 prints the overall count and sum. SKIP=2L leaves two blank lines between sections. Format and keyword names may vary by product.

Formatting the Subtotal Line

You can make the subtotal line easy to read by:

  • Labeling with the section key — Include the section key field (e.g. 30,5) in TRAILER3 so the line shows which group it belongs to (e.g. "Dept SALES").
  • Positioning — Use position notation (n:literal or n:field) so columns align (e.g. totals right-aligned at position 60).
  • Literal text — Add strings like "Subtotal: ", "Count: ", "Total: " so the meaning is clear.
  • Blank lines — Use 2/ or X at the start of TRAILER3 to leave a blank line before the subtotal, separating it from the last detail line.

Example with alignment and blank line:

text
1
2
3
TRAILER3=(2/,1:'--- Subtotal for ',30,5,' ---', 50:'Count: ',COUNT=(M11,LENGTH=6), 65:'Sum: ',TOTAL=(40,6,PD,LENGTH=12))

Multi-Level Subtotals

When you have two or more break levels (e.g. region and department), you can have a subtotal at each level. Sort by both keys (e.g. SORT FIELDS=(1,6,CH,A,30,5,CH,A)). In SECTIONS= you define both levels; the first level typically uses HEADER3/TRAILER3 and the second HEADER4/TRAILER4 (or similar). In each trailer you use COUNT= and TOTAL= for that level. So you might get a subtotal after each department (TRAILER4) and a higher-level subtotal after each region (TRAILER3). Exact parameter order and level numbers are product-dependent; see your DFSORT manual for multi-level SECTIONS=.

MIN=, MAX=, AVG= in Trailers

Besides COUNT= and TOTAL=, many DFSORT products allow MIN=, MAX=, and AVG= in trailer specifications. They compute the minimum, maximum, or average of a numeric field over the current scope (section for TRAILER3, whole report for TRAILER1). Useful for lines like "Min: 100 Max: 500 Avg: 250" per section or for the report. Syntax is similar to TOTAL=: position, length, format, and output length. Check your manual for exact keywords and format codes.

Subtotal and total placement
TrailerScope
TRAILER3 (in SECTIONS=)Per section: subtotal, section count, MIN/MAX/AVG for the section.
TRAILER1Whole report: grand total, total record count, MIN/MAX/AVG over all records.

SUBCOUNT and Product-Specific Options

Some products support SUBCOUNT or similar keywords for cumulative or cross-section counts. The exact meaning (e.g. running total, count across a subset of sections) is product-dependent. When in doubt, use COUNT= and TOTAL= in TRAILER3 for section subtotals and in TRAILER1 for the grand total; that pattern is widely supported.

Explain It Like I'm Five

Imagine a list of toys by color. You want to know "how many red toys?" and "total price of red toys?" then the same for blue, then green. Each of those is a "subtotal"—a little total for one group. At the very end you want "how many toys in total?" and "total price of everything?"—that is the "grand total." In DFSORT, the little totals (subtotals) go in TRAILER3 after each color group, and the big total (grand total) goes in TRAILER1 at the end of the list.

Exercises

  1. Your input has amount at 50,8 (packed decimal). Write the TRAILER3 and TRAILER1 entries to show section total and grand total for that field (conceptual syntax).
  2. Why does the section key (e.g. 30,5) need to appear in the sort key when using subtotals?
  3. How would you add both a record count and a sum of amount in the same TRAILER3 line?

Quiz

Test Your Knowledge

1. Where do you put the subtotal for each group (e.g. each department) in a DFSORT report?

  • In TRAILER1 only
  • In TRAILER3= inside SECTIONS=—TRAILER3 is written after each section with COUNT= or TOTAL= for that section only
  • In HEADER2
  • In OUTREC= only

2. What does TOTAL=(20,6,PD,LENGTH=12) in a trailer mean?

  • Total of 20 records, 6 bytes each
  • Sum the 6-byte packed decimal field at position 20 in the input records; format the result in 12 characters in the trailer
  • Position 20 only
  • Only for TRAILER1

3. How do you get both a subtotal per section and a grand total at the end?

  • Use two OUTFIL statements
  • Use SECTIONS= with TRAILER3= for section subtotals and TRAILER1= for the grand total—TRAILER3 prints after each group, TRAILER1 prints once at the end
  • Use only TRAILER3
  • Use SUM statement only

4. Why must data be sorted by the section key when using subtotals in SECTIONS?

  • It is optional
  • So that all records in a group are consecutive—TRAILER3 is written when the key changes, and the count/total are computed only over the records in the current section
  • Only for TRAILER1
  • To improve performance only

5. What is SUBCOUNT used for in DFSORT reports?

  • Same as COUNT
  • In some products, SUBCOUNT accumulates count (or total) across sections—e.g. for a running or cross-section total; exact meaning is product-dependent
  • Section count only
  • To subtract from COUNT