The PRINT statement is how an Easytrieve program produces a formatted report. When you issue PRINT inside a JOB activity, you are telling Easytrieve "take the current record and send it to this report". The report itself is described separately in a REPORT declaration that lists titles, column layout (LINE), and control-break totals (CONTROL). PRINT is the bridge between your record-by-record logic and that report definition: each PRINT contributes one detail line worth of data to the report. A key idea that trips up beginners is that PRINT usually does not write to the printer immediately. Instead, report output is scheduled for deferred formatting - Easytrieve often writes the fields to an intermediate work file, and only after all records are processed does the report writer sort, format, add headings and page numbers, calculate totals at each control break, and finally produce the printed pages. This deferred model is exactly what lets Easytrieve generate polished reports with almost no code on your part. This tutorial explains the PRINT syntax, when the optional report-name is required, how PRINT cooperates with REPORT, CONTROL, TITLE, and LINE, what the report work file is and why it exists, how PRINT behaves when a JOB drives several reports at once, and the important differences between PRINT and DISPLAY so you always pick the right output statement. Worked examples show a minimal single-report program and a control-break report.
1PRINT [report-name]
The syntax is deliberately tiny. PRINT takes one optional operand, report-name, which must match the name given on a REPORT statement. That simplicity is intentional: all the formatting complexity lives in the REPORT declaration, so PRINT only has to say which report to feed.
Whether you must name the report depends on how many reports your JOB activity defines. The rules are straightforward once you see them in a table.
| JOB activity has... | What PRINT needs |
|---|---|
| One report (unnamed) | Code PRINT with no report-name |
| One report (named) | PRINT report-name (matching the REPORT name) |
| Multiple reports | First may be unnamed; each PRINT names its target report |
A report-name follows Easytrieve naming rules: it can be up to 128 characters, must begin with a letter, digit, or national character (#, @, $), cannot be all numeric, and must be unique within the JOB activity. At least one report-name must appear on a PRINT statement so the report is actually requested.
The smallest useful example reads a file and prints one report. PRINT names the report, and the REPORT declaration below it supplies the title and the columns for each detail line.
1234567FILE PERSNL FB(150 1800) %PERSNL JOB INPUT PERSNL NAME PRINT-RPT PRINT REPORT1 REPORT REPORT1 TITLE 'PERSONNEL REPORT' LINE EMP# SSN EMPNAME
For every record read from PERSNL, the PRINT REPORT1 statement schedules a detail line. The report writer then produces a titled report where each line shows the employee number, social security number, and name. You never wrote any page-break, heading, or spacing code - the REPORT declaration and PRINT handled all of it.
PRINT does not push characters to the printer the moment it runs. Report output is scheduled for deferred formatting and writing to the report's printer file, possibly after resequencing through an intermediate file. When a report needs a work file, executing PRINT outputs fixed-format records (spool records) containing every field the report requires - Easytrieve determines that layout automatically. After the JOB finishes reading records, the report subactivity sorts the work file if a SEQUENCE was requested, formats each line, inserts titles and headings, computes control-break totals, and writes the finished pages. Understanding this two-phase model explains why totals and sorted order appear correctly even though your logic processed records one at a time.
| Phase | What happens |
|---|---|
| During JOB (each PRINT) | Field values written as a spool record to the report work file |
| End of JOB | Work file optionally sorted by the SEQUENCE fields |
| Report formatting | Titles, headings, detail lines, and control-break totals produced |
| Output | Formatted pages written to the report printer file |
Reports become powerful when combined with a CONTROL statement, which lists the fields that drive subtotals. A control break occurs whenever a CONTROL field value changes or at end-of-report, and at each break the report writer prints accumulated totals for quantitative fields. Your PRINT statements simply feed records in; the break logic is automatic as long as the data is sequenced by the control fields.
1234567JOB INPUT FILE1 NAME MYPROG PRINT REPORT1 REPORT REPORT1 LINESIZE 65 SEQUENCE STATE ZIP LAST-NAME CONTROL STATE ZIP TITLE 'SALES BY STATE' LINE 01 LAST-NAME STATE ZIP PAY-NET
Here SEQUENCE orders the spool records by STATE, then ZIP, then LAST-NAME, and CONTROL declares STATE and ZIP as break levels. When STATE changes, the report prints a total for the previous state; ZIP works the same at a finer level. Options such as NEWPAGE, RENUM, and NOPRINT on CONTROL further tune how each break is presented.
A single JOB activity can feed several reports. You code more than one REPORT declaration and issue a PRINT for each one you want the current record to contribute to. Because the first report may be unnamed but the rest must be named, giving every report an explicit name is the clearest habit. This lets one pass over the input produce, say, a detail report and a summary report simultaneously.
1234567891011JOB INPUT SALES NAME MULTI PRINT DETAIL-RPT IF REGION = 'WEST' PRINT WEST-RPT END-IF REPORT DETAIL-RPT TITLE 'ALL SALES' LINE CUST SALES-AMT REPORT WEST-RPT TITLE 'WEST REGION SALES' LINE CUST SALES-AMT
Every record goes to DETAIL-RPT, but only western records also go to WEST-RPT. Conditional PRINT statements are the normal way to route records to the reports they belong in.
Both statements produce printed output, but they serve opposite purposes. PRINT is for the formatted report and defers writing so the report writer can do its work. DISPLAY is for a single raw line written immediately, with no report definition involved. If you want titles, columns, page numbers, and totals, use PRINT with a REPORT. If you want a quick operator message, a running total during processing, or a debugging trace, use DISPLAY.
| You want to... | Use |
|---|---|
| Produce a titled, columnar report | PRINT + REPORT |
| Print subtotals and grand totals automatically | PRINT + CONTROL |
| Write a one-off message or trace line | DISPLAY |
| Dump packed/binary data in hex for debugging | DISPLAY HEX |
PRINT is like dropping a filled-in form into a special box. You do not see the report yet - the box just collects one form each time you drop one in. At the end of the day a helper (the report writer) takes all the forms, puts them in order, adds a nice title at the top, numbers the pages, adds up the totals, and hands you a neat booklet. DISPLAY is different: DISPLAY is like writing a sticky note and slapping it on the wall right away. Use the box (PRINT) for the neat booklet, and the sticky note (DISPLAY) for a quick reminder.
1. What does the Easytrieve PRINT statement do?
2. What does PRINT do when you omit the report-name?
3. How is PRINT output written compared to DISPLAY?
4. In a JOB activity with two reports, what is required?
5. What triggers a control break during PRINT processing?