An audit report documents what happened to data: which records were processed, what changed between two runs, or how many records fall into each category. On the mainframe, DFSORT can produce these reports by combining sorted data with OUTFIL report formatting: headers for title and column names, detail lines built from each record, and trailers for record counts and totals. You can add control-break grouping (SECTIONS) so the report is organized by user, date, or account with section-level subtotals. This page explains how to generate audit reports with DFSORT: using OUTFIL HEADER1, HEADER2, TRAILER1, and TRAILER2, adding record counts in trailers, using SECTIONS for grouped reports, and combining file comparison output with report layout to produce change-audit reports.
An audit report is a human-readable summary of data or of changes to data. It might list every transaction processed, every record that was added or deleted between two files, or totals and counts by category. The report usually has a title, column headers, detail lines, and one or more footer lines with totals or counts. DFSORT does not have a dedicated "audit report" verb; you build the report by sorting the data and then using OUTFIL with report options: HEADER1, HEADER2, TRAILER1, TRAILER2, and optionally SECTIONS and TRAILER3 for grouped output.
| Component | Purpose |
|---|---|
| HEADER1 | Report title, run date/time; appears once at the start |
| HEADER2 | Column headers or page title; repeats each page |
| Detail lines | One line per record (BUILD= or FIELDS=) |
| TRAILER1 | Report total, record count; once at end |
| TRAILER2 | Page footer (e.g. page number); each page |
| SECTIONS + TRAILER3 | Group subtotals or counts per key |
Use one OUTFIL that writes to the report DD (FNAMES=). In that OUTFIL specify: BUILD= or FIELDS= (or the equivalent) to define each detail line from the input record; HEADER1= for one or more lines at the start of the report (e.g. report title and run date); HEADER2= for lines that repeat at the top of each page (e.g. column headers); TRAILER1= for lines at the end of the report (e.g. "Total records: n"); and optionally TRAILER2= for a page footer (e.g. page number). Use LINES=n to set the number of lines per page so HEADER2 and TRAILER2 repeat correctly. REMOVECC is often used so the output file does not contain printer control characters if the report will be viewed online.
Audit reports often end with a line like "Total records: 12345". In OUTFIL TRAILER1 you can include a count of how many detail records were written. The exact keyword is product-dependent: DFSORT and ICETOOL may use COUNT= with a format and length, e.g. COUNT=(M3,LENGTH=10) to output the count in a 10-byte field. You combine that with a label: 1:\'Total records: \',COUNT=(...). Check your product manual for the precise syntax. If COUNT= is not available, an alternative is to run a separate step that counts records and writes a one-line file, then concatenate or use ICETOOL to merge that line as the last line of the report.
The order of the report is the sort order. So you SORT FIELDS=(...) first (e.g. by user ID, then by date). If you want the report grouped by a key (e.g. one section per user), use SECTIONS=(position,length,format) on the OUTFIL. For each distinct value of that key you get a section. You can define HEADER3= to print a line at the start of each section (e.g. the user ID) and TRAILER3= to print a line at the end of each section (e.g. "Records for user: n" or a subtotal). That gives you a control-break style audit: sections with optional section-level counts or totals.
When the audit is "what changed between two files," you first produce a stream of changes using file comparison (e.g. JOINKEYS with UNPAIRED,ONLY to get adds and deletes, or a join that outputs matched pairs with both versions for change detection). That stream becomes the input to the report step. Sort that input if needed (e.g. by key or by change type), then use OUTFIL to format it as a report: HEADER1 "Change Audit Report", HEADER2 with columns like Key, Change Type, Old Value, New Value, detail lines from the compare output, and TRAILER1 with total count of changes. So the audit content (adds, deletes, changes) comes from the comparison step; the report layout (title, headers, footers) comes from OUTFIL.
12345678SORT FIELDS=(1,20,CH,A) OUTFIL FNAMES=AUDITRPT, HEADER1=(1:'AUDIT REPORT',40:DATE=(MD4/),60:TIME/), HEADER2=(1:'KEY',22:'AMOUNT',35:'DATE'/), BUILD=(1,20,25,10,PD,EDIT=(IIIIIIIIII.TT),38,8), TRAILER1=(1:'Total records: ',COUNT=(M3,LENGTH=10)), LINES=60, REMOVECC
This sorts by the key at 1,20. HEADER1 prints a title and run date/time. HEADER2 prints column headers. BUILD defines the detail line (key, amount with edit mask, date). TRAILER1 prints a label and the record count. LINES=60 sets 60 lines per page. REMOVECC strips carriage control. The exact COUNT= and DATE= formats may vary by product; see your manual.
You can write both a formatted report and a summary dataset from the same step. Use two OUTFILs: one with FNAMES=REPORT and the HEADER/TRAILER/BUILD report layout, and another with FNAMES=SUMMARY and a different BUILD= or INCLUDE= (e.g. one summary record per section using SECTIONS, or a single record with totals). Both read the same sorted data; one produces the human-readable audit report, the other produces a machine-readable summary for downstream use or for restart.
An audit report is like a list your teacher makes: at the top it says "Class list" and the date, then each row is one kid's name and maybe their score, and at the bottom it says "Total: 25 students." DFSORT makes that list for data: you tell it what to put in the title (HEADER1), what to put at the top of each page (HEADER2), what one line per record looks like (BUILD), and what to put at the end (TRAILER1 with the count). If you want a section for each class, you use SECTIONS so each class gets its own little block with a subtitle and a small total.
1. What DFSORT feature is most used to build a formatted audit report (title, column headers, totals)?
2. How can you include a record count in the report trailer?
3. Why sort data before building an audit report?
4. What is the role of file comparison in an audit report?
5. When would you use SECTIONS in an audit report?