Page control in COBOL lets you format report output into pages with a fixed number of lines, top and bottom margins, and a footing area. The LINAGE clause on the file description defines the page layout, and LINAGE-COUNTER tells you the current line so you can break pages at the right place.
When you print a report, each sheet of paper has a limited number of lines. Page control is the set of rules that say "this many lines per page," "skip this many at the top and bottom," and "when we reach this line, start a new page." COBOL does this with the LINAGE clause and a counter (LINAGE-COUNTER) so the program can know when to start a new page and where to put headers and footers.
LINAGE is specified in the FD (file description) for a sequential report file. It defines the logical page: how many lines are in the body, where the footing starts, and how many lines are reserved at the top and bottom. The compiler creates a special register called LINAGE-COUNTER that is updated as you write lines; it holds the current line number within the page body (1 up to the LINAGE value). When you write past the last line or into the footing area, behavior depends on the implementation—often the next WRITE causes an advance to the next page and the counter resets.
| Subclause | Meaning | Effect |
|---|---|---|
| LINAGE IS n LINES | Page body height in lines. | LINAGE-COUNTER runs from 1 to n within each page. |
| WITH FOOTING AT m | Footing area starts at line m of the body. | Lines m through n are the footing area; often used to trigger page advance. |
| LINES AT TOP t | Top margin lines (before body). | t lines at top of physical page are skipped for body counting. |
| LINES AT BOTTOM b | Bottom margin lines (after body). | b lines at bottom are reserved; body does not use them. |
12345678910111213141516FD REPORT-FILE LINAGE IS 60 LINES WITH FOOTING AT 55 LINES AT TOP 2 LINES AT BOTTOM 3. 01 REPORT-LINE PIC X(132). WORKING-STORAGE SECTION. 01 WS-LINE-LIMIT PIC 99 VALUE 55. WRITE-REPORT-LINE. IF LINAGE-COUNTER >= WS-LINE-LIMIT WRITE REPORT-LINE BEFORE ADVANCING PAGE ELSE WRITE REPORT-LINE AFTER ADVANCING 1 LINE END-IF.
In practice, the runtime often maintains LINAGE-COUNTER automatically when you WRITE with ADVANCING. Check your compiler documentation: some implementations increment LINAGE-COUNTER on WRITE and automatically advance page when the body is full or when you write into the footing area. Others expect you to test LINAGE-COUNTER and explicitly WRITE ... BEFORE ADVANCING PAGE when you want a new page.
LINAGE IS n LINES sets the number of lines in the page body. The page body is the area where detail lines and optional heading/footing lines go. LINAGE-COUNTER is 1 when the page starts and increases as lines are written (or is updated by the runtime). When LINAGE-COUNTER exceeds n (or when you write into the footing area if specified), the next write may advance to the next page and reset the counter. The value n should match your physical form length minus top and bottom margins if you use LINES AT TOP/BOTTOM.
WITH FOOTING AT m defines the footing area as starting at line m of the page body. The footing area is from line m through the last line of the body (line n). It is often used for page footers (e.g. "Page 1") or to trigger page advance: when LINAGE-COUNTER reaches m, you might write your footer and then advance page. The exact behavior (automatic advance vs manual) depends on the implementation. If you do not need a footing area, omit this clause.
LINES AT TOP t reserves t lines at the top of each physical page; they are not part of the countable body. LINES AT BOTTOM b reserves b lines at the bottom. So the physical page has t top lines, then n body lines (where LINAGE-COUNTER applies), then b bottom lines. This gives consistent margins. For a 66-line form with 3-line top and 3-line bottom margins, you would use LINES AT TOP 3, LINES AT BOTTOM 3, and LINAGE IS 60 LINES so the body is 60 lines.
To start a new page you write a record with BEFORE ADVANCING PAGE or AFTER ADVANCING PAGE. BEFORE ADVANCING PAGE ejects the current page and then writes the record (typically a header line) at the top of the new page. AFTER ADVANCING PAGE writes the record and then ejects. So to print a page header at the top of each new page, use WRITE header-line BEFORE ADVANCING PAGE after you have determined that you need a new page (e.g. when LINAGE-COUNTER exceeds your desired lines or when you have written into the footing area). After the advance, LINAGE-COUNTER is typically reset to 1 (or 0 depending on implementation).
1234567CHECK-PAGE-BREAK. IF LINAGE-COUNTER >= 55 WRITE HEADER-LINE BEFORE ADVANCING PAGE END-IF. WRITE-DETAIL. WRITE DETAIL-LINE AFTER ADVANCING 1 LINE.
Report Writer (RW) is a higher-level facility that uses report groups (e.g. PAGE HEADING, DETAIL, PAGE FOOTING). In that model, page control is partly defined by the report section (LINE NUMBER, TYPE PAGE HEADING, TYPE PAGE FOOTING, etc.) and the report writer control logic. The underlying file can still use LINAGE for the physical page size. PAGE HEADING prints at the start of each page; PAGE FOOTING prints in the footing area or at the bottom. If you use Report Writer, refer to the REPORT SECTION and GENERATE/INITIATE/TERMINATE verbs; if you use plain WRITE with LINAGE, the logic above applies.
1. LINAGE-COUNTER is used to:
2. To start a new page when writing a report you typically:
3. FOOTING AT 55 in a LINAGE IS 60 LINES means: