Compaq COBOL
User Manual


Previous Contents Index

10.6 Programming a Linage-File Compaq COBOL Report

A linage-file report has sequential organization and access mode, and consists of one or more logical pages. A Compaq COBOL program that produces a linage-file report uses the LINAGE and LINAGE-COUNTER capabilities in addition to the facilities used for conventional reports.

In contrast to the conventional COBOL report, you can use the LINAGE clause to do the following:

Additionally, a linage-file report has a LINAGE-COUNTER special register assigned to it that monitors the number of lines written to the current logical page.

To program a linage report, you should understand how to do the following:

On OpenVMS Alpha, the linage file contains variable length with fixed control records. All advancing information is encoded in the fixed control portion of the record. <>

On Tru64 UNIX, the linage file contains variable length records. All advancing information is written to the file as blank lines. <>

The following sections discuss these topics in detail. Example 10-5 shows an example of a linage-file program.

10.6.1 Defining the Logical Page in a Linage-File Report

Your program specifies the format of your report. Using the report layout worksheet you created, you can write a Compaq COBOL program that defines the logical page area and divides the page into logical page sections for a linage-file report. Figure 10-6 shows the logical page area and the four divisions of a linage-file report.

Figure 10-6 Logical Page Areas for a Linage-File Report


To define the number of lines on a logical page and to divide it into logical page sections, you must include the LINAGE clause as a File Description entry in your program. The LINAGE clause lets you specify the size of the logical page's top and bottom margins and the line where the footing area begins in the page body.

For example, to define how many lines you want your program to skip at the top or bottom of the logical page, use the LINAGE clause with either the LINES AT TOP or the LINES AT BOTTOM phrase. To define a footing area within the logical page, use the LINAGE clause with the WITH FOOTING phrase.

The LINES AT TOP phrase positions the printer on the first print line in the page body. The LINES AT BOTTOM phrase positions the printer at the top of the next logical page once the current page body is complete. The WITH FOOTING phrase defines a footing area in the logical page that controls page-overflow conditions. Additionally, you can insert specific text, such as footnotes or page numbers, on the bottom lines of your logical page.

In addition to defining the logical page area and the number of lines that appear on a page, you must be prepared to handle vertical spacing, horizontal spacing, logical page advancement, and page-overflow. The following sections discuss these topics in detail.

10.6.2 Controlling the Spacing in a Linage-File Report

To control the horizontal spacing on a logical page, define every report item from your report layout worksheet in the Working-Storage Section of your Compaq COBOL program.

To control the vertical spacing on a logical page, use the WRITE statement. The WRITE statement controls whether one or more lines is skipped before or after your program writes a line of the report. For example, to print a line before advancing five lines, use the following:


WRITE... BEFORE ADVANCING 5 LINES. 

To print a line after advancing two lines, use the following:


WRITE... AFTER ADVANCING 2 LINES. 

10.6.3 Using the LINAGE-COUNTER

The LINAGE-COUNTER special register is one method of tracking the number of lines that your program writes on a logical page. When you use the LINAGE-COUNTER special register, each time a line is written or skipped, the register is incremented by 1.

Before the program writes a new line, it checks the LINAGE-COUNTER value to see if the current logical page can accept the new line. If the value equals the maximum number of lines for the page body, the compiler positions the pointer on the first print line of the next page body. The compiler automatically resets this register to 1 each time your program begins a new logical page.

If you choose not to use the LINAGE-COUNTER register, you can advance to the next logical page using the WRITE statement, as explained in Section 10.6.4.

10.6.4 Advancing to the Next Logical Page in a Linage-File Report

Linage-files automatically advance to the next logical page when the LINAGE-COUNTER value equals the number of lines on the logical page. However, Compaq COBOL also lets your program control logical page advancement with the WRITE statement.

To manually advance to the next logical page from any line in the current page body and position the printer on the first print line of the next page body, your program must include the WRITE statement with either the BEFORE ADVANCING PAGE clause or the AFTER ADVANCING PAGE clause. For an example of the WRITE statement, see Section 10.6.7.

Section 10.6.5 describes how to handle a page-overflow condition.

10.6.5 Programming for the End-of-Page and Page-Overflow Condition

A page-overflow condition occurs when your program writes more lines than the logical page can accommodate. Although the compiler automatically advances to the next logical page when you use the LINAGE-COUNTER register, header information is not printed, and the next line begins on the next logical page.

If you want your program to advance to the next page and print page headers on the new page when the page is full, you should include routines in your program that limit the number of lines on each logical page.

Example 10-4 demonstrates how to include these routines in your program using the logical page shown in Figure 10-7.

Figure 10-7 A 28-Line Logical Page


In Figure 10-7, each detail line of the report represents a separate purchase at the XYZ Clothing Store. Each page can contain from 1 to 18 purchase lines. Each customer can have an unlimited number of purchases. A total of purchases for each customer is to appear on line 25 of that customer's last statement page. Headers appear on the top of each page.

The input file, INPUT.DAT, consists of individual purchase records sorted in ascending order by customer account number and purchase date. In Example 10-4, the LINAGE clause defines a footing area so the program can check for an end-of-page condition. When the condition is detected, the program executes its header routine to print lines 1 to 7.

Example 10-4 Checking for End-of-Page on a 28-Line Logical Page

IDENTIFICATION DIVISION. 
PROGRAM-ID. REPOVF. 
ENVIRONMENT DIVISION. 
INPUT-OUTPUT SECTION. 
FILE-CONTROL. 
    SELECT INPUT-FILE  ASSIGN TO "INPUT.DAT". 
    SELECT REPORT-FILE ASSIGN TO "REPORT.DAT". 
DATA DIVISION. 
FILE SECTION. 
FD  INPUT-FILE. 
01  INPUT-RECORD. 
    02  I-NAME. 
        03  I-FIRST          PIC X(10). 
        03  I-MID            PIC X. 
        03  I-LAST           PIC X(15). 
    02  I-ADDRESS. 
        03  I-STREET         PIC X(20). 
        03  I-CITY           PIC X(15). 
        03  I-STATE          PIC XX. 
        03  I-ZIP            PIC 99999. 
    02  I-ACCOUNT-NUMBER     PIC X(9). 
    02  I-PURCHASE-DATE      PIC XXXXXX. 
    02  I-PURCHASE-AMOUNT    PIC S9(6)V99. 
    02  I-PURCHASE-DESCRIP   PIC X(20). 
FD  REPORT-FILE 
    LINAGE IS 26 LINES 
           WITH FOOTING AT 25 
           LINES AT BOTTOM  2. 
01  PRINT-LINE               PIC X(80). 
WORKING-STORAGE SECTION. 
01  HEAD-1. 
    02  H1-LC    PIC 99. 
    02  FILLER   PIC X(20) VALUE "XYZ Clothing Store  ". 
    02  FILLER   PIC X(25) VALUE SPACES. 
    02  FILLER   PIC X(6)  VALUE "Page: ". 
    02  H1-PAGE  PIC Z(9). 
01  HEAD-2. 
    02  H2-LC    PIC 99. 
    02  FILLER   PIC X(20) VALUE "STATEMENT OF ACCOUNT". 
    02  FILLER   PIC X(25) VALUE SPACES. 
    02  FILLER   PIC X(6)  VALUE "Date: ". 
    02  H2-DATE  PIC X(9). 
 
01  HEAD-3. 
    02  H3-LC    PIC 99. 
    02  FILLER   PIC X(6)  VALUE "Name: ". 
    02  H3-FNAME PIC X(10). 
    02  FILLER   PIC X     VALUE SPACE. 
    02  H3-MNAME PIC X. 
    02  FILLER   PIC X     VALUE SPACE. 
    02  H3-LNAME PIC X(15). 
    02  FILLER   PIC X(17) VALUE " Account Number: ". 
    02  H3-NUM   PIC Z(9). 
01  HEAD-4. 
    02  H4-LC    PIC 99. 
    02  FILLER   PIC X(9)  VALUE "Address: ". 
    02  H4-STRT  PIC X(20). 
    02  FILLER   PIC X     VALUE SPACE. 
    02  H4-CITY  PIC X(15). 
    02  FILLER   PIC X     VALUE SPACE. 
    02  H4-STATE PIC XX. 
    02  FILLER   PIC X     VALUE SPACE. 
    02  H4-ZIP   PIC 99999. 
01  HEAD-5. 
    02  H5-LC    PIC 99. 
    02  FILLER   PIC X(4)  VALUE "Date". 
    02  FILLER   PIC X(7)  VALUE SPACES. 
    02  FILLER   PIC X(6)  VALUE "Amount". 
    02  FILLER   PIC X(10) VALUE SPACES. 
    02  FILLER   PIC X(11) VALUE "Description". 
01  HEAD-6       PIC X(61) VALUE ALL "-". 
01  DETAIL-LINE. 
    02  DET-LC   PIC 99. 
    02  DL-DATE  PIC X(9). 
    02  FILLER   PIC X     VALUE SPACE. 
    02  DL-AMT   PIC $ZZZ,ZZZ.99-. 
    02  FILLER   PIC X     VALUE SPACE. 
    02  DL-DESC  PIC X(20). 
01  TOTAL-LINE. 
    02  TOT-LC   PIC 99. 
    02  FILLER   PIC X(25) VALUE "Total purchases to date: ". 
    02  TL       PIC $ZZZ,ZZZ,ZZZ.99-. 
01  TOTAL-PURCHASES        PIC S9(9)V99. 
01  PAGE-NUMBER            PIC S9(9). 
01  HOLD-I-ACCOUNT-NUMBER  PIC X(9)   VALUE IS LOW-VALUES. 
01  END-OF-FILE            PIC X      VALUE IS "N". 
01  THESE-MANY             PIC 99     VALUE IS 1. 
 
PROCEDURE DIVISION. 
A000-BEGIN. 
    OPEN INPUT  INPUT-FILE 
         OUTPUT REPORT-FILE. 
    DISPLAY " Enter date--DD-MMM-YY:". 
    ACCEPT H2-DATE. 
    PERFORM A100-READ-INPUT UNTIL END-OF-FILE = "Y". 
A050-WRAP-UP. 
    CLOSE INPUT-FILE 
          REPORT-FILE. 
    DISPLAY "END-OF-JOB". 
    STOP RUN. 
A100-READ-INPUT. 
    READ INPUT-FILE AT END MOVE "Y" TO END-OF-FILE 
                           PERFORM A400-PRINT-TOTALS 
                           MOVE HIGH-VALUES TO I-ACCOUNT-NUMBER. 
    DISPLAY INPUT-RECORD. 
    IF END-OF-FILE NOT = "Y" 
       AND I-ACCOUNT-NUMBER NOT = HOLD-I-ACCOUNT-NUMBER 
              PERFORM A200-NEW-CUSTOMER. 
    IF END-OF-FILE NOT = "Y" 
       AND I-ACCOUNT-NUMBER = HOLD-I-ACCOUNT-NUMBER 
              PERFORM A300-PRINT-DETAIL-LINE. 
    MOVE I-ACCOUNT-NUMBER TO HOLD-I-ACCOUNT-NUMBER. 
A200-NEW-CUSTOMER. 
    IF HOLD-I-ACCOUNT-NUMBER = LOW-VALUES 
           PERFORM A600-SET-UP-HEADERS 
           PERFORM A500-PRINT-HEADERS 
           PERFORM A300-PRINT-DETAIL-LINE 
       ELSE 
           PERFORM A400-PRINT-TOTALS 
           PERFORM A600-SET-UP-HEADERS 
           PERFORM A500-PRINT-HEADERS 
           PERFORM A300-PRINT-DETAIL-LINE. 
A300-PRINT-DETAIL-LINE. 
    MOVE I-PURCHASE-DATE    TO DL-DATE. 
    MOVE I-PURCHASE-AMOUNT  TO DL-AMT. 
    MOVE I-PURCHASE-DESCRIP TO DL-DESC. 
* At EOP this last detail line goes in footing area of current page 
    WRITE PRINT-LINE FROM DETAIL-LINE 
                     AT END-OF-PAGE PERFORM A500-PRINT-HEADERS. 
    ADD I-PURCHASE-AMOUNT TO TOTAL-PURCHASES. 
A400-PRINT-TOTALS. 
    MOVE TOTAL-PURCHASES TO TL. 
* Skip to footing area 
    COMPUTE THESE-MANY = 25 - LINAGE-COUNTER. 
    WRITE PRINT-LINE FROM TOTAL-LINE AFTER ADVANCING THESE-MANY LINES. 
    MOVE 0 TO TOTAL-PURCHASES. 
A500-PRINT-HEADERS. 
    ADD 1 TO PAGE-NUMBER. 
    MOVE PAGE-NUMBER TO H1-PAGE. 
    WRITE PRINT-LINE FROM HEAD-1 AFTER ADVANCING PAGE. 
    WRITE PRINT-LINE FROM HEAD-2. 
    MOVE SPACES TO PRINT-LINE. 
    WRITE PRINT-LINE. 
    WRITE PRINT-LINE FROM HEAD-3. 
    WRITE PRINT-LINE FROM HEAD-4. 
    WRITE PRINT-LINE FROM HEAD-5. 
    WRITE PRINT-LINE FROM HEAD-6. 
A600-SET-UP-HEADERS. 
    MOVE I-FIRST          TO H3-FNAME. 
    MOVE I-MID            TO H3-MNAME. 
    MOVE I-LAST           TO H3-LNAME. 
    MOVE I-ACCOUNT-NUMBER TO H3-NUM. 
    MOVE I-STREET         TO H4-STRT. 
    MOVE I-CITY           TO H4-CITY. 
    MOVE I-STATE          TO H4-STATE. 
    MOVE I-ZIP            TO H4-ZIP. 

10.6.6 Printing a Linage-File Report

The default PRINT command inserts a page ejection when a form nears the end of a page. Therefore, when the default PRINT command refers to a linage-file report, it can change the report's page spacing.

On Tru64 UNIX systems, to print a linage-file report, use this command:


% lpr report-file-specification  <>

On OpenVMS Alpha systems, to print a linage-file report, use the /NOFEED qualifier with the DCL PRINT command as follows:


$ PRINT report-file-specification/NOFEED 

On OpenVMS Alpha systems, the LINAGE clause causes a Compaq COBOL report file to be in print-file format. (See Chapter 6 for more information.) <>

When a WRITE statement positions the file to the top of the next logical page, the device is positioned by line spacing rather than by page ejection or form feed.

For more information on printing your report, see Section 10.7.

10.6.7 A Linage-File Report Example

Example 10-5 shows a Compaq COBOL program that produces a linage-file report.

The LINAGE clause in the following File Description entry defines the logical page areas shown in Figure 10-8:


FD  MINIF1-REPORT 
    LINAGE IS 13 LINES 
                       LINES AT TOP      2 
                       LINES AT BOTTOM   5. 

Figure 10-8 shows a 20-line logical page that includes a top margin (T), a page body (P), and a bottom margin (B).

Figure 10-8 A 20-Line Logical Page


The first line to which the logical page can be positioned is the third line on the page; this is the first print line. The page-overflow condition occurs when a WRITE statement causes the LINAGE-COUNTER value to equal 15. Line 15 is the last line on the page on which text can be written. The page advances to the next logical page when a WRITE statement causes the LINAGE-COUNTER value to exceed 15. The pointer is then positioned on the first print line of the next logical page.

LINAGE is the sum of N (where N represents the number of lines of text) plus X (where X represents the number of lines at the top) plus Y (where Y represents the number of lines at the bottom). The sum total should not exceed the length of the physical page, which is usually 66 lines.

Example 10-5 Programming a 20-Line Logical Page Defined by the LINAGE Clause with Automatic Page Overflow

IDENTIFICATION DIVISION. 
PROGRAM-ID. REPLINAG. 
ENVIRONMENT DIVISION. 
INPUT-OUTPUT SECTION. 
FILE-CONTROL. 
    SELECT INPUT-FILE   ASSIGN TO "REPIN.DAT". 
    SELECT MINIF1-REPORT ASSIGN TO "MINIF1.DAT". 
DATA DIVISION. 
FILE SECTION. 
FD  INPUT-FILE. 
01  INPUT-RECORD. 
    02  I-NAME. 
        03  I-FIRST                      PIC X(10). 
        03  I-MID                        PIC X. 
        03  I-LAST                       PIC X(15). 
    02  I-ADDRESS. 
        03  I-STREET                     PIC X(20). 
        03  I-CITY                       PIC X(15). 
        03  I-STATE                      PIC XX. 
        03  I-ZIP                        PIC 99999. 
FD  MINIF1-REPORT 
    LINAGE IS 13 LINES 
           LINES AT TOP    2 
           LINES AT BOTTOM 5. 
01  MINIF1-PRINT-LINE                    PIC X(80). 
WORKING-STORAGE SECTION. 
01  END-OF-FILE                          PIC  X     VALUE SPACE. 
01  LINE-UP-OK                           PIC  X     VALUE SPACE. 
01  MINIF1-LINE-3. 
    02  FILLER                           PIC X(9)   VALUE SPACES. 
    02  MINIF1-LAST                      PIC X(15). 
    02  FILLER                           PIC X(23)  VALUE SPACES. 
    02  FILLER                           PIC X(6)   VALUE "Date: ". 
    02  MINIF1-DATE                      PIC 99/99/99. 
01  MINIF1-LINE-13. 
    02  FILLER                           PIC X(4)   VALUE SPACES. 
    02  MINIF1-NAME                      PIC X(26). 
01  MINIF1-LINE-14. 
    02  FILLER                           PIC X(4)   VALUE SPACES. 
    02  MINIF1-STREET                    PIC X(20). 
01  MINIF1-LINE-15. 
    02  FILLER                           PIC X(4)   VALUE SPACES. 
    02  MINIF1-CITY                      PIC X(15). 
    02  FILLER                           PIC X      VALUE SPACE. 
    02  MINIF1-STATE                     PIC XX. 
    02  FILLER                           PIC X      VALUE SPACE. 
    02  MINIF1-ZIP                       PIC 99999. 
PROCEDURE DIVISION. 
A000-BEGIN. 
    OPEN OUTPUT MINIF1-REPORT. 
    ACCEPT MINIF1-DATE FROM DATE. 
    PERFORM A300-FORM-LINE-UP UNTIL LINE-UP-OK = "Y". 
    OPEN INPUT  INPUT-FILE. 
    PERFORM A100-READ-INPUT UNTIL END-OF-FILE = "Y". 
A010-WRAP-UP. 
    CLOSE INPUT-FILE 
          MINIF1-REPORT. 
    DISPLAY "END OF JOB". 
    STOP RUN. 
A100-READ-INPUT. 
    READ INPUT-FILE AT END MOVE "Y" TO END-OF-FILE. 
    IF END-OF-FILE NOT = "Y" 
       PERFORM A200-PRINT-REPORT. 
A200-PRINT-REPORT. 
    MOVE I-LAST          TO MINIF1-LAST. 
    WRITE MINIF1-PRINT-LINE FROM MINIF1-LINE-3 BEFORE ADVANCING 1 LINE. 
    MOVE SPACES TO MINIF1-PRINT-LINE. 
    WRITE MINIF1-PRINT-LINE AFTER ADVANCING 9 LINES. 
    MOVE I-NAME          TO MINIF1-NAME. 
    WRITE MINIF1-PRINT-LINE FROM MINIF1-LINE-13 BEFORE ADVANCING 1 LINE. 
    MOVE I-STREET        TO MINIF1-STREET. 
    WRITE MINIF1-PRINT-LINE FROM MINIF1-LINE-14 BEFORE ADVANCING 1 LINE. 
    MOVE I-CITY          TO MINIF1-CITY. 
    MOVE I-STATE     TO MINIF1-STATE. 
    MOVE I-ZIP       TO MINIF1-ZIP. 
    WRITE MINIF1-PRINT-LINE FROM MINIF1-LINE-15 BEFORE ADVANCING 1 LINE. 
A300-FORM-LINE-UP. 
    MOVE ALL "X" TO INPUT-RECORD. 
    PERFORM A200-PRINT-REPORT 3 TIMES. 
    DISPLAY "Is Alignment OK? (Y/N): " WITH NO ADVANCING. 
    ACCEPT LINE-UP-OK. 

10.7 Modes for Printing Reports

Either your Compaq COBOL program can allocate a printer directly and immediately produce the report, or it can spool the report to a mass storage device for printing later. Section 10.7.1 and Section 10.7.2 describe these two modes of printing. Note that spooling the report to a mass storage device makes better use of system resources than allocating a printer directly.

10.7.1 Directly Allocating a Printer

To directly allocate a printer, your Compaq COBOL program must include the printer's device name in the file specification for the report file.

On OpenVMS, for example:


SELECT REPORT-FILE ASSIGN TO "LP:".   <>

Directly allocating the printer has the following advantages:

Directly allocating the printer has the following disadvantages:

10.7.2 Spooling to a Mass Storage Device

To spool your report to a mass storage device (such as a disk or magnetic tape) for later printing, your Compaq COBOL program must include a file specification. For example, to spool JAN28P.DAT you would include the following code in your program:


SELECT REPORT-FILE ASSIGN TO "USER1$:JAN28P".   (OpenVMS) 
SELECT REPORT-FILE ASSIGN TO "/usr1$/JAN28P".   (Tru64 UNIX) 

Spooling to a mass storage device has the following advantages:

Spooling to a mass storage device has the following disadvantages:

10.8 Programming a Report Writer Report

Report Writer allows you to describe the appearance of a report's format. To do this, you specify the Report Writer statements that describe the report's contents and control in the Report Section of the Data Division. These statements replace many complex, detailed procedures that you would otherwise have to include in a conventional or linage-file report.

The following sections explain how to produce a report with the Report Writer. These sections describe how to do the following:

Detailed examples using Report Writer are documented in Section 10.9.


Previous Next Contents Index