Real batch jobs rarely stop at one listing. Payroll might need a complete register for audit, a deduction detail tape for finance, and a department-only exception for operations—all from the same employee extract read once overnight. Easytrieve supports that pattern natively: one JOB activity, one pass over the input file, several REPORT declarations, and PRINT statements that decide which records feed which layout. This tutorial explains how multiple reports coexist in a single program, how PRINT routing and conditional selection work, why each REPORT keeps its own formatting and control breaks, how printer destinations including SYSPRINT and named PRINTER files affect output and performance, and which error patterns beginners hit when report names, work files, or unsorted CONTROL fields collide. Everything here aligns with Broadcom Easytrieve Report Generator 11.6 documentation on multiple reports, PRINT, REPORT, and routing printer output.
Multiple reports only make sense once you internalize the two-phase model Easytrieve has used for decades. During the JOB activity, PRINT is a selector. It says "the current record belongs in report X" without painting columns or page headers. After input processing completes—or at controlled points when work files flush—the report writer reads each REPORT subactivity and produces finished pages: TITLE lines, LINE layouts, CONTROL break headers, SUM totals, page numbers, and optional REPORT PROC logic. One REPORT does not know about another’s LINE definitions. Two PRINT calls in the same IF block can target different report names, and each target formats independently when its turn arrives. Beginners who expect PRINT to behave like DISPLAY often wonder why nothing appears on spool mid-loop; deferred formatting is normal and is what enables correct subtotals across an entire file.
Every report in a JOB activity needs its own REPORT block coded after executable statements and job PROCs. Broadcom naming rules allow up to 128 characters, must start with a letter digit or national character, and must be unique within the JOB. When only one report exists, the REPORT name is optional. With multiple reports, the first REPORT may remain unnamed per language rules, but naming every report explicitly is the maintainability standard production shops expect—support analysts searching source for RPT3 should find a matching PRINT RPT3, not guess which unnamed block is third in the file.
123456789101112131415161718192021222324252627FILE PERSNL FB(150 1800) EMPNAME 17 8 A DEPARTMENT 98 3 N NET 90 4 P 2 GROSS 94 4 P 2 DEDUCTIONS W 4 P 2 JOB INPUT PERSNL NAME MULTRPTS PRINT RPT1 DEDUCTIONS = GROSS - NET PRINT RPT2 IF DEPARTMENT = 911 PRINT RPT3 END-IF * REPORT RPT1 TITLE 1 'REPORT ONE' LINE 1 EMPNAME DEPARTMENT GROSS NET * REPORT RPT2 SEQUENCE DEPARTMENT TITLE 1 'REPORT TWO' LINE 1 DEPARTMENT EMPNAME GROSS NET DEDUCTIONS * REPORT RPT3 CONTROL DEPARTMENT TITLE 1 'REPORT THREE - DEPT 911' LINE 1 EMPNAME GROSS NET DEDUCTIONS
This example is adapted from Broadcom’s Multiple Reports guide. RPT1 lists every employee in simple column order. RPT2 adds a computed DEDUCTIONS column and sequences by department so related rows group before formatting. RPT3 receives only department 911 rows and uses CONTROL for break-oriented layout. Three layouts, three names, one input pass—no duplicate GET loops required.
PRINT report-name is the routing switch. Unconditional PRINT sends every record to that report. Conditional PRINT inside IF, CASE, or procedure calls restricts membership—only western region rows hit WEST-RPT, only over-limit balances hit EXCEPTION-RPT. You may issue several PRINT statements per record: the MULTRPTS job prints RPT1 and RPT2 for all employees after computing deductions, then adds RPT3 when DEPARTMENT equals 911. Nothing in the language prevents a record from appearing in every report, one report, or none. Records that fail all PRINT conditions simply skip every report, which is how exception-only reports stay small while detail reports remain complete.
| Pattern | Typical JOB logic | Outcome |
|---|---|---|
| Full detail plus summary | PRINT DETAIL-RPT for all; PRINT SUMMARY-RPT when last record of group (or separate aggregation) | Detail and summary share input; summary REPORT often uses CONTROL and SUM |
| Exception branch | PRINT FULL-RPT always; IF AMOUNT GT LIMIT PRINT EXCEPTION-RPT | Exception report contains only failing rows |
| Regional split | IF REGION EQ 'WEST' PRINT WEST-RPT; IF REGION EQ 'EAST' PRINT EAST-RPT | Mutually exclusive or overlapping regional books from one file |
| Dual layout same data | PRINT MGR-RPT and PRINT AUDIT-RPT on same record | Two formats of identical rows—for example wide audit columns vs narrow manager view |
At least one report-name must appear on a PRINT statement in the JOB so the compiler knows which reports are actually requested. Defining REPORT blocks without any matching PRINT produces dead declarations—harmless at compile time but confusing when operators expect spool data that never materializes.
The economic reason sites choose multiple reports is single-pass efficiency. Reading a large sequential extract twice doubles I/O and extends the batch window. Easytrieve’s design keeps one JOB INPUT (or controlled GET loop) as the driver. Each input record triggers zero or more PRINT operations; the report writer handles the rest. Derived fields computed before PRINT—like DEDUCTIONS = GROSS - NET in the Broadcom example—are available to every subsequent PRINT in that iteration because they live in working storage for the current record context. If a second report needs different derivations, calculate them before the PRINT that needs them or use REPORT PROCs for break-time logic that should not affect JOB-level fields.
Sort order of the input file matters per report, not globally. RPT1 without SEQUENCE prints in arrival order. RPT2 with SEQUENCE DEPARTMENT may sort spool records during report processing even when input arrived random—Easytrieve builds a work file and sorts it. RPT3 with CONTROL DEPARTMENT assumes meaningful breaks when department values change; if input is not ordered and RPT3 lacks SEQUENCE, break headers may repeat incorrectly. Each report’s SEQUENCE and CONTROL are evaluated independently—do not assume sorting for one report helps another.
Each REPORT subactivity is a self-contained layout contract. LINESIZE on RPT1 can be 80 while RPT2 uses 132 for wide financial columns. TITLE text differs per audience. LINE statements list different fields and literals. CONTROL and SUM on one report do not propagate to siblings—a CONTROL DEPARTMENT on RPT3 does not affect RPT1’s flat listing. SEQUENCE on one report reorders only that report’s work file. PAGE, SKIP, HEADING, FOOTING, and mask options documented for your release apply per REPORT block. Pagination therefore restarts separately per report when NEWPAGE or control-level NEWPAGE options are coded; page 1 of the exception book is unrelated to page 1 of the full register.
Imagine payroll where RPT-REGISTER lists every employee unsorted for archival tape, RPT-DEPT uses SEQUENCE DEPARTMENT with CONTROL DEPARTMENT and SUM GROSS for supervisor review, and RPT-911 is a flat exception with no breaks. The register might span thousands of pages in input order while the departmental book breaks cleanly with subtotals only because its REPORT declared SEQUENCE and CONTROL. Trying to share one CONTROL definition across reports is a conceptual mistake—copy the pattern into each REPORT that needs breaks and tune NEWPAGE or RENUM per report requirements.
| REPORT-level option | Scope |
|---|---|
| LINESIZE | Line width for this report only |
| SEQUENCE | Sort keys for this report’s work file only |
| CONTROL / SUM | Break levels and totals for this report only |
| TITLE / LINE | Headers and columns for this report only |
| PRINTER | Output file routing for this report only |
| REPORT PROCs | Must follow the REPORT that references them |
Broadcom distinguishes two deployment shapes. Multiple reports to a single printer—the default SYSPRINT or SYSLST device configured in the Site Options Table—require no special coding beyond separate REPORT names and PRINT targets. Reports queue through the report writer and typically share work-file mechanics when the printer is already active in the same JOB or when SEQUENCE forces intermediate storage. Operators see separate logical reports in spool, often as distinct sysout data sets or sequential sections depending on JCL and site options, but your Easytrieve source does not need a PRINTER parameter for that case.
Multiple reports to more than one printer—or more accurately to more than one logical PRINTER file—uses the PRINTER parameter on REPORT. Define a library FILE with the PRINTER attribute, assign a unique ddname in JCL, and reference that file-name on REPORT. Broadcom’s MULT-PRINTERS example sends FIRST-REPORT to SPFORM while NORM-REPORT uses the default printer. Routing can split preprinted forms from standard listings, send labels to a narrow device, or parallelize spool to different JES classes so large jobs finish faster when SEQUENCE is not forcing shared work files.
12345678910111213141516171819202122FILE PAYFILE EMPNAME 17 16 A ADDRESS 57 20 A STREET 37 20 A EMP-NUMBER 9 5 N * FILE SPFORM PRINTER * JOB INPUT PAYFILE NAME MULT-PRINTERS IF EMP-NUMBER LE 12345 PRINT FIRST-REPORT PRINT NORM-REPORT END-IF * REPORT FIRST-REPORT PRINTER SPFORM SEQUENCE EMP-NUMBER LINE 1 EMPNAME LINE 3 STREET LINE 5 ADDRESS * REPORT NORM-REPORT LINE 1 EMPNAME ADDRESS EMP-NUMBER
FIRST-REPORT formats a multi-line address layout on the SPFORM logical printer—often preprinted checks or special forms in production. NORM-REPORT stays on the default device with a compact single LINE. JCL ties SPFORM to the physical ddname operations maintain; mismatched JCL between test and production is a frequent go-live defect when multiple printers are involved.
Default output goes to SYSPRINT unless your site retargets it. The actual mainframe destination is controlled by the Site Options Table—ask your systems programmer rather than assuming SYSOUT class A. Named PRINTER files accept F(length) on the FILE statement; record length defaults from site options or from LINESIZE on the related REPORT. Destinations can include the originating terminal (invoking Report Display Facility on some platforms), another terminal in CICS, the operating system spooler, or an external dataset depending on FILE definition. Broadcom notes that routing each report to a different logical printer can improve performance when no SEQUENCE requires shared resequencing— parallel spool writers reduce contention on one ddname.
When PRINT runs, Easytrieve often writes fixed-format spool records containing all fields needed for the report—excluding S-type working storage per Broadcom. Work files activate in two documented cases: the target printer is already activated by a previous report in the same JOB activity, or the report declares SEQUENCE so records must be reordered before formatting. Multiple reports hitting the same default printer therefore commonly share work-file behavior even though your source looks like simple PRINT statements. After input ends, each report’s work file is sorted if SEQUENCE demands it, then formatted with titles, breaks, and totals. Spooled reports display in definition order at JOB termination; understanding that order helps when DISPLAY diagnostics seem to appear after report bodies on terminal sessions.
Large jobs can redirect work files to sequential datasets using FILE parameters documented on REPORT for your release—consult Broadcom when register and exception reports together exhaust region. Empty input with multiple reports still triggers report processing; titles may print with no detail lines depending on SUMMARY and site options—verify expected behavior before sign-off.
Single-pass input is the primary performance win—protect it when stakeholders ask for "just one more report." Each additional REPORT adds formatting cost proportional to rows PRINT selects, not to total input rows if routing is selective. SEQUENCE on several reports multiplies sort work; prefer pre-sorted input when multiple reports share the same keys and your process already runs SORT. Routing reports to separate PRINTER files can parallelize I/O when Broadcom’s guidance applies and SEQUENCE does not force shared pipelines. Conditional PRINT that skips most rows keeps exception reports cheap even when detail reports print everything. Avoid redundant PRINT to five reports when two layouts could merge with REPORT PROC logic—clarity and performance both suffer.
Wrong or missing report-name on PRINT is the most common logic bug: records vanish from the expected spool data set or populate an unnamed first report you forgot about. Misspelled report-names fail at compile time; mismatched names between PRINT and REPORT are caught early—thank the compiler. CONTROL without SEQUENCE on unsorted input produces repeating break headers and wrong subtotals on one report while another report looks fine—debug the broken report’s SEQUENCE line, not the input FILE. Forgetting to PRINT to a defined REPORT yields empty output and wasted operator time. REPORT PROCs placed after the wrong REPORT block cause undefined procedure errors—each PROC belongs immediately after its REPORT. JCL that omits a DD for a PRINTER file fails at runtime when that report formats, often late in the batch after the input pass succeeded. S-type working storage fields silently absent from work files confuse developers who PRINT computed flags that never appear on LINE—use non-S types or move values to regular working storage before PRINT.
| Symptom | Likely cause |
|---|---|
| Report empty but job RC 0 | No PRINT targets that report, or condition never true |
| Records on wrong report | PRINT omits report-name or names first unnamed report |
| Duplicate break headers | CONTROL without SEQUENCE on unsorted input for that REPORT |
| Field blank on LINE | S-type working storage excluded from spool records |
| I/O error at end of job | Missing JCL DD for PRINTER file-name |
| Totals correct on one report only | SUM coded on one REPORT but not the other |
Imagine one box of class photos and three different yearbook teams. Every time you look at a photo, you can drop a copy into team A's bin, team B's bin, both bins, or neither—depending on rules like "only kids in red shirts go to bin C." That is PRINT: you decide which bins get the photo. Later, each team lays out its bin its own way—big titles, different columns, counting kids by grade for one book but not the other. That layout step is REPORT. One box of photos (one input file), several bins (several reports), several layout teams (several REPORT blocks). If two teams share one printer, they wait in line; if each team has its own printer (PRINTER file), they finish in parallel. You never need to open the photo box twice unless you choose to run the whole program again.
1. When a JOB activity defines more than one report, what must each PRINT statement do?
2. Can one input record contribute to more than one report in the same loop iteration?
3. What is the default printer destination when REPORT omits PRINTER?
4. When does Easytrieve use a report work file for multiple reports on one printer?
5. How do control breaks differ across multiple reports in one JOB?