MODULE 10 · BATCH REPORTS · 4/7

Line counting and page breaks

14 min30 XPExercise

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-DETAIL asks "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-COUNT begins 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.

fixed format
Run your program to see its output here. The first visible test's input and datasets are used.
Submit to grade your program against every test.