Line counting and page breaks
Paper has a fixed number of lines: 60 on a classic 11-inch page printed at 6 lines per inch, once you leave margins. Your program has to know when a page is full, start a new one, and repeat the headings with the next page number. Nobody does this for you; you count lines.
The pattern
IDENTIFICATION DIVISION.
PROGRAM-ID. PAGEDEMO.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-MAX-LINES PIC 99 VALUE 5.
01 WS-LINE-COUNT PIC 99 VALUE 99.
01 WS-PAGE PIC 99 VALUE 0.
01 WS-ITEM PIC 99.
01 HDG-LINE.
05 FILLER PIC X(12) VALUE "ITEM LIST".
05 FILLER PIC X(5) VALUE "PAGE ".
05 HL-PAGE PIC Z9.
01 DETAIL-LINE.
05 FILLER PIC X(5) VALUE "ITEM ".
05 DL-ITEM PIC Z9.
PROCEDURE DIVISION.
PERFORM VARYING WS-ITEM FROM 1 BY 1 UNTIL WS-ITEM > 7
MOVE WS-ITEM TO DL-ITEM
PERFORM PRINT-DETAIL
END-PERFORM
STOP RUN.
PRINT-DETAIL.
IF WS-LINE-COUNT >= WS-MAX-LINES
PERFORM PRINT-HEADINGS
END-IF
DISPLAY DETAIL-LINE
ADD 1 TO WS-LINE-COUNT.
PRINT-HEADINGS.
ADD 1 TO WS-PAGE
MOVE WS-PAGE TO HL-PAGE
DISPLAY HDG-LINE
DISPLAY "-----------------"
MOVE 2 TO WS-LINE-COUNT.
Output (5-line pages):
ITEM LIST PAGE 1
-----------------
ITEM 1
ITEM 2
ITEM 3
ITEM LIST PAGE 2
-----------------
ITEM 4
ITEM 5
ITEM 6
ITEM LIST PAGE 3
-----------------
ITEM 7
Three details make it work:
- Check before you write.
PRINT-DETAILasks "is this page full?" before writing the line. Checking after writing would print headings at the bottom of a page with nothing under them when the input ends. - Start the counter high.
WS-LINE-COUNTbegins at 99, so the very first line finds the "page" full and prints page 1's headings. No special case for the first page, and an empty input produces no page at all. - Headings reset the counter to the number of lines they used (2 here), and bump the page number.
Everything goes through one paragraph
Totals and other trailing lines must follow the same rule as details, or they can spill past the bottom of the page. Route every body line through the paragraph that does the check. A common shape is to build the line in a work area first:
MOVE TOTAL-LINE TO WS-PRINT-AREA
PERFORM PRINT-LINE
where PRINT-LINE checks the count, writes RPT-LINE FROM WS-PRINT-AREA
and adds one. Don't park the pending line in the FD record: printing
headings writes RPT-LINE FROM each heading, which would overwrite it.
(On z/OS, the FD record area of an output file isn't even guaranteed to
survive a WRITE.)
On a real printer
In production the heading write is usually
WRITE RPT-LINE FROM HDG-1 AFTER ADVANCING PAGE, which puts a
new-page control character (ASA 1) in front of the line, and the page
size comes from a WORKING-STORAGE constant like WS-MAX-LINES VALUE 55.
COBOL also has an FD LINAGE clause that counts lines for you, but you'll
rarely meet it. Hand-counted pages like this are the norm. In this
course, a page is simply the heading followed by its lines.
On the job
"Headings print at the bottom of the last page" and "the total line is on a page of its own with no headings" are two of the oldest report bugs. Test your page logic with input that exactly fills a page, one line more, and one line less. The graders here do.
Your task
The account balance listing runs to thousands of lines, so it must be split into numbered pages. To keep tests readable, a page here is 10 lines.
DD ACCTIN — line sequential, 35 bytes: ACCT-ID X(6),
ACCT-NAME X(20), ACCT-BAL 9(7)V99.
DD RPTOUT — the report.
Every page starts with three heading lines, the first carrying the page number:
ACCOUNT BALANCE LISTING PAGE 1
ACCOUNT NAME BALANCE
------- -------------------- ------------
followed by up to 7 detail lines. The total line
(ACCOUNTS: 16 TOTAL BALANCE 1,593,067.05) follows the last detail;
it counts as a line too, so if the last page is already full it goes on a
new page of its own, under fresh headings.
The starter has every layout and prints the headings once. Make
PRINT-LINE start a new page whenever the current one is full.