A free-format DCL-F PRINTER file writes report lines with an explicit
two-operand WRITE, where the second operand is the source record - a data
structure (or character field) whose storage supplies the printed line image:
**FREE
dcl-f QSYSPRT printer(132) oflind(*in99);
dcl-ds outRec;
text char(132);
end-ds;
dcl-s i int(5);
for i = 1 to 130;
if *in99; // overflow reached - reprint the heading
text = 'ACME REPORT';
write QSYSPRT outRec;
*in99 = *off; // clear it; it re-arms on the next page
endif;
text = 'Detail line ' + %char(i);
write QSYSPRT outRec;
endfor;
*inlr = *on;
The record image is the source data structure's storage laid out subfield by
subfield in declaration order: a character subfield contributes its characters;
a zoned subfield its zoned digit image (a negative value carries the sign as the
EBCDIC overpunch on the units digit); a date, time, or timestamp subfield its
character storage image (the field's DATFMT/TIMFMT text - e.g. *ISO
yyyy-mm-dd, hh.mm.ss, yyyy-mm-dd-hh.mm.ss.ffffff). A packed, integer,
unsigned, float, or binary subfield occupies its byte width as blanks, since its
BCD/binary storage is not a printable character image - pre-edit such values into
a character subfield if they must appear on the report. A single character field
may be written directly. A program whose only file is a PRINTER needs no database
connection.
A VARYING subfield occupies 2 + maxLen columns: its storage is a 2-byte
binary length prefix followed by the value left-justified in the declared
maximum data area. The prefix is not printable, so it prints as two blanks and
the value starts at the subfield's third byte. For example a data structure of
a char(3) inz('ABC'), v varchar(5) inz('XY'), b char(3) inz('END') prints:
ABC XY END
``` - `ABC`, two blanks for the length prefix, `XY`, three blanks for the unused
remainder of the 5-byte data area, then `END`. Declare the subfield as fixed
`char` instead if you want the value flush against the preceding one.
**Page overflow (`OFLIND`).** `OFLIND(*INxx)` names an overflow indicator that
turns on when a `WRITE` reaches the page overflow line. The indicator is
**edge-triggered**: it is set on once when the overflow line is reached, and it
is the program's responsibility to test it, print headings, and clear it - it
is not re-asserted on every subsequent write. On the next page it re-arms and
fires again when the overflow line is crossed, so an overflow-conditioned
heading prints once per page.
**Form geometry (`FORMLEN` / `FORMOFL`).** `FORMLEN(n)` sets the form length
(total lines per page) and `FORMOFL(n)` sets the overflow line. The defaults
are a 66-line form with overflow at line 60 - so with default geometry the
first `WRITE` prints on line 1 and `*INxx` first turns on after the line that
advances the paper to line 60. When the form length is passed, the page wraps
to line 1 and the overflow indicator re-arms.
**In fixed format**, the same `WRITE` is written as a C-spec naming the file in
factor 2 and the source data structure in the **result** field - the operand
positions used for a program-described `WRITE`:
FQSYSPRT O F 132 PRINTER DREC DS D A 3A INZ('ABC') D C 5A INZ('XY') D B 3A INZ('END') C WRITE QSYSPRT REC
This prints `ABCXY END`, identical to the free-format form - a subfield
declared on a D-spec lays out exactly as one declared with `DCL-SUBF`, and a
fixed-format alpha subfield carries no length prefix unless it is declared
`VARYING`.
> Printer output driven by the program cycle and O-specs (see the
> [Fixed-Logic Program Cycle](/docs/triton-rpg/fixed-logic-program-cycle/)
> and `EXCEPT`) uses a separate overflow mechanism from the `WRITE`-with-source-record
> form described here. Both forms are available in either source format.