TOYS1 - program with headers

This program has a page and a columnn header written at the top of the first page.

       IDENTIFICATION DIVISION.
       PROGRAM-ID.  TOYS.
       AUTHOR.  GROCER.
       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT TOYS-FILE
               ASSIGN TO "C:\PCOBWIN\CIS12FST\C12TOYS.DAT".
           SELECT TOYS-REPORT
               ASSIGN TO "A:\toys1out".
       DATA DIVISION.
       FILE SECTION.
       FD  TOYS-FILE
           DATA RECORD IS TOYS-REC.
       01  TOYS-REC.
           05  TOY-ID              PIC XXXX.
           05  TOY-NAME            PIC X(20).
           05  ON-HAND             PIC 9(5).
           05  ON-ORDER            PIC 9(5).
           05  REORDER-PT          PIC 9(5).
           05  COST                PIC 999V99.
           05  PRICE               PIC 999V99.
       FD  TOYS-REPORT
           DATA RECORD IS PRINTZ.
       01  PRINTZ.
           05  FILLER              PIC X.
           05  TOY-ID-PR           PIC XXXX.
           05  FILLER              PIC XXX.
           05  TOY-NAME-PR         PIC X(20).
           05  FILLER              PIC XXX.
           05  COST-PR             PIC $ZZ9.99.
           05  FILLER              PIC XXXX.
           05  PRICE-PR            PIC $ZZ9.99.
           05  FILLER              PIC XXXX.
           05  ON-HAND-PR          PIC ZZ,ZZ9.
           05  FILLER              PIC XXXX.
           05  ON-ORDER-PR         PIC ZZ,ZZ9.
           05  FILLER              PIC XXXX.
           05  REORDER-PT-PR       PIC ZZ,ZZ9.
           05  FILLER              PIC X.
       WORKING-STORAGE SECTION.
       01  INDICATORS.
           05  MORE-RECORDS        PIC XXX    VALUE "YES".
The page header is defined in working storage. We want to have it in the center of the line. To do this, we count the number of characters in the literal we want to print (TOY DEPARTMENT INVENTORY). It is 24 characters. The line is 80 characters. 80 - 24 = 56. Since we want to center the header, we divide the 56 by 2 to get the number of characters (28) to put in the first filler and the last filler.
       01  PAGE-HDR.
           05  FILLER              PIC X(28)  VALUE SPACES.
           05  FILLER              PIC X(24)
               VALUE "TOY DEPARTMENT INVENTORY".
           05  FILLER              PIC X(28)  VALUE SPACES.
The column header is also defined in working storage. We want to have a header over each column. To do this we lay out the fields defined in PRINTZ on a piece of paper and we then write the column headers over the fields on PRINTZ. The next job is to count. We need to figure out how many characters the header words take, how many blank spaces are needed etc. Once we have the columnn header layed out, we can then code it. In the coding below, I have one field per field and in many cases I have combined the fillers by putting spaces in the literals. For example, look at cost. It is a X(11) field but the actual word COST only takes 4 characters. This is because there are 3 spaces, then COST and then 4 spaces. Notice that I could have combined fields. For example I could have combined the first two fields and coded 05 FILLER PIC X(11) VALUE " ID # TOY". As another example, I could have combined the last 3 fields and coded 05 FILLER PIC X(27) VALUE "ON HAND ON ORDER REORDER ". The only rule for combining is that no literal can be bigger than 120.
       01  COLUMN-HDR.
  
           05  FILLER              PIC X(8)   VALUE " ID #   ".
           05  FILLER              PIC X(3)   VALUE "TOY".
           05  FILLER              PIC X(20)  VALUE SPACES.
           05  FILLER              PIC X(11)  VALUE "   COST    ".
           05  FILLER              PIC X(11)  VALUE "  PRICE    ".
           05  FILLER              PIC X(10)  VALUE "ON HAND   ".
           05  FILLER              PIC X(10)  VALUE "ON ORDER  ".
           05  FILLER              PIC X(7)   VALUE "REORDR ".
       PROCEDURE DIVISION.
       MAIN-PROGRAM.
           PERFORM A-100-STARTUP.
           PERFORM B-100-PROCESS.
           PERFORM C-100-TERMINATE.
           STOP RUN.
       A-100-STARTUP.
           OPEN INPUT TOYS-FILE
                OUTPUT TOYS-REPORT.
The page and column header are written in A-100-STARTUP right after the files have been opened. This means we will only get headers at the top of the first page. To get headers at the top of each page, we would need to code things in a different way. The headers have been defined in working storage. As we know, we cannot write directly from working storage. Input and output must pass through the file section. The way we do this is to WRITE PRINTZ which is defined in the 01 level of the FD from the line we defined in working storage. In the case of the page header, we want to write the header at the top of the page so the AFTER ADVANCING clause use the reserved word PAGE. Different COBOLs may use different reserved words here and others may force a form of definition, but most will use the reserved word PAGE. We want to leave a blank line between the page header and the column header so we write the column header after advancing 2 lines. This results in the blank line that we want. We also want to write a blank line after the column header. To do this we move spaces to printz to clear it out and then write the empty printz after advancing one line. This results in writing a blank line.

Please note that WRITE PRINTZ FROM PAGE-HDR could also have been coded as MOVE PAGE-HDR TO PRINTZ and then WRITE PRINTZ. This means that the FROM works like a MOVE. This is why we have to move spaces to PRINTZ to clear it out before writing PRINTZ.
           WRITE PRINTZ FROM PAGE-HDR
                AFTER ADVANCING PAGE.
           WRITE PRINTZ FROM COLUMN-HDR
                AFTER ADVANCING 2 LINES.
           MOVE SPACES TO PRINTZ.
           WRITE PRINTZ
                AFTER ADVANCING 1 LINES.
       B-100-PROCESS.
           READ TOYS-FILE
               AT END
                  MOVE "NO " TO MORE-RECORDS.
           PERFORM B-200-LOOP
               UNTIL MORE-RECORDS = "NO ".
       B-200-LOOP.
           MOVE SPACES TO PRINTZ.
           MOVE TOY-ID TO TOY-ID-PR.
           MOVE TOY-NAME TO TOY-NAME-PR.
           MOVE COST TO COST-PR.
           MOVE PRICE TO PRICE-PR.
           MOVE ON-HAND TO ON-HAND-PR.
           MOVE ON-ORDER TO ON-ORDER-PR.
           MOVE REORDER-PT TO REORDER-PT-PR.
           WRITE PRINTZ
               AFTER ADVANCING 1 LINES.
           READ TOYS-FILE
               AT END
                  MOVE "NO " TO MORE-RECORDS.
       C-100-TERMINATE.
           CLOSE TOYS-FILE
                 TOYS-REPORT.
      *
      *This is the input file:
      *
      *1212TEDDY BEAR          0002000025000500200002499
      *1234TEA SET             0001000030000300050000799
      *1245SUPERMAN            0003500000000500080001099
      *1266DUMP TRUCK          0007500000001000100001599
      *1289BABY DOLL           0004000025000500070001299
      *1444BLOCKS              0000000050000500050000899
      *
      *This is the output file that is written to the printer.
      *
      *                            TOY DEPARTMENT INVENTORY
      *
      * ID #   TOY                       COST      PRICE    ON HAND   ON ORDER  REORDR
      *
      * 1212   TEDDY BEAR             $ 20.00    $ 24.99        20        25        50
      * 1234   TEA SET                $  5.00    $  7.99        10        30        30
      * 1245   SUPERMAN               $  8.00    $ 10.99        35         0        50
      * 1266   DUMP TRUCK             $ 10.00    $ 15.99        75         0       100
      * 1289   BABY DOLL              $  7.00    $ 12.99        40        25        50
      * 1444   BLOCKS                 $  5.00    $  8.99         0        50        50