Teach Yourself COBOL in 21 days, Second Edition

Previous chapterNext chapterContents


- Day 21 -
Selecting, Sorting, and Reporting

Reporting is the most visible part of any program. Hard-copy reports tend to circulate and be seen by many users. Reports tend to be the area where most modification requests come in. You need several tools to handle reports effectively.

Today, you learn about the following topics:

Continuing the Bills Payment System

Figure 21.1 shows the flowchart from Day 20. Steps 2, 7, and 12, shown in light gray, were completed on that day. In today's lesson, you complete steps 4, 6, and 8 shown in dark gray. This will complete all of the computer processes in the bills payment system.

Figure 21.1.
The bills payment system.

You start with step 6, the selection of records by date range.

Selecting Records

In many programs, it is necessary to read through a file, picking out records that require processing. Step 4 in Figure 21.1 is to report on all unpaid bills. That report has to select for printing all voucher records in which the VOUCHER-PAID-DATE is zeroes. In step 8, the cash-requirements report selects for printing all vouchers that are unpaid (VOUCHER-PAID-DATE = ZEROES) and that are selected for payment (VOUCHER-SELECTED = "Y").

There are several solutions to this selection problem, but one of the most efficient methods is to stick with the basic processing-loop design. Listing 21.1 shows the pseudocode for this style of processing.

TYPE: Listing 21.1. Pseudocode for a selected records-processing loop.

process-records
    read-first-valid-record
    perform process-loop
        until file-at-end
process-loop
    process-this-record
    read-next-valid-record

ANALYSIS: In some programs, such as those covered in Day 17, "Alternate Keys," it is necessary to use a START command to change the key path in the file before reading through the file. In such a program, the read-first-valid-record action is used to set up the file so that it can be read.

In other programs, you don't need to do any setting up. The OPEN positions the file so that the first READ NEXT will return the first record on the primary key path. In this type of program, there is no difference between a read-first-valid-record and a read-next-valid-record.

The read-next-valid-record logic reads a record and makes all the decisions necessary to determine that this record fits the selection criteria. The read-first-valid-record action sets up the file, reads a record, and then uses the same decisions used in read-next-valid-record. Listing 21.2 shows how this code might look on the voucher file.

TYPE: Listing 21.2. Code for a selected records processing loop.

010100 PROCESS-VOUCHERS.
010200    PERFORM READ-FIRST-VALID-VOUCHER.
010300    PERFORM PROCESS-ALL-VOUCHERS
010400        UNTIL VOUCHER-FILE-AT-END = "Y".
010500
010600 PROCESS-ALL-VOUCHERS.
010700    PERFORM PROCESS-THIS-VOUCHER.
010800    PERFORM READ-NEXT-VALID-VOUCHER.

Step 6 in Figure 21.1, selecting vouchers by range, is really a two-step process. Selecting vouchers for payment the first time is simple, but if the user wants to change the selection, there must be some way to clear out existing selections in order to start over again. This process of clearing existing selections and selecting could be combined into one program, but for ease of illustration, it is broken down here into two separate programs.

The vchclr01.cbl program in Listing 21.3 clears all VOUCHER-SELECTED flags, and vchsel01.cbl (which you'll see soon) selects vouchers by range.

TYPE: Listing 21.3. Clearing existing selections.

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID. VCHCLR01.
000300*--------------------------------
000400* Asks the user if all selected
000500* vouchers should be cleared.
000600*
000700* 1. Searches the voucher file for
000800*    unpaid vouchers that are
000900*    selected and clears the
001000*    selected flag
001100*--------------------------------
001200 ENVIRONMENT DIVISION.
001300 INPUT-OUTPUT SECTION.
001400 FILE-CONTROL.
001500
001600     COPY "SLVOUCH.CBL".
001700
001800 DATA DIVISION.
001900 FILE SECTION.
002000
002100     COPY "FDVOUCH.CBL".
002200
002300 WORKING-STORAGE SECTION.
002400
002500 77  OK-TO-CLEAR             PIC X.
002600 77  VOUCHER-FILE-AT-END     PIC X.
002700
002800     COPY "WSCASE01.CBL".
002900
003000 PROCEDURE DIVISION.
003100 PROGRAM-BEGIN.
003200     PERFORM OPENING-PROCEDURE.
003300     PERFORM MAIN-PROCESS.
003400     PERFORM CLOSING-PROCEDURE.
003500
003600 PROGRAM-EXIT.
003700     EXIT PROGRAM.
003800
003900 PROGRAM-DONE.
004000     STOP RUN.
004100
004200 OPENING-PROCEDURE.
004300     OPEN I-O VOUCHER-FILE.
004400
004500 CLOSING-PROCEDURE.
004600     CLOSE VOUCHER-FILE.
004700
004800 MAIN-PROCESS.
004900     PERFORM GET-OK-TO-CLEAR.
005000     IF OK-TO-CLEAR = "Y"
005100         PERFORM PROCESS-VOUCHERS.
005200
005300 GET-OK-TO-CLEAR.
005400     PERFORM ACCEPT-OK-TO-CLEAR.
005500     PERFORM RE-ACCEPT-OK-TO-CLEAR
005600         UNTIL OK-TO-CLEAR = "Y" OR "N".
005700
005800 ACCEPT-OK-TO-CLEAR.
005900     DISPLAY "CLEAR ALL PREVIOUS SELECTIONS (Y/N)?".
006000     ACCEPT OK-TO-CLEAR.
006100     INSPECT OK-TO-CLEAR
006200       CONVERTING LOWER-ALPHA
006300       TO         UPPER-ALPHA.
006400
006500
006600 RE-ACCEPT-OK-TO-CLEAR.
006700     DISPLAY "YOU MUST ENTER YES OR NO".
006800     PERFORM ACCEPT-OK-TO-CLEAR.
006900
007000*--------------------------------
007100* Clear all previous selections.
007200*--------------------------------
007300 PROCESS-VOUCHERS.
007400     PERFORM READ-FIRST-VALID-VOUCHER.
007500     PERFORM PROCESS-ALL-VOUCHERS
007600         UNTIL VOUCHER-FILE-AT-END = "Y".
007700
007800 PROCESS-ALL-VOUCHERS.
007900     PERFORM PROCESS-THIS-VOUCHER.
008000     PERFORM READ-NEXT-VALID-VOUCHER.
008100
008200 PROCESS-THIS-VOUCHER.
008300     MOVE "N" TO VOUCHER-SELECTED
008400     PERFORM REWRITE-VOUCHER-RECORD.
008500
008600*--------------------------------
008700* Read first, read next routines
008800*--------------------------------
008900 READ-FIRST-VALID-VOUCHER.
009000     PERFORM READ-NEXT-VALID-VOUCHER.
009100
009200 READ-NEXT-VALID-VOUCHER.
009300     PERFORM READ-NEXT-VOUCHER-RECORD.
009400     PERFORM READ-NEXT-VOUCHER-RECORD
009500         UNTIL VOUCHER-FILE-AT-END = "Y"
009600            OR (    VOUCHER-PAID-DATE = ZEROES
009700                AND VOUCHER-SELECTED = "Y").
009800
009900 READ-NEXT-VOUCHER-RECORD.
010000     MOVE  "N" TO VOUCHER-FILE-AT-END.
010100     READ VOUCHER-FILE NEXT RECORD
010200        AT END
010300         MOVE "Y" TO VOUCHER-FILE-AT-END.
010400
010500*--------------------------------
010600* Other File I-O routines.
010700*--------------------------------
010800 REWRITE-VOUCHER-RECORD.
010900     REWRITE VOUCHER-RECORD
011000         INVALID KEY
011100         DISPLAY "ERROR REWRITING VENDOR RECORD".
011200

ANALYSIS: The MAIN-PROCESS of the program at line 004800 starts by asking the user whether to "CLEAR ALL PREVIOUS SELECTIONS (Y/N)?". This gives the user a chance to back out in case the program was run incorrectly. The routines to ask the user extend from line 005300 through line 006800. If the user answers yes, PROCESS-VOUCHERS at line 007300 is performed. This logic extends from line 007300 through line 008400 and follows the format of a selected records processing loop.

The actual processing of the voucher is at line 008200 in PROCESS-THIS-VOUCHER. This routine moves "N" to VOUCHER-SELECTED and rewrites the record. This takes care of what is to be done to the records, but the selection of which records it will be done to still needs attention.

READ-FIRST-VALID-VOUCHER and READ-NEXT-VALID-VOUCHER are at lines 008900 and 009200. No special setup is needed for the READ-FIRST-VALID-VOUCHER routine, so it simply performs READ-NEXT-VALID-VOUCHER.

The real action takes place in READ-NEXT-VALID-VOUCHER at line 009200. At first glance, the paragraph seems odd because it appears to read the next voucher record twice. Remember that the UNTIL in a PERFORM UNTIL is tested once before anything is performed. Lines 009200 through 009700 actually do the following:

1. Read the next voucher record.

2. Test whether the file is at end or paid date is zeroes and the selected flag is "Y".

3. If none of the conditions is true, read the next voucher record and go back to step 2.

It is easy to forget that the test in a PERFORM UNTIL occurs before the PERFORM because of the way the command is structured.

The overall effect is that READ-NEXT-VALID-VOUCHER continues reading through the file until either the file is exhausted (at end), or a record is found that matches the two conditions of VOUCHER-PAID-DATE = ZEROES and VOUCHER-SELECTED = "Y". The READ-NEXT-VOUCHER-RECORD routine at line 009900 is a standard read-next routine that sets an at-end flag.

The pseudocode for record selection now can be extended to incorporate the logic for reading the first and next selected records, as in Listing 21.4.

TYPE: Listing 21.4. An extended selected record-processing loop.

process-records
    read-first-valid-record
    perform process-loop
        until file-at-end
process-loop
    process-this-record
    read-next-valid-record
read-first-valid-record
    start-the-file
    read-next-valid-record
read-next-valid-record
    read-next-record
    perform read-next-record
        until file is at end
        or (the selection condition is met)

The second half of the selection problem is solved with vchsel01.cbl, shown in Listing 21.5. This program enables the user to select vouchers for payment by a cutoff date. The user enters a cutoff date, and all unpaid vouchers due on or before that date are selected for payment. The vchsel01.cbl program that you are about to create (vchclr01.cbl) and vchpic01.cbl created in Day 20, "More Complex Data Entry," can be used repeatedly to select and reselect vouchers. This will be done as long as the cash requirements report (step 8 of Figure 21.1) produces a number that is too large to pay.

TYPE: Listing 21.5. Selecting by cutoff date.

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID. VCHSEL01.
000300*--------------------------------
000400* Asks the user for a cutoff
000500* date
000600*
000700* 1. Searches the voucher file for
000800*    unpaid vouchers that are
000900*    within the cut off date
001000*    and reflags them as selected
001100*--------------------------------
001200 ENVIRONMENT DIVISION.
001300 INPUT-OUTPUT SECTION.
001400 FILE-CONTROL.
001500
001600     COPY "SLVOUCH.CBL".
001700
001800 DATA DIVISION.
001900 FILE SECTION.
002000
002100     COPY "FDVOUCH.CBL".
002200
002300 WORKING-STORAGE SECTION.
002400
002500 77  OK-TO-PROCESS           PIC X.
002600 77  VOUCHER-FILE-AT-END     PIC X.
002700
002800 77  CUT-OFF-DATE            PIC 9(8).
002900
003000     COPY "WSCASE01.CBL".
003100
003200     COPY "WSDATE01.CBL".
003300
003400 PROCEDURE DIVISION.
003500 PROGRAM-BEGIN.
003600     PERFORM OPENING-PROCEDURE.
003700     PERFORM MAIN-PROCESS.
003800     PERFORM CLOSING-PROCEDURE.
003900
004000 PROGRAM-EXIT.
004100     EXIT PROGRAM.
004200
004300 PROGRAM-DONE.
004400     STOP RUN.
004500
004600 OPENING-PROCEDURE.
004700     OPEN I-O VOUCHER-FILE.
004800
004900 CLOSING-PROCEDURE.
005000     CLOSE VOUCHER-FILE.
005100
005200 MAIN-PROCESS.
005300     PERFORM GET-OK-TO-PROCESS.
005400     IF OK-TO-PROCESS = "Y"
005500         PERFORM GET-CUT-OFF-DATE
005600         PERFORM PROCESS-VOUCHERS.
005700
005800 GET-OK-TO-PROCESS.
005900     PERFORM ACCEPT-OK-TO-PROCESS.
006000     PERFORM RE-ACCEPT-OK-TO-PROCESS
006100         UNTIL OK-TO-PROCESS = "Y" OR "N".
006200
006300 ACCEPT-OK-TO-PROCESS.
006400     DISPLAY "SELECT VOUCHER BY DATE RANGE (Y/N)?".
006500     ACCEPT OK-TO-PROCESS.
006600     INSPECT OK-TO-PROCESS
006700       CONVERTING LOWER-ALPHA
006800       TO         UPPER-ALPHA.
006900
007000
007100 RE-ACCEPT-OK-TO-PROCESS.
007200     DISPLAY "YOU MUST ENTER YES OR NO".
007300     PERFORM ACCEPT-OK-TO-PROCESS.
007400
007500 GET-CUT-OFF-DATE.
007600     MOVE "N" TO ZERO-DATE-IS-OK.
007700     MOVE "SELECT ON OR BEFORE (MM/DD/CCYY)?"
007800             TO DATE-PROMPT.
007900     PERFORM GET-A-DATE.
008000     MOVE DATE-CCYYMMDD TO CUT-OFF-DATE.
008100
008200*--------------------------------
008300* Clear all previous selections.
008400*--------------------------------
008500 PROCESS-VOUCHERS.
008600     PERFORM READ-FIRST-VALID-VOUCHER.
008700     PERFORM PROCESS-ALL-VOUCHERS
008800         UNTIL VOUCHER-FILE-AT-END = "Y".
008900
009000 PROCESS-ALL-VOUCHERS.
009100     PERFORM PROCESS-THIS-VOUCHER.
009200     PERFORM READ-NEXT-VALID-VOUCHER.
009300
009400 PROCESS-THIS-VOUCHER.
009500     MOVE "Y" TO VOUCHER-SELECTED
009600     PERFORM REWRITE-VOUCHER-RECORD.
009700
009800*--------------------------------
009900* Read first, read next routines
010000*--------------------------------
010100 READ-FIRST-VALID-VOUCHER.
010200     PERFORM READ-NEXT-VALID-VOUCHER.
010300
010400 READ-NEXT-VALID-VOUCHER.
010500     PERFORM READ-NEXT-VOUCHER-RECORD.
010600     PERFORM READ-NEXT-VOUCHER-RECORD
010700         UNTIL VOUCHER-FILE-AT-END = "Y"
010800            OR (    VOUCHER-PAID-DATE = ZEROES
010900                AND VOUCHER-DUE NOT > CUT-OFF-DATE).
011000
011100 READ-NEXT-VOUCHER-RECORD.
011200     MOVE  "N" TO VOUCHER-FILE-AT-END.
011300     READ VOUCHER-FILE NEXT RECORD
011400        AT END
011500         MOVE "Y" TO VOUCHER-FILE-AT-END.
011600
011700*--------------------------------
011800* Other File I-O routines.
011900*--------------------------------
012000 REWRITE-VOUCHER-RECORD.
012100     REWRITE VOUCHER-RECORD
012200         INVALID KEY
012300         DISPLAY "ERROR REWRITING VENDOR RECORD".
012400*--------------------------------
012500* Utility routines.
012600*--------------------------------
012700     COPY "PLDATE01.CBL".
012800

ANALYSIS: This program is similar to vchclr01.cbl. The user is asked at line 005300 whether to continue. If the answer is yes, GET-CUT-OFF-DATE is performed to get a date range to use for the selection process. This is a simple routine at line 007500 that asks the user for a required date and stores it in CUT-OFF-DATE. It uses the GET-A-DATE routine that was created in pldate01.cbl. This is copied at the end of the program. After the cutoff date is entered, the flow of the program is identical to vchclr01.cbl.

The only real differences are at line 009500 in PROCESS-THIS-VOUCHER, which moves "Y" instead of "N" to VOUCHER-SELECTED, and in the record selection logic at lines 010700 through 010900. The selection is for records with VOUCHER-PAID-DATE = ZEROES and VOUCHER-DUE NOT > CUT-OFF-DATE.

Sorting a File

The bills report lists all the outstanding bills. It is step 4 of the flowchart in Figure 21.1. Figure 21.2 is a printer spacing chart for the bills report. The column headed S will be used to print the VOUCHER-SELECTED flag.

Figure 21.2.
The printer chart for bilrpt01.cbl.

Listing 21.6 is the simplest version of this report.

TYPE: Listing 21.6. The bills report.

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID. BILRPT01.
000300*--------------------------------
000400* Bills report in Due Date order
000500*--------------------------------
000600 ENVIRONMENT DIVISION.
000700 INPUT-OUTPUT SECTION.
000800 FILE-CONTROL.
000900
001000     COPY "SLVOUCH.CBL".
001100
001200     COPY "SLVND02.CBL".
001300
001400     SELECT PRINTER-FILE
001500         ASSIGN TO PRINTER
001600         ORGANIZATION IS LINE SEQUENTIAL.
001700
001800 DATA DIVISION.
001900 FILE SECTION.
002000
002100     COPY "FDVOUCH.CBL".
002200
002300     COPY "FDVND04.CBL".
002400
002500 FD  PRINTER-FILE
002600     LABEL RECORDS ARE OMITTED.
002700 01  PRINTER-RECORD             PIC X(80).
002800
002900 WORKING-STORAGE SECTION.
003000
003100 77  OK-TO-PROCESS         PIC X.
003200
003300     COPY "WSCASE01.CBL".
003400
003500 01  DETAIL-LINE.
003600     05  PRINT-NUMBER      PIC ZZZZ9.
003700     05  FILLER            PIC X(3) VALUE SPACE.
003800     05  PRINT-NAME        PIC X(30).
003900     05  FILLER            PIC X(1) VALUE SPACE.
004000     05  PRINT-DUE-DATE    PIC Z9/99/9999.
004100     05  FILLER            PIC X(1) VALUE SPACE.
004200     05  PRINT-AMOUNT      PIC ZZZ,ZZ9.99.
004300     05  FILLER            PIC X(1) VALUE SPACE.
004400     05  PRINT-INVOICE     PIC X(15).
004500     05  FILLER            PIC X(1) VALUE SPACE.
004600     05  PRINT-SELECTED    PIC X(1) VALUE SPACE.
004700
004800 01  TOTAL-THRU.
004900     05  FILLER            PIC X(20) VALUE SPACE.
005000     05  FILLER            PIC X(10) VALUE "TOTAL THRU".
005100
005200 01  COLUMN-LINE.
005300     05  FILLER         PIC X(7)  VALUE "VOUCHER".
005400     05  FILLER         PIC X(1)  VALUE SPACE.
005500     05  FILLER         PIC X(10) VALUE "VENDOR/For".
005600     05  FILLER         PIC X(23) VALUE SPACE.
005700     05  FILLER         PIC X(8)  VALUE "DUE DATE".
005800     05  FILLER         PIC X(1)  VALUE SPACE.
005900     05  FILLER         PIC X(10) VALUE "AMOUNT DUE".
006000     05  FILLER         PIC X(1)  VALUE SPACE.
006100     05  FILLER         PIC X(7)  VALUE "INVOICE".
006200     05  FILLER         PIC X(9)  VALUE SPACE.
006300     05  FILLER         PIC X(1)  VALUE "S".
006400
006500 01  TITLE-LINE.
006600     05  FILLER              PIC X(30) VALUE SPACE.
006700     05  FILLER              PIC X(12)
006800         VALUE "BILLS REPORT".
006900     05  FILLER              PIC X(19) VALUE SPACE.
007000     05  FILLER              PIC X(5) VALUE "PAGE:".
007100     05  FILLER              PIC X(1) VALUE SPACE.
007200     05  PRINT-PAGE-NUMBER   PIC ZZZ9.
007300
007400 77  VOUCHER-FILE-AT-END     PIC X.
007500 77  VENDOR-RECORD-FOUND     PIC X.
007600
007700 77  LINE-COUNT              PIC 999 VALUE ZERO.
007800 77  PAGE-NUMBER             PIC 9999 VALUE ZERO.
007900 77  MAXIMUM-LINES           PIC 999 VALUE 55.
008000
008100 77  RECORD-COUNT            PIC 9999 VALUE ZEROES.
008200
008300     COPY "WSDATE01.CBL".
008400
008500 PROCEDURE DIVISION.
008600 PROGRAM-BEGIN.
008700
008800     PERFORM OPENING-PROCEDURE.
008900     PERFORM MAIN-PROCESS.
009000     PERFORM CLOSING-PROCEDURE.
009100
009200 PROGRAM-EXIT.
009300     EXIT PROGRAM.
009400
009500 PROGRAM-DONE.
009600     STOP RUN.
009700
009800 OPENING-PROCEDURE.
009900     OPEN I-O VENDOR-FILE.
010000
010100     OPEN OUTPUT PRINTER-FILE.
010200
010300 MAIN-PROCESS.
010400     PERFORM GET-OK-TO-PROCESS.
010500     IF OK-TO-PROCESS = "Y"
010600         PERFORM PRINT-THE-REPORT.
010700
010800 CLOSING-PROCEDURE.
010900     CLOSE VENDOR-FILE.
011000     PERFORM END-LAST-PAGE.
011100     CLOSE PRINTER-FILE.
011200
011300 GET-OK-TO-PROCESS.
011400     PERFORM ACCEPT-OK-TO-PROCESS.
011500     PERFORM RE-ACCEPT-OK-TO-PROCESS
011600         UNTIL OK-TO-PROCESS = "Y" OR "N".
011700
011800 ACCEPT-OK-TO-PROCESS.
011900     DISPLAY "PRINT BILLS REPORT (Y/N)?".
012000     ACCEPT OK-TO-PROCESS.
012100     INSPECT OK-TO-PROCESS
012200       CONVERTING LOWER-ALPHA
012300       TO         UPPER-ALPHA.
012400
012500 RE-ACCEPT-OK-TO-PROCESS.
012600     DISPLAY "YOU MUST ENTER YES OR NO".
012700     PERFORM ACCEPT-OK-TO-PROCESS.
012800
012900 PRINT-THE-REPORT.
013000     OPEN INPUT VOUCHER-FILE.
013100     PERFORM START-ONE-REPORT.
013200     PERFORM PROCESS-VOUCHERS.
013300     PERFORM END-ONE-REPORT.
013400     CLOSE VOUCHER-FILE.
013500
013600 START-ONE-REPORT.
013700     PERFORM INITIALIZE-REPORT.
013800     PERFORM START-NEW-PAGE.
013900
014000 INITIALIZE-REPORT.
014100     MOVE ZEROES TO LINE-COUNT PAGE-NUMBER.
014200
014300 END-ONE-REPORT.
014400     IF RECORD-COUNT = ZEROES
014500         MOVE "NO RECORDS FOUND" TO PRINTER-RECORD
014600         PERFORM WRITE-TO-PRINTER.
014700
014800 PROCESS-VOUCHERS.
014900     PERFORM READ-FIRST-VALID-VOUCHER.
015000     PERFORM PROCESS-ALL-VOUCHERS
015100         UNTIL VOUCHER-FILE-AT-END = "Y".
015200
015300 PROCESS-ALL-VOUCHERS.
015400     PERFORM PROCESS-THIS-VOUCHER.
015500     PERFORM READ-NEXT-VALID-VOUCHER.
015600
015700 PROCESS-THIS-VOUCHER.
015800     ADD 1 TO RECORD-COUNT.
015900     IF LINE-COUNT > MAXIMUM-LINES
016000         PERFORM START-NEXT-PAGE.
016100     PERFORM PRINT-THE-RECORD.
016200
016300 PRINT-THE-RECORD.
016400     PERFORM PRINT-LINE-1.
016500     PERFORM PRINT-LINE-2.
016600     PERFORM LINE-FEED.
016700
016800 PRINT-LINE-1.
016900     MOVE SPACE TO DETAIL-LINE.
017000     MOVE VOUCHER-NUMBER TO PRINT-NUMBER.
017100
017200     MOVE VOUCHER-VENDOR TO VENDOR-NUMBER.
017300     PERFORM READ-VENDOR-RECORD.
017400     IF VENDOR-RECORD-FOUND = "Y"
017500         MOVE VENDOR-NAME TO PRINT-NAME
017600     ELSE
017700         MOVE "*VENDOR NOT ON FILE*" TO PRINT-NAME.
017800
017900     MOVE VOUCHER-DUE TO DATE-CCYYMMDD.
018000     PERFORM CONVERT-TO-MMDDCCYY.
018100     MOVE DATE-MMDDCCYY TO PRINT-DUE-DATE.
018200
018300     MOVE VOUCHER-AMOUNT TO PRINT-AMOUNT.
018400     MOVE VOUCHER-INVOICE TO PRINT-INVOICE.
018500
018600     IF VOUCHER-SELECTED = "Y"
018700         MOVE VOUCHER-SELECTED TO PRINT-SELECTED
018800     ELSE
018900         MOVE SPACE TO PRINT-SELECTED.
019000
019100     MOVE DETAIL-LINE TO PRINTER-RECORD.
019200     PERFORM WRITE-TO-PRINTER.
019300
019400 PRINT-LINE-2.
019500     MOVE SPACE TO DETAIL-LINE.
019600     MOVE VOUCHER-FOR TO PRINT-NAME.
019700     MOVE DETAIL-LINE TO PRINTER-RECORD.
019800     PERFORM WRITE-TO-PRINTER.
019900
020000 WRITE-TO-PRINTER.
020100     WRITE PRINTER-RECORD BEFORE ADVANCING 1.
020200     ADD 1 TO LINE-COUNT.
020300
020400 LINE-FEED.
020500     MOVE SPACE TO PRINTER-RECORD.
020600     PERFORM WRITE-TO-PRINTER.
020700
020800 START-NEXT-PAGE.
020900     PERFORM END-LAST-PAGE.
021000     PERFORM START-NEW-PAGE.
021100
021200 START-NEW-PAGE.
021300     ADD 1 TO PAGE-NUMBER.
021400     MOVE PAGE-NUMBER TO PRINT-PAGE-NUMBER.
021500     MOVE TITLE-LINE TO PRINTER-RECORD.
021600     PERFORM WRITE-TO-PRINTER.
021700     PERFORM LINE-FEED.
021800     MOVE COLUMN-LINE TO PRINTER-RECORD.
021900     PERFORM WRITE-TO-PRINTER.
022000     PERFORM LINE-FEED.
022100
022200 END-LAST-PAGE.
022300     PERFORM FORM-FEED.
022400     MOVE ZERO TO LINE-COUNT.
022500
022600 FORM-FEED.
022700     MOVE SPACE TO PRINTER-RECORD.
022800     WRITE PRINTER-RECORD BEFORE ADVANCING PAGE.
022900
023000*--------------------------------
023100* Read first, read next routines
023200*--------------------------------
023300 READ-FIRST-VALID-VOUCHER.
023400     PERFORM READ-NEXT-VALID-VOUCHER.
023500
023600 READ-NEXT-VALID-VOUCHER.
023700     PERFORM READ-NEXT-VOUCHER-RECORD.
023800     PERFORM READ-NEXT-VOUCHER-RECORD
023900         UNTIL VOUCHER-FILE-AT-END = "Y"
024000            OR VOUCHER-PAID-DATE = ZEROES.
024100
024200 READ-NEXT-VOUCHER-RECORD.
024300     MOVE "N" TO VOUCHER-FILE-AT-END.
024400     READ VOUCHER-FILE NEXT RECORD
024500         AT END MOVE "Y" TO VOUCHER-FILE-AT-END.
024600
024700*--------------------------------
024800* Other File IO routines
024900*--------------------------------
025000 READ-VENDOR-RECORD.
025100     MOVE "Y" TO VENDOR-RECORD-FOUND.
025200     READ VENDOR-FILE RECORD
025300         INVALID KEY
025400         MOVE "N" TO VENDOR-RECORD-FOUND.
025500
025600*--------------------------------
025700* Utility Routines
025800*--------------------------------
025900     COPY "PLDATE01.CBL".
026000

The sample report output from bilrpt01.cbl lists vouchers in voucher number order that are not yet paid:

OUTPUT:

                              BILLS REPORT                   PAGE:   1
VOUCHER VENDOR/For                       DUE DATE AMOUNT DUE INVOICE    S
3   CHARLES SMITH AND SONS          2/22/1997      27.76 5057
OFFICE SUPPLIES
4   ABC PRINTING                    2/07/1997     104.19 CX-5055
LETTER HEAD
7   ABC PRINTING                    2/22/1997      48.97 CX-1407
BUSINESS CARDS
8   ABC PRINTING                    1/27/1997      48.97 CX-1566
BUSINESS CARDS
13   MA BELL                         1/23/1997      94.96 50577
PHONE LINE 555-6067
14   AERIAL SIGNS                    1/17/1997   1,046.97 FA1234
SIGN OVER ZUMA BEACH
15   ABERCROMBIE AND OTHERS          1/31/1997     657.19 MONTHLY
RENT
16   CHARLES SMITH AND SONS          1/16/1997      25.97 5098
1997 DAY RUNNER
17   RANIER GRAPHICS                 2/25/1997   4,057.07 ZO-1515
2 PAGE AD LAYOUT WITH RACE CAR
19   MA BELL                         1/23/1997      34.95 50577
PHONE LINE 555-9098

ANALYSIS: The logic to process selected records begins at line 014800 with PROCESS-VOUCHERS. The actual processing loop, PROCESS-THIS-VOUCHER at line 015700, is printing logic to print the record information.

The READ-NEXT-VALID-VOUCHER routine at line 023600 is simpler than the previous examples because all you want are records where VOUCHER-PAID-DATE = ZEROES.

One unusual thing in bilrpt01.cbl is the opening and closing of VOUCHER-FILE at lines 013000 and 013400, rather than in the OPENING-PROCEDURE and CLOSING-PROCEDURE. If this were the final version of the program, the OPEN and CLOSE would have been placed correctly in OPENING-PROCEDURE and CLOSING-PROCEDURE. You are working up to another version of this program, so allow this discrepancy for the moment and it will be explained. This program still works correctly.

Code, compile, and run bilrpt01.cbl. Make sure that it works correctly, and make sure that you understand how it works. You are about to add several things to this program, and if you understand this one fairly well, the additions should not cause any confusion.

Although it is possible simply to write a report of the information in the voucher file, as in bilrpt01.cbl, the report would be more useful if it were organized in order of the dates on which the bills are due. Anyone reading the report would know that bills appearing earlier in the report are the more urgent ones because their due dates are closer.

This presents a problem. The voucher file does not have an alternate key for the due date. Should you go back, redefine the file, add a key, and go through a file conversion? You could, but there is another solution. Alternate keys carry an overhead in a file. They slow down the writing of a new record because the alternate key information has to be updated during the write. They also increase the size of the file on the disk. Whether to create an alternate key or to use a sort on a field (which you learn about in this section) is a part of database and file design, trading off different kinds of costs to produce an efficient compromise.

A file can be sorted on any field or fields in the record by using the COBOL SORT command. The SORT command creates a new file in the process. It is a sequential file that has the same FD as the original file, but it is not keyed. The SORT command requires three files to work correctly:

The SORT command has many options. Here is an example of a common syntax for the SORT command:

SORT sort-file
  ON ASCENDING KEY sort-field
  USING input-file
  GIVING output-file

The following is an example:

SORT SORT-FILE
  ON ASCENDING KEY SORT-DATE
  USING VOUCHER-FILE
  GIVING WORK-FILE.

The KEY in a SORT command is not an indexed key, but simply a way of indicating the field on which the file will be sorted. Because the SORT command uses two extra files, both files must be defined in the ENVIRONMENT DIVISION and the DATA DIVISION. The easiest way to understand this is to look at an example of a sort. Listing 21.7 is bilrpt02.cbl, a modified version of bilrpt01.cbl that includes a sort.

TYPE: Listing 21.7. The bills report sorted in due date order.

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID. BILRPT02.
000300*--------------------------------
000400* Bills report in Due Date order
000500*--------------------------------
000600 ENVIRONMENT DIVISION.
000700 INPUT-OUTPUT SECTION.
000800 FILE-CONTROL.
000900
001000     COPY "SLVOUCH.CBL".
001100
001200     COPY "SLVND02.CBL".
001300
001400     COPY "SLSTATE.CBL".
001500
001600     SELECT WORK-FILE
001700         ASSIGN TO "WORK"
001800         ORGANIZATION IS SEQUENTIAL.
001900
002000     SELECT SORT-FILE
002100         ASSIGN TO "SORT".
002200
002300     SELECT PRINTER-FILE
002400         ASSIGN TO PRINTER
002500         ORGANIZATION IS LINE SEQUENTIAL.
002600
002700 DATA DIVISION.
002800 FILE SECTION.
002900
003000     COPY "FDVOUCH.CBL".
003100
003200     COPY "FDVND04.CBL".
003300
003400     COPY "FDSTATE.CBL".
003500
003600 FD  WORK-FILE
003700     LABEL RECORDS ARE STANDARD.
003800 01  WORK-RECORD.
003900     05  WORK-NUMBER           PIC 9(5).
004000     05  WORK-VENDOR           PIC 9(5).
004100     05  WORK-INVOICE          PIC X(15).
004200     05  WORK-FOR              PIC X(30).
004300     05  WORK-AMOUNT           PIC S9(6)V99.
004400     05  WORK-DATE             PIC 9(8).
004500     05  WORK-DUE              PIC 9(8).
004600     05  WORK-DEDUCTIBLE       PIC X.
004700     05  WORK-SELECTED         PIC X.
004800     05  WORK-PAID-AMOUNT      PIC S9(6)V99.
004900     05  WORK-PAID-DATE        PIC 9(8).
005000     05  WORK-CHECK-NO         PIC 9(6).
005100
005200 SD  SORT-FILE.
005300
005400 01  SORT-RECORD.
005500     05  SORT-NUMBER           PIC 9(5).
005600     05  SORT-VENDOR           PIC 9(5).
005700     05  SORT-INVOICE          PIC X(15).
005800     05  SORT-FOR              PIC X(30).
005900     05  SORT-AMOUNT           PIC S9(6)V99.
006000     05  SORT-DATE             PIC 9(8).
006100     05  SORT-DUE              PIC 9(8).
006200     05  SORT-DEDUCTIBLE       PIC X.
006300     05  SORT-SELECTED         PIC X.
006400     05  SORT-PAID-AMOUNT      PIC S9(6)V99.
006500     05  SORT-PAID-DATE        PIC 9(8).
006600     05  SORT-CHECK-NO         PIC 9(6).
006700
006800 FD  PRINTER-FILE
006900     LABEL RECORDS ARE OMITTED.
007000 01  PRINTER-RECORD             PIC X(80).
007100
007200 WORKING-STORAGE SECTION.
007300
007400 77  OK-TO-PROCESS         PIC X.
007500
007600     COPY "WSCASE01.CBL".
007700
007800 01  DETAIL-LINE.
007900     05  PRINT-NUMBER      PIC ZZZZ9.
008000     05  FILLER            PIC X(3) VALUE SPACE.
008100     05  PRINT-NAME        PIC X(30).
008200     05  FILLER            PIC X(1) VALUE SPACE.
008300     05  PRINT-DUE-DATE    PIC Z9/99/9999.
008400     05  FILLER            PIC X(1) VALUE SPACE.
008500     05  PRINT-AMOUNT      PIC ZZZ,ZZ9.99.
008600     05  FILLER            PIC X(1) VALUE SPACE.
008700     05  PRINT-INVOICE     PIC X(15).
008800     05  FILLER            PIC X(1) VALUE SPACE.
008900     05  PRINT-SELECTED    PIC X(1) VALUE SPACE.
009000
009100 01  TOTAL-THRU.
009200     05  FILLER            PIC X(20) VALUE SPACE.
009300     05  FILLER            PIC X(10) VALUE "TOTAL THRU".
009400
009500 01  COLUMN-LINE.
009600     05  FILLER         PIC X(7)  VALUE "VOUCHER".
009700     05  FILLER         PIC X(1)  VALUE SPACE.
009800     05  FILLER         PIC X(10) VALUE "VENDOR/For".
009900     05  FILLER         PIC X(23) VALUE SPACE.
010000     05  FILLER         PIC X(8)  VALUE "DUE DATE".
010100     05  FILLER         PIC X(1)  VALUE SPACE.
010200     05  FILLER         PIC X(10) VALUE "AMOUNT DUE".
010300     05  FILLER         PIC X(1)  VALUE SPACE.
010400     05  FILLER         PIC X(7)  VALUE "INVOICE".
010500     05  FILLER         PIC X(9)  VALUE SPACE.
010600     05  FILLER         PIC X(1)  VALUE "S".
010700
010800 01  TITLE-LINE.
010900     05  FILLER              PIC X(30) VALUE SPACE.
011000     05  FILLER              PIC X(12)
011100         VALUE "BILLS REPORT".
011200     05  FILLER              PIC X(19) VALUE SPACE.
011300     05  FILLER              PIC X(5) VALUE "PAGE:".
011400     05  FILLER              PIC X(1) VALUE SPACE.
011500     05  PRINT-PAGE-NUMBER   PIC ZZZ9.
011600
011700 77  WORK-FILE-AT-END     PIC X.
011800 77  VENDOR-RECORD-FOUND     PIC X.
011900
012000 77  LINE-COUNT              PIC 999 VALUE ZERO.
012100 77  PAGE-NUMBER             PIC 9999 VALUE ZERO.
012200 77  MAXIMUM-LINES           PIC 999 VALUE 55.
012300
012400 77  RECORD-COUNT            PIC 9999 VALUE ZEROES.
012500
012600     COPY "WSDATE01.CBL".
012700
012800 PROCEDURE DIVISION.
012900 PROGRAM-BEGIN.
013000
013100     PERFORM OPENING-PROCEDURE.
013200     PERFORM MAIN-PROCESS.
013300     PERFORM CLOSING-PROCEDURE.
013400
013500 PROGRAM-EXIT.
013600     EXIT PROGRAM.
013700
013800 PROGRAM-DONE.
013900     STOP RUN.
014000
014100 OPENING-PROCEDURE.
014200     OPEN I-O VENDOR-FILE.
014300
014400     OPEN OUTPUT PRINTER-FILE.
014500
014600 MAIN-PROCESS.
014700     PERFORM GET-OK-TO-PROCESS.
014800     IF OK-TO-PROCESS = "Y"
014900         PERFORM SORT-DATA-FILE
015000         PERFORM PRINT-THE-REPORT.
015100
015200 CLOSING-PROCEDURE.
015300     CLOSE VENDOR-FILE.
015400     PERFORM END-LAST-PAGE.
015500     CLOSE PRINTER-FILE.
015600
015700 GET-OK-TO-PROCESS.
015800     PERFORM ACCEPT-OK-TO-PROCESS.
015900     PERFORM RE-ACCEPT-OK-TO-PROCESS
016000         UNTIL OK-TO-PROCESS = "Y" OR "N".
016100
016200 ACCEPT-OK-TO-PROCESS.
016300     DISPLAY "PRINT BILLS REPORT (Y/N)?".
016400     ACCEPT OK-TO-PROCESS.
016500     INSPECT OK-TO-PROCESS
016600       CONVERTING LOWER-ALPHA
016700       TO         UPPER-ALPHA.
016800
016900 RE-ACCEPT-OK-TO-PROCESS.
017000     DISPLAY "YOU MUST ENTER YES OR NO".
017100     PERFORM ACCEPT-OK-TO-PROCESS.
017200
017300*--------------------------------
017400* Sorting logic
017500*--------------------------------
017600 SORT-DATA-FILE.
017700     SORT SORT-FILE
017800         ON ASCENDING KEY SORT-DUE
017900          USING VOUCHER-FILE
018000          GIVING WORK-FILE.
018100
018200 PRINT-THE-REPORT.
018300     OPEN INPUT WORK-FILE.
018400     PERFORM START-ONE-REPORT.
018500     PERFORM PROCESS-VOUCHERS.
018600     PERFORM END-ONE-REPORT.
018700     CLOSE WORK-FILE.
018800
018900 START-ONE-REPORT.
019000     PERFORM INITIALIZE-REPORT.
019100     PERFORM START-NEW-PAGE.
019200
019300 INITIALIZE-REPORT.
019400     MOVE ZEROES TO LINE-COUNT PAGE-NUMBER.
019500
019600 END-ONE-REPORT.
019700     IF RECORD-COUNT = ZEROES
019800         MOVE "NO RECORDS FOUND" TO PRINTER-RECORD
019900         PERFORM WRITE-TO-PRINTER.
020000
020100 PROCESS-VOUCHERS.
020200     PERFORM READ-FIRST-VALID-WORK.
020300     PERFORM PROCESS-ALL-VOUCHERS
020400         UNTIL WORK-FILE-AT-END = "Y".
020500
020600 PROCESS-ALL-VOUCHERS.
020700     PERFORM PROCESS-THIS-VOUCHER.
020800     PERFORM READ-NEXT-VALID-WORK.
020900
021000 PROCESS-THIS-VOUCHER.
021100     ADD 1 TO RECORD-COUNT.
021200     IF LINE-COUNT > MAXIMUM-LINES
021300         PERFORM START-NEXT-PAGE.
021400     PERFORM PRINT-THE-RECORD.
021500
021600 PRINT-THE-RECORD.
021700     PERFORM PRINT-LINE-1.
021800     PERFORM PRINT-LINE-2.
021900     PERFORM LINE-FEED.
022000
022100 PRINT-LINE-1.
022200     MOVE SPACE TO DETAIL-LINE.
022300     MOVE WORK-NUMBER TO PRINT-NUMBER.
022400
022500     MOVE WORK-VENDOR TO VENDOR-NUMBER.
022600     PERFORM READ-VENDOR-RECORD.
022700     IF VENDOR-RECORD-FOUND = "Y"
022800         MOVE VENDOR-NAME TO PRINT-NAME
022900     ELSE
023000         MOVE "*VENDOR NOT ON FILE*" TO PRINT-NAME.
023100
023200     MOVE WORK-DUE TO DATE-CCYYMMDD.
023300     PERFORM CONVERT-TO-MMDDCCYY.
023400     MOVE DATE-MMDDCCYY TO PRINT-DUE-DATE.
023500
023600     MOVE WORK-AMOUNT TO PRINT-AMOUNT.
023700     MOVE WORK-INVOICE TO PRINT-INVOICE.
023800
023900     IF WORK-SELECTED = "Y"
024000         MOVE WORK-SELECTED TO PRINT-SELECTED
024100     ELSE
024200         MOVE SPACE TO PRINT-SELECTED.
024300
024400     MOVE DETAIL-LINE TO PRINTER-RECORD.
024500     PERFORM WRITE-TO-PRINTER.
024600
024700 PRINT-LINE-2.
024800     MOVE SPACE TO DETAIL-LINE.
024900     MOVE WORK-FOR TO PRINT-NAME.
025000     MOVE DETAIL-LINE TO PRINTER-RECORD.
025100     PERFORM WRITE-TO-PRINTER.
025200
025300 WRITE-TO-PRINTER.
025400     WRITE PRINTER-RECORD BEFORE ADVANCING 1.
025500     ADD 1 TO LINE-COUNT.
025600
025700 LINE-FEED.
025800     MOVE SPACE TO PRINTER-RECORD.
025900     PERFORM WRITE-TO-PRINTER.
026000
026100 START-NEXT-PAGE.
026200     PERFORM END-LAST-PAGE.
026300     PERFORM START-NEW-PAGE.
026400
026500 START-NEW-PAGE.
026600     ADD 1 TO PAGE-NUMBER.
026700     MOVE PAGE-NUMBER TO PRINT-PAGE-NUMBER.
026800     MOVE TITLE-LINE TO PRINTER-RECORD.
026900     PERFORM WRITE-TO-PRINTER.
027000     PERFORM LINE-FEED.
027100     MOVE COLUMN-LINE TO PRINTER-RECORD.
027200     PERFORM WRITE-TO-PRINTER.
027300     PERFORM LINE-FEED.
027400
027500 END-LAST-PAGE.
027600     PERFORM FORM-FEED.
027700     MOVE ZERO TO LINE-COUNT.
027800
027900 FORM-FEED.
028000     MOVE SPACE TO PRINTER-RECORD.
028100     WRITE PRINTER-RECORD BEFORE ADVANCING PAGE.
028200
028300*--------------------------------
028400* Read first, read next routines
028500*--------------------------------
028600 READ-FIRST-VALID-WORK.
028700     PERFORM READ-NEXT-VALID-WORK.
028800
028900 READ-NEXT-VALID-WORK.
029000     PERFORM READ-NEXT-WORK-RECORD.
029100     PERFORM READ-NEXT-WORK-RECORD
029200         UNTIL WORK-FILE-AT-END = "Y"
029300            OR WORK-PAID-DATE = ZEROES.
029400
029500 READ-NEXT-WORK-RECORD.
029600     MOVE "N" TO WORK-FILE-AT-END.
029700     READ WORK-FILE NEXT RECORD
029800         AT END MOVE "Y" TO WORK-FILE-AT-END.
029900
030000*--------------------------------
030100* Other File IO routines
030200*--------------------------------
030300 READ-VENDOR-RECORD.
030400     MOVE "Y" TO VENDOR-RECORD-FOUND.
030500     READ VENDOR-FILE RECORD
030600         INVALID KEY
030700         MOVE "N" TO VENDOR-RECORD-FOUND.
030800
030900*--------------------------------
031000* Utility Routines
031100*--------------------------------
031200     COPY "PLDATE01.CBL".
031300

The output of bilrpt02.cbl is sorted in due-date order, improving the usefulness of the report:

OUTPUT:

                                  BILLS REPORT                   PAGE: 1
VOUCHER VENDOR/For                       DUE DATE AMOUNT DUE INVOICE    S
16   CHARLES SMITH AND SONS          1/16/1997      25.97 5098
1997 DAY RUNNER
14   AERIAL SIGNS                    1/17/1997   1,046.97 FA1234
SIGN OVER ZUMA BEACH
13   MA BELL                         1/23/1997      94.96 50577
PHONE LINE 555-6067
19   MA BELL                         1/23/1997      34.95 50577
PHONE LINE 555-9098
8   ABC PRINTING                    1/27/1997      48.97 CX-1566       Y
BUSINESS CARDS
15   ABERCROMBIE AND OTHERS          1/31/1997     657.19 MONTHLY
RENT
4   ABC PRINTING                    2/07/1997     104.19 CX-5055       Y
LETTER HEAD
3   CHARLES SMITH AND SONS          2/22/1997      27.76 5057
OFFICE SUPPLIES
7   ABC PRINTING                    2/22/1997      48.97 CX-1407
BUSINESS CARDS
17   RANIER GRAPHICS                 2/25/1997   4,057.07 ZO-1515
2 PAGE AD LAYOUT WITH RACE CAR

ANALYSIS: This program is identical to bilrpt01.cbl except that the voucher file is sorted into a work file, and the report is printed using the data in the work file rather than directly from the voucher file.

The FILE-CONTROL paragraph of the INPUT-OUTPUT SECTION in the ENVIRONMENT DIVISION contains SELECT clauses for two new files. WORK-FILE at line 001600 will be used as the output of the sort, and SORT-FILE at line 002000 will be used as a temporary file by the SORT command. Note that the organization of the WORK-FILE is SEQUENTIAL because it will have no key. No organization is specified for the SORT-FILE.

The organization of a sort file is omitted, because it is a special type of file used by the SORT command. The actual organization of the file probably is nothing like any of the standard COBOL file organizations. It is set up by your version of COBOL to produce the fastest possible sorting of another file.

In the FILE SECTION of the DATA DIVISION, the FD for the WORK-FILE is defined at lines 003600 through 005000. It is an exact duplicate of the VOUCHER-FILE, but it uses the prefix WORK- for all fields. This work version of the voucher file will have exactly the same record layout as the voucher file, but it will be a SEQUENTIAL file, not an INDEXED file.

The FD for the SORT-FILE begins at line 005200. Notice that it is not given a level number of FD but is called an SD (sort descriptor). This again highlights the special nature of a sort file. The SD serves to set the file apart from others as a special file that will be used only by the SORT command. It cannot be used as a standard file. Aside from the SD, the remainder of the sort file is identical to the VOUCHER-FILE, but all fields use the prefix SORT-.

The actual sort is done at lines 017600 through 018000 in the SORT-DATA-FILE paragraph. You can think of the SORT command as a series of steps:

1. Copy the voucher file to the sort file.

2. Sort the sort file on the SORT-DUE field.

3. Copy the resulting sorted file to the work file.

This version of the SORT command automatically opens the input file (VOUCHER-FILE) and the output file (WORK-FILE) before the sort and closes them when the sort is done. The SORT command fails if you have opened either of these files in your program already. If you do need to open a file that is used in a sort for any reason, it must be closed again before the SORT command is used. There is no OPEN or CLOSE of VOUCHER-FILE or WORK-FILE in OPENING-PROCEDURE or CLOSING-PROCEDURE.

The work file cannot be opened until after the sort is completed, but it must be opened for the report. The opening and closing of the WORK-FILE is performed at lines 018300 and 018700, respectively--which are the top and bottom of the PRINT-THE-REPORT paragraph--just as the VOUCHER-FILE is handled in bilrpt01.cbl.

To execute the sort, it is inserted into MAIN-PROCESS after the user has said yes to go ahead with the report, but before performing PRINT-THE-REPORT (at line 014900).

From PRINT-THE-REPORT at line 018200 to the end of the program, the processing is identical to bilrpt01.cbl except for one point. The bilrpt01.cbl program prints out the voucher file and bilrpt02.cbl is printing out the work file, so all fields have been changed to WORK-. Values now are moved from the work file to the print record.

Code, compile, and run bilrpt02.cbl; you should get a report with the same information, but sorted in due-date order.

Printing Totals

The bilrpt02.cbl program still leaves the user the task of totaling the dollars and working out the total due day by day, and it seems that the computer should be able to do the mathematics.

Figure 21.3 is a modified layout for the bills report program that provides a running total at the end of each day.

The problem is to print the same report but to keep a running total of the amount owed as each voucher is processed, with a running total printed at the end of each due date.

New Term: The interruption of the usual printing of a report program to print a total or subtotal is called a control break or level break. In the following example, the report breaks at the end of each vendor, prints a subtotal for that vendor, and then breaks at the end of the report and prints a total for the report. These are control breaks:

Vendor            DUE DATE      AMOUNT
ABC Printing     1/23/1997       27.95
ABC Printing     1/31/1997       15.54
ABC Printing     2/16/1997       10.17
Total       53.66
GTE              1/17/1997       34.97
GTE              1/24/1997       17.54
Total       52.51
Grand Total      106.17

Programming Control Breaks

A control break in a program usually is programmed by setting up the program so that it prints until the value in one of the fields changes. In the previous example, the report prints until the vendor name changes and then prints a total. In the problem you are dealing with, the report prints until the due date changes. When the field changes, a subtotal or running total is printed.

In all control breaking, the data file is sorted on the field that will be used for controlling the break. In the case of bilrpt03.cbl in Listing 21.8, the control field will be WORK-DUE and the file already is sorted on this field.

Listing 21.8. Sorted bills report with totals.

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID. BILRPT03.
000300*--------------------------------
000400* Bills Report with totals by day.
000500*--------------------------------
000600 ENVIRONMENT DIVISION.
000700 INPUT-OUTPUT SECTION.
000800 FILE-CONTROL.
000900
001000     COPY "SLVOUCH.CBL".
001100
001200     COPY "SLVND02.CBL".
001300
001400     COPY "SLSTATE.CBL".
001500
001600     SELECT WORK-FILE
001700         ASSIGN TO "WORK"
001800         ORGANIZATION IS SEQUENTIAL.
001900
002000     SELECT SORT-FILE
002100         ASSIGN TO "SORT".
002200
002300     SELECT PRINTER-FILE
002400         ASSIGN TO PRINTER
002500         ORGANIZATION IS LINE SEQUENTIAL.
002600
002700 DATA DIVISION.
002800 FILE SECTION.
002900
003000     COPY "FDVOUCH.CBL".
003100
003200     COPY "FDVND04.CBL".
003300
003400     COPY "FDSTATE.CBL".
003500
003600 FD  WORK-FILE
003700     LABEL RECORDS ARE STANDARD.
003800 01  WORK-RECORD.
003900     05  WORK-NUMBER           PIC 9(5).
004000     05  WORK-VENDOR           PIC 9(5).
004100     05  WORK-INVOICE          PIC X(15).
004200     05  WORK-FOR              PIC X(30).
004300     05  WORK-AMOUNT           PIC S9(6)V99.
004400     05  WORK-DATE             PIC 9(8).
004500     05  WORK-DUE              PIC 9(8).
004600     05  WORK-DEDUCTIBLE       PIC X.
004700     05  WORK-SELECTED         PIC X.
004800     05  WORK-PAID-AMOUNT      PIC S9(6)V99.
004900     05  WORK-PAID-DATE        PIC 9(8).
005000     05  WORK-CHECK-NO         PIC 9(6).
005100
005200 SD  SORT-FILE.
005300
005400 01  SORT-RECORD.
005500     05  SORT-NUMBER           PIC 9(5).
005600     05  SORT-VENDOR           PIC 9(5).
005700     05  SORT-INVOICE          PIC X(15).
005800     05  SORT-FOR              PIC X(30).
005900     05  SORT-AMOUNT           PIC S9(6)V99.
006000     05  SORT-DATE             PIC 9(8).
006100     05  SORT-DUE              PIC 9(8).
006200     05  SORT-DEDUCTIBLE       PIC X.
006300     05  SORT-SELECTED         PIC X.
006400     05  SORT-PAID-AMOUNT      PIC S9(6)V99.
006500     05  SORT-PAID-DATE        PIC 9(8).
006600     05  SORT-CHECK-NO         PIC 9(6).
006700
006800 FD  PRINTER-FILE
006900     LABEL RECORDS ARE OMITTED.
007000 01  PRINTER-RECORD             PIC X(80).
007100
007200 WORKING-STORAGE SECTION.
007300
007400 77  OK-TO-PROCESS         PIC X.
007500
007600     COPY "WSCASE01.CBL".
007700
007800 01  DETAIL-LINE.
007900     05  PRINT-NUMBER      PIC ZZZZ9.
008000     05  FILLER            PIC X(3) VALUE SPACE.
008100     05  PRINT-NAME        PIC X(30).
008200     05  FILLER            PIC X(1) VALUE SPACE.
008300     05  PRINT-DUE-DATE   PIC Z9/99/9999.
008400     05  FILLER            PIC X(1) VALUE SPACE.
008500     05  PRINT-AMOUNT      PIC ZZZ,ZZ9.99.
008600     05  FILLER            PIC X(1) VALUE SPACE.
008700     05  PRINT-INVOICE     PIC X(15).
008800     05  FILLER            PIC X(1) VALUE SPACE.
008900     05  PRINT-SELECTED    PIC X(1) VALUE SPACE.
009000
009100 01  TOTAL-THRU.
009200     05  FILLER            PIC X(20) VALUE SPACE.
009300     05  FILLER            PIC X(10) VALUE "TOTAL THRU".
009400
009500 01  COLUMN-LINE.
009600     05  FILLER         PIC X(7)  VALUE "VOUCHER".
009700     05  FILLER         PIC X(1)  VALUE SPACE.
009800     05  FILLER         PIC X(10) VALUE "VENDOR/For".
009900     05  FILLER         PIC X(23) VALUE SPACE.
010000     05  FILLER         PIC X(8)  VALUE "DUE DATE".
010100     05  FILLER         PIC X(1)  VALUE SPACE.
010200     05  FILLER         PIC X(10) VALUE "AMOUNT DUE".
010300     05  FILLER         PIC X(1)  VALUE SPACE.
010400     05  FILLER         PIC X(7)  VALUE "INVOICE".
010500     05  FILLER         PIC X(9)  VALUE SPACE.
010600     05  FILLER         PIC X(1)  VALUE "S".
010700
010800 01  TITLE-LINE.
010900     05  FILLER              PIC X(30) VALUE SPACE.
011000     05  FILLER              PIC X(12)
011100         VALUE "BILLS REPORT".
011200     05  FILLER              PIC X(19) VALUE SPACE.
011300     05  FILLER              PIC X(5) VALUE "PAGE:".
011400     05  FILLER              PIC X(1) VALUE SPACE.
011500     05  PRINT-PAGE-NUMBER   PIC ZZZ9.
011600
011700 77  WORK-FILE-AT-END     PIC X.
011800 77  VENDOR-RECORD-FOUND     PIC X.
011900
012000 77  LINE-COUNT              PIC 999 VALUE ZERO.
012100 77  PAGE-NUMBER             PIC 9999 VALUE ZERO.
012200 77  MAXIMUM-LINES           PIC 999 VALUE 55.
012300
012400 77  RECORD-COUNT            PIC 9999 VALUE ZEROES.
012500
012600 77  SAVE-DUE                PIC 9(8).
012700
012800 77  RUNNING-TOTAL           PIC S9(6)V99.
012900
013000     COPY "WSDATE01.CBL".
013100
013200 PROCEDURE DIVISION.
013300 PROGRAM-BEGIN.
013400
013500     PERFORM OPENING-PROCEDURE.
013600     PERFORM MAIN-PROCESS.
013700     PERFORM CLOSING-PROCEDURE.
013800
013900 PROGRAM-EXIT.
014000     EXIT PROGRAM.
014100
014200 PROGRAM-DONE.
014300     STOP RUN.
014400
014500 OPENING-PROCEDURE.
014600     OPEN I-O VENDOR-FILE.
014700
014800     OPEN OUTPUT PRINTER-FILE.
014900
015000 MAIN-PROCESS.
015100     PERFORM GET-OK-TO-PROCESS.
015200     IF OK-TO-PROCESS = "Y"
015300         PERFORM SORT-DATA-FILE
015400         PERFORM PRINT-THE-REPORT.
015500
015600 CLOSING-PROCEDURE.
015700     CLOSE VENDOR-FILE.
015800     PERFORM END-LAST-PAGE.
015900     CLOSE PRINTER-FILE.
016000
016100 GET-OK-TO-PROCESS.
016200     PERFORM ACCEPT-OK-TO-PROCESS.
016300     PERFORM RE-ACCEPT-OK-TO-PROCESS
016400         UNTIL OK-TO-PROCESS = "Y" OR "N".
016500
016600 ACCEPT-OK-TO-PROCESS.
016700     DISPLAY "PRINT BILLS REPORT (Y/N)?".
016800     ACCEPT OK-TO-PROCESS.
016900     INSPECT OK-TO-PROCESS
017000       CONVERTING LOWER-ALPHA
017100       TO         UPPER-ALPHA.
017200
017300 RE-ACCEPT-OK-TO-PROCESS.
017400     DISPLAY "YOU MUST ENTER YES OR NO".
017500     PERFORM ACCEPT-OK-TO-PROCESS.
017600
017700*--------------------------------
017800* Sorting logic
017900*--------------------------------
018000 SORT-DATA-FILE.
018100     SORT SORT-FILE
018200         ON ASCENDING KEY SORT-DUE
018300          USING VOUCHER-FILE
018400          GIVING WORK-FILE.
018500
018600 PRINT-THE-REPORT.
018700     OPEN INPUT WORK-FILE.
018800     PERFORM START-ONE-REPORT.
018900     PERFORM PROCESS-VOUCHERS.
019000     PERFORM END-ONE-REPORT.
019100     CLOSE WORK-FILE.
019200
019300 START-ONE-REPORT.
019400     PERFORM INITIALIZE-REPORT.
019500     PERFORM START-NEW-PAGE.
019600     MOVE ZEROES TO RUNNING-TOTAL.
019700
019800 INITIALIZE-REPORT.
019900     MOVE ZEROES TO LINE-COUNT PAGE-NUMBER.
020000
020100 END-ONE-REPORT.
020200     IF RECORD-COUNT = ZEROES
020300         MOVE "NO RECORDS FOUND" TO PRINTER-RECORD
020400         PERFORM WRITE-TO-PRINTER.
020500
020600 PROCESS-VOUCHERS.
020700     PERFORM READ-FIRST-VALID-WORK.
020800     PERFORM PROCESS-ALL-DATES
020900         UNTIL WORK-FILE-AT-END = "Y".
021000
021100 PROCESS-ALL-DATES.
021200     PERFORM START-ONE-DATE.
021300
021400     PERFORM PROCESS-ALL-VOUCHERS
021500         UNTIL WORK-FILE-AT-END = "Y"
021600            OR WORK-DUE NOT = SAVE-DUE.
021700
021800     PERFORM END-ONE-DATE.
021900
022000 START-ONE-DATE.
022100     MOVE WORK-DUE TO SAVE-DUE.
022200
022300 END-ONE-DATE.
022400     PERFORM PRINT-RUNNING-TOTAL.
022500
022600 PRINT-RUNNING-TOTAL.
022700     MOVE SPACE TO DETAIL-LINE.
022800     MOVE SAVE-DUE TO DATE-CCYYMMDD.
022900     PERFORM CONVERT-TO-MMDDCCYY.
023000     MOVE DATE-MMDDCCYY TO PRINT-DUE-DATE.
023100     MOVE RUNNING-TOTAL TO PRINT-AMOUNT.
023200     MOVE TOTAL-THRU TO PRINT-NAME.
023300     MOVE DETAIL-LINE TO PRINTER-RECORD.
023400     PERFORM WRITE-TO-PRINTER.
023500     PERFORM LINE-FEED 2 TIMES.
023600
023700 PROCESS-ALL-VOUCHERS.
023800     PERFORM PROCESS-THIS-VOUCHER.
023900     PERFORM READ-NEXT-VALID-WORK.
024000
024100 PROCESS-THIS-VOUCHER.
024200     ADD 1 TO RECORD-COUNT.
024300     IF LINE-COUNT > MAXIMUM-LINES
024400         PERFORM START-NEXT-PAGE.
024500     PERFORM PRINT-THE-RECORD.
024600     ADD WORK-AMOUNT TO RUNNING-TOTAL.
024700
024800 PRINT-THE-RECORD.
024900     PERFORM PRINT-LINE-1.
025000     PERFORM PRINT-LINE-2.
025100     PERFORM LINE-FEED.
025200
025300 PRINT-LINE-1.
025400     MOVE SPACE TO DETAIL-LINE.
025500     MOVE WORK-NUMBER TO PRINT-NUMBER.
025600
025700     MOVE WORK-VENDOR TO VENDOR-NUMBER.
025800     PERFORM READ-VENDOR-RECORD.
025900     IF VENDOR-RECORD-FOUND = "Y"
026000         MOVE VENDOR-NAME TO PRINT-NAME
026100     ELSE
026200         MOVE "*VENDOR NOT ON FILE*" TO PRINT-NAME.
026300
026400     MOVE WORK-DUE TO DATE-CCYYMMDD.
026500     PERFORM CONVERT-TO-MMDDCCYY.
026600     MOVE DATE-MMDDCCYY TO PRINT-DUE-DATE.
026700
026800     MOVE WORK-AMOUNT TO PRINT-AMOUNT.
026900     MOVE WORK-INVOICE TO PRINT-INVOICE.
027000
027100     IF WORK-SELECTED = "Y"
027200         MOVE WORK-SELECTED TO PRINT-SELECTED
027300     ELSE
027400         MOVE SPACE TO PRINT-SELECTED.
027500
027600     MOVE DETAIL-LINE TO PRINTER-RECORD.
027700     PERFORM WRITE-TO-PRINTER.
027800
027900 PRINT-LINE-2.
028000     MOVE SPACE TO DETAIL-LINE.
028100     MOVE WORK-FOR TO PRINT-NAME.
028200     MOVE DETAIL-LINE TO PRINTER-RECORD.
028300     PERFORM WRITE-TO-PRINTER.
028400
028500 WRITE-TO-PRINTER.
028600     WRITE PRINTER-RECORD BEFORE ADVANCING 1.
028700     ADD 1 TO LINE-COUNT.
028800
028900 LINE-FEED.
029000     MOVE SPACE TO PRINTER-RECORD.
029100     PERFORM WRITE-TO-PRINTER.
029200
029300 START-NEXT-PAGE.
029400     PERFORM END-LAST-PAGE.
029500     PERFORM START-NEW-PAGE.
029600
029700 START-NEW-PAGE.
029800     ADD 1 TO PAGE-NUMBER.
029900     MOVE PAGE-NUMBER TO PRINT-PAGE-NUMBER.
030000     MOVE TITLE-LINE TO PRINTER-RECORD.
030100     PERFORM WRITE-TO-PRINTER.
030200     PERFORM LINE-FEED.
030300     MOVE COLUMN-LINE TO PRINTER-RECORD.
030400     PERFORM WRITE-TO-PRINTER.
030500     PERFORM LINE-FEED.
030600
030700 END-LAST-PAGE.
030800     PERFORM FORM-FEED.
030900     MOVE ZERO TO LINE-COUNT.
031000
031100 FORM-FEED.
031200     MOVE SPACE TO PRINTER-RECORD.
031300     WRITE PRINTER-RECORD BEFORE ADVANCING PAGE.
031400
031500*--------------------------------
031600* Read first, read next routines
031700*--------------------------------
031800 READ-FIRST-VALID-WORK.
031900     PERFORM READ-NEXT-VALID-WORK.
032000
032100 READ-NEXT-VALID-WORK.
032200     PERFORM READ-NEXT-WORK-RECORD.
032300     PERFORM READ-NEXT-WORK-RECORD
032400         UNTIL WORK-FILE-AT-END = "Y"
032500            OR WORK-PAID-DATE = ZEROES.
032600
032700 READ-NEXT-WORK-RECORD.
032800     MOVE "N" TO WORK-FILE-AT-END.
032900     READ WORK-FILE NEXT RECORD
033000         AT END MOVE "Y" TO WORK-FILE-AT-END.
033100
033200*--------------------------------
033300* Other File IO routines
033400*--------------------------------
033500 READ-VENDOR-RECORD.
033600     MOVE "Y" TO VENDOR-RECORD-FOUND.
033700     READ VENDOR-FILE RECORD
033800         INVALID KEY
033900         MOVE "N" TO VENDOR-RECORD-FOUND.
034000
034100*--------------------------------
034200* Utility Routines
034300*--------------------------------
034400     COPY "PLDATE01.CBL".
034500

The output of bilrpt03.cbl includes running totals for each day:

OUTPUT:

                              BILLS REPORT                   PAGE:    1
VOUCHER VENDOR/For                       DUE DATE AMOUNT DUE INVOICE    S
16   CHARLES SMITH AND SONS          1/16/1997      25.97 5098
1997 DAY RUNNER
TOTAL THRU  1/16/1997      25.97
14   AERIAL SIGNS                    1/17/1997   1,046.97 FA1234
SIGN OVER ZUMA BEACH
TOTAL THRU  1/17/1997   1,072.94
13   MA BELL                         1/23/1997      94.96 50577
PHONE LINE 555-6067
19   MA BELL                         1/23/1997      34.95 50577
PHONE LINE 555-9098
TOTAL THRU  1/23/1997   1,202.85
8   ABC PRINTING                    1/27/1997      48.97 CX-1566        Y
BUSINESS CARDS
TOTAL THRU  1/27/1997   1,251.82
15   ABERCROMBIE AND OTHERS          1/31/1997     657.19 MONTHLY
RENT
TOTAL THRU  1/31/1997   1,909.01
4   ABC PRINTING                    2/07/1997     104.19 CX-5055        Y
LETTER HEAD
TOTAL THRU  2/07/1997   2,013.20
3   CHARLES SMITH AND SONS          2/22/1997      27.76 5057
OFFICE SUPPLIES
7   ABC PRINTING                    2/22/1997      48.97 CX-1407
BUSINESS CARDS
TOTAL THRU  2/22/1997   2,089.93
17   RANIER GRAPHICS                 2/25/1997   4,057.07 ZO-1515
2 PAGE AD LAYOUT WITH RACE CAR
TOTAL THRU  2/25/1997   6,147.00

ANALYSIS: In Listing 21.8, a totaling field has been added to keep a running total of the amount owed. RUNNING-TOTAL is defined at line 012800. This is kept up to date inside the PROCESS-THIS-VOUCHER processing loop at line 024600, where WORK-AMOUNT is added to RUNNING-TOTAL. At line 012600, SAVE-DUE is defined. This field will be used to save the values in the due-date field so that it is possible to tell whether it has changed from one record to the next.

The original PROCESS-ALL-VOUCHERS routine is a processing loop that processes all voucher records. You need a higher-level loop that processes the group of all records that have the same due date. The control break logic PROCESS-ALL-DATES is inserted as a level between PRINT-THE-REPORT and PROCESS-ALL-VOUCHERS at line 021100.

Rather than performing PROCESS-ALL-VOUCHERS, PRINT-THE-REPORT performs PROCESS-ALL-DATES. PROCESS-ALL-DATES in turn performs PROCESS-ALL-VOUCHERS.

PROCESS-ALL-DATES is the clue to the control break. It starts by performing START-ONE-DATE. This is a routine at line 022000 that saves WORK-DUE in SAVE-DUE. After this is saved, it is possible at line 021400 to perform PROCESS-ALL-VOUCHERS until WORK-FILE-AT-END = "Y" or WORK-DUE NOT = SAVE-DUE.

This PERFORM causes the primary logic of the program to print individual records from the voucher file until a read on the work file pulls up a voucher record with a different due date.

After this break happens at line 021800, END-ONE-DATE is performed. END-ONE-DATE at line 022300 in turn performs PRINT-RUNNING-TOTAL. This routine at line 022600 prints the running total so far for this date by printing the SAVE-DATE and the RUNNING-TOTAL, along with a total message.

At this point, PROCESS-ALL-DATES ends and the logic returns to lines 020800 and 020900. If WORK-FILE-AT-END = "Y" the whole loop ends, but if it is only a change of date, PROCESS-ALL-DATES is performed again. This continues until WORK-FILE-AT-END = "Y".

The remainder of the program is identical to bilrpt02.cbl.

Code, compile, and run bilrpt03.cbl to see a report like the one given in the sample output. This report helps a user determine what date line to use as the cutoff date for selecting records using vchsel01.cbl.

Several different methods can be used to organize a control breaking report. Listing 21.8, bilrpt02.cbl, illustrates one flexible method that I like.

The Cash Requirements Report

The cash requirements report is the final program that you need in order to complete the bills payment system shown in Figure 21.1. It is step 8 of the bills payment system.

The cash requirements report in Listing 21.9 is not much different from bilrpt03.cbl. It prints only vouchers that are selected, so the "S" column has been removed from the report.

TYPE: Listing 21.9. The cash requirements report.

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID. CSHREQ01.
000300*--------------------------------
000400* Cash Requirements Report
000500*--------------------------------
000600 ENVIRONMENT DIVISION.
000700 INPUT-OUTPUT SECTION.
000800 FILE-CONTROL.
000900
001000     COPY "SLVOUCH.CBL".
001100
001200     COPY "SLVND02.CBL".
001300
001400     COPY "SLSTATE.CBL".
001500
001600     SELECT WORK-FILE
001700         ASSIGN TO "WORK"
001800         ORGANIZATION IS SEQUENTIAL.
001900
002000     SELECT SORT-FILE
002100         ASSIGN TO "SORT".
002200
002300     SELECT PRINTER-FILE
002400         ASSIGN TO PRINTER
002500         ORGANIZATION IS LINE SEQUENTIAL.
002600
002700 DATA DIVISION.
002800 FILE SECTION.
002900
003000     COPY "FDVOUCH.CBL".
003100
003200     COPY "FDVND04.CBL".
003300
003400     COPY "FDSTATE.CBL".
003500
003600 FD  WORK-FILE
003700     LABEL RECORDS ARE STANDARD.
003800 01  WORK-RECORD.
003900     05  WORK-NUMBER           PIC 9(5).
004000     05  WORK-VENDOR           PIC 9(5).
004100     05  WORK-INVOICE          PIC X(15).
004200     05  WORK-FOR              PIC X(30).
004300     05  WORK-AMOUNT           PIC S9(6)V99.
004400     05  WORK-DATE             PIC 9(8).
004500     05  WORK-DUE              PIC 9(8).
004600     05  WORK-DEDUCTIBLE       PIC X.
004700     05  WORK-SELECTED         PIC X.
004800     05  WORK-PAID-AMOUNT      PIC S9(6)V99.
004900     05  WORK-PAID-DATE        PIC 9(8).
005000     05  WORK-CHECK-NO         PIC 9(6).
005100
005200 SD  SORT-FILE.
005300
005400 01  SORT-RECORD.
005500     05  SORT-NUMBER           PIC 9(5).
005600     05  SORT-VENDOR           PIC 9(5).
005700     05  SORT-INVOICE          PIC X(15).
005800     05  SORT-FOR              PIC X(30).
005900     05  SORT-AMOUNT           PIC S9(6)V99.
006000     05  SORT-DATE             PIC 9(8).
006100     05  SORT-DUE              PIC 9(8).
006200     05  SORT-DEDUCTIBLE       PIC X.
006300     05  SORT-SELECTED         PIC X.
006400     05  SORT-PAID-AMOUNT      PIC S9(6)V99.
006500     05  SORT-PAID-DATE        PIC 9(8).
006600     05  SORT-CHECK-NO         PIC 9(6).
006700
006800 FD  PRINTER-FILE
006900     LABEL RECORDS ARE OMITTED.
007000 01  PRINTER-RECORD             PIC X(80).
007100
007200 WORKING-STORAGE SECTION.
007300
007400 77  OK-TO-PROCESS         PIC X.
007500
007600     COPY "WSCASE01.CBL".
007700
007800 01  DETAIL-LINE.
007900     05  PRINT-NUMBER      PIC ZZZZ9.
008000     05  FILLER            PIC X(3) VALUE SPACE.
008100     05  PRINT-NAME        PIC X(30).
008200     05  FILLER            PIC X(1) VALUE SPACE.
008300     05  PRINT-DUE-DATE   PIC Z9/99/9999.
008400     05  FILLER            PIC X(1) VALUE SPACE.
008500     05  PRINT-AMOUNT      PIC ZZZ,ZZ9.99.
008600     05  FILLER            PIC X(1) VALUE SPACE.
008700     05  PRINT-INVOICE     PIC X(15).
008800
008900 01  TOTAL-THRU.
009000     05  FILLER            PIC X(20) VALUE SPACE.
009100     05  FILLER            PIC X(10) VALUE "TOTAL THRU".
009200
009300 01  COLUMN-LINE.
009400     05  FILLER         PIC X(7)  VALUE "VOUCHER".
009500     05  FILLER         PIC X(1)  VALUE SPACE.
009600     05  FILLER         PIC X(10) VALUE "VENDOR/For".
009700     05  FILLER         PIC X(23) VALUE SPACE.
009800     05  FILLER         PIC X(8)  VALUE "DUE DATE".
009900     05  FILLER         PIC X(1)  VALUE SPACE.
010000     05  FILLER         PIC X(10) VALUE "AMOUNT DUE".
010100     05  FILLER         PIC X(1)  VALUE SPACE.
010200     05  FILLER         PIC X(7)  VALUE "INVOICE".
010300
010400 01  TITLE-LINE.
010500     05  FILLER              PIC X(28) VALUE SPACE.
010600     05  FILLER              PIC X(17)
010700         VALUE "CASH REQUIREMENTS".
010800     05  FILLER              PIC X(16) VALUE SPACE.
010900     05  FILLER              PIC X(5) VALUE "PAGE:".
011000     05  FILLER              PIC X(1) VALUE SPACE.
011100     05  PRINT-PAGE-NUMBER   PIC ZZZ9.
011200
011300 77  WORK-FILE-AT-END     PIC X.
011400 77  VENDOR-RECORD-FOUND     PIC X.
011500
011600 77  LINE-COUNT              PIC 999 VALUE ZERO.
011700 77  PAGE-NUMBER             PIC 9999 VALUE ZERO.
011800 77  MAXIMUM-LINES           PIC 999 VALUE 55.
011900
012000 77  RECORD-COUNT            PIC 9999 VALUE ZEROES.
012100
012200 77  SAVE-DUE                PIC 9(8).
012300
012400 77  RUNNING-TOTAL           PIC S9(6)V99.
012500
012600     COPY "WSDATE01.CBL".
012700
012800 PROCEDURE DIVISION.
012900 PROGRAM-BEGIN.
013000
013100     PERFORM OPENING-PROCEDURE.
013200     PERFORM MAIN-PROCESS.
013300     PERFORM CLOSING-PROCEDURE.
013400
013500 PROGRAM-EXIT.
013600     EXIT PROGRAM.
013700
013800 PROGRAM-DONE.
013900     STOP RUN.
014000
014100 OPENING-PROCEDURE.
014200     OPEN I-O VENDOR-FILE.
014300
014400     OPEN OUTPUT PRINTER-FILE.
014500
014600 MAIN-PROCESS.
014700     PERFORM GET-OK-TO-PROCESS.
014800     IF OK-TO-PROCESS = "Y"
014900         PERFORM SORT-DATA-FILE
015000         PERFORM PRINT-THE-REPORT.
015100
015200 CLOSING-PROCEDURE.
015300     CLOSE VENDOR-FILE.
015400     PERFORM END-LAST-PAGE.
015500     CLOSE PRINTER-FILE.
015600
015700 GET-OK-TO-PROCESS.
015800     PERFORM ACCEPT-OK-TO-PROCESS.
015900     PERFORM RE-ACCEPT-OK-TO-PROCESS
016000         UNTIL OK-TO-PROCESS = "Y" OR "N".
016100
016200 ACCEPT-OK-TO-PROCESS.
016300     DISPLAY "PRINT CASH REQUIREMENTS REPORT (Y/N)?".
016400     ACCEPT OK-TO-PROCESS.
016500     INSPECT OK-TO-PROCESS
016600       CONVERTING LOWER-ALPHA
016700       TO         UPPER-ALPHA.
016800
016900 RE-ACCEPT-OK-TO-PROCESS.
017000     DISPLAY "YOU MUST ENTER YES OR NO".
017100     PERFORM ACCEPT-OK-TO-PROCESS.
017200
017300*--------------------------------
017400* Sorting logic
017500*--------------------------------
017600 SORT-DATA-FILE.
017700     SORT SORT-FILE
017800         ON ASCENDING KEY SORT-DUE
017900          USING VOUCHER-FILE
018000          GIVING WORK-FILE.
018100
018200 PRINT-THE-REPORT.
018300     OPEN INPUT WORK-FILE.
018400     PERFORM START-ONE-REPORT.
018500     PERFORM PROCESS-VOUCHERS.
018600     PERFORM END-ONE-REPORT.
018700     CLOSE WORK-FILE.
018800
018900 START-ONE-REPORT.
019000     PERFORM INITIALIZE-REPORT.
019100     PERFORM START-NEW-PAGE.
019200     MOVE ZEROES TO RUNNING-TOTAL.
019300
019400 INITIALIZE-REPORT.
019500     MOVE ZEROES TO LINE-COUNT PAGE-NUMBER.
019600
019700 END-ONE-REPORT.
019800     IF RECORD-COUNT = ZEROES
019900         MOVE "NO RECORDS FOUND" TO PRINTER-RECORD
020000         PERFORM WRITE-TO-PRINTER.
020100
020200 PROCESS-VOUCHERS.
020300     PERFORM READ-FIRST-VALID-WORK.
020400     PERFORM PROCESS-ALL-DATES
020500         UNTIL WORK-FILE-AT-END = "Y".
020600
020700 PROCESS-ALL-DATES.
020800     PERFORM START-ONE-DATE.
020900
021000     PERFORM PROCESS-ALL-VOUCHERS
021100         UNTIL WORK-FILE-AT-END = "Y"
021200            OR WORK-DUE NOT = SAVE-DUE.
021300
021400     PERFORM END-ONE-DATE.
021500
021600 START-ONE-DATE.
021700     MOVE WORK-DUE TO SAVE-DUE.
021800
021900 END-ONE-DATE.
022000     PERFORM PRINT-RUNNING-TOTAL.
022100
022200 PRINT-RUNNING-TOTAL.
022300     MOVE SPACE TO DETAIL-LINE.
022400     MOVE SAVE-DUE TO DATE-CCYYMMDD.
022500     PERFORM CONVERT-TO-MMDDCCYY.
022600     MOVE DATE-MMDDCCYY TO PRINT-DUE-DATE.
022700     MOVE RUNNING-TOTAL TO PRINT-AMOUNT.
022800     MOVE TOTAL-THRU TO PRINT-NAME.
022900     MOVE DETAIL-LINE TO PRINTER-RECORD.
023000     PERFORM WRITE-TO-PRINTER.
023100     PERFORM LINE-FEED 2 TIMES.
023200
023300 PROCESS-ALL-VOUCHERS.
023400     PERFORM PROCESS-THIS-VOUCHER.
023500     PERFORM READ-NEXT-VALID-WORK.
023600
023700 PROCESS-THIS-VOUCHER.
023800     ADD 1 TO RECORD-COUNT.
023900     IF LINE-COUNT > MAXIMUM-LINES
024000         PERFORM START-NEXT-PAGE.
024100     PERFORM PRINT-THE-RECORD.
024200     ADD WORK-AMOUNT TO RUNNING-TOTAL.
024300
024400 PRINT-THE-RECORD.
024500     PERFORM PRINT-LINE-1.
024600     PERFORM PRINT-LINE-2.
024700     PERFORM LINE-FEED.
024800
024900 PRINT-LINE-1.
025000     MOVE SPACE TO DETAIL-LINE.
025100     MOVE WORK-NUMBER TO PRINT-NUMBER.
025200
025300     MOVE WORK-VENDOR TO VENDOR-NUMBER.
025400     PERFORM READ-VENDOR-RECORD.
025500     IF VENDOR-RECORD-FOUND = "Y"
025600         MOVE VENDOR-NAME TO PRINT-NAME
025700     ELSE
025800         MOVE "*VENDOR NOT ON FILE*" TO PRINT-NAME.
025900
026000     MOVE WORK-DUE TO DATE-CCYYMMDD.
026100     PERFORM CONVERT-TO-MMDDCCYY.
026200     MOVE DATE-MMDDCCYY TO PRINT-DUE-DATE.
026300
026400     MOVE WORK-AMOUNT TO PRINT-AMOUNT.
026500     MOVE WORK-INVOICE TO PRINT-INVOICE.
026600
026700     MOVE DETAIL-LINE TO PRINTER-RECORD.
026800     PERFORM WRITE-TO-PRINTER.
026900
027000 PRINT-LINE-2.
027100     MOVE SPACE TO DETAIL-LINE.
027200     MOVE WORK-FOR TO PRINT-NAME.
027300     MOVE DETAIL-LINE TO PRINTER-RECORD.
027400     PERFORM WRITE-TO-PRINTER.
027500
027600 WRITE-TO-PRINTER.
027700     WRITE PRINTER-RECORD BEFORE ADVANCING 1.
027800     ADD 1 TO LINE-COUNT.
027900
028000 LINE-FEED.
028100     MOVE SPACE TO PRINTER-RECORD.
028200     PERFORM WRITE-TO-PRINTER.
028300
028400 START-NEXT-PAGE.
028500     PERFORM END-LAST-PAGE.
028600     PERFORM START-NEW-PAGE.
028700
028800 START-NEW-PAGE.
028900     ADD 1 TO PAGE-NUMBER.
029000     MOVE PAGE-NUMBER TO PRINT-PAGE-NUMBER.
029100     MOVE TITLE-LINE TO PRINTER-RECORD.
029200     PERFORM WRITE-TO-PRINTER.
029300     PERFORM LINE-FEED.
029400     MOVE COLUMN-LINE TO PRINTER-RECORD.
029500     PERFORM WRITE-TO-PRINTER.
029600     PERFORM LINE-FEED.
029700
029800 END-LAST-PAGE.
029900     PERFORM FORM-FEED.
030000     MOVE ZERO TO LINE-COUNT.
030100
030200 FORM-FEED.
030300     MOVE SPACE TO PRINTER-RECORD.
030400     WRITE PRINTER-RECORD BEFORE ADVANCING PAGE.
030500
030600*--------------------------------
030700* Read first, read next routines
030800*--------------------------------
030900 READ-FIRST-VALID-WORK.
031000     PERFORM READ-NEXT-VALID-WORK.
031100
031200 READ-NEXT-VALID-WORK.
031300     PERFORM READ-NEXT-WORK-RECORD.
031400     PERFORM READ-NEXT-WORK-RECORD
031500         UNTIL WORK-FILE-AT-END = "Y"
031600            OR ( WORK-PAID-DATE = ZEROES AND
031700                 WORK-SELECTED = "Y").
031800
031900 READ-NEXT-WORK-RECORD.
032000     MOVE "N" TO WORK-FILE-AT-END.
032100     READ WORK-FILE NEXT RECORD
032200         AT END MOVE "Y" TO WORK-FILE-AT-END.
032300
032400*--------------------------------
032500* Other File IO routines
032600*--------------------------------
032700 READ-VENDOR-RECORD.
032800     MOVE "Y" TO VENDOR-RECORD-FOUND.
032900     READ VENDOR-FILE RECORD
033000         INVALID KEY
033100         MOVE "N" TO VENDOR-RECORD-FOUND.
033200
033300*--------------------------------
033400* Utility Routines
033500*--------------------------------
033600     COPY "PLDATE01.CBL".
033700

In the sample output report from cshrq01.cbl, the user has selected all vouchers through 01/23/1997, using vchsel01.cbl, and has additionally selected vouchers numbered 3 and 4, using vchpic01.cbl:

OUTPUT:

                            CASH REQUIREMENTS                PAGE:    1
VOUCHER VENDOR/For                       DUE DATE AMOUNT DUE INVOICE
16   CHARLES SMITH AND SONS          1/16/1997      25.97 5098
1997 DAY RUNNER
TOTAL THRU  1/16/1997      25.97
14   AERIAL SIGNS                    1/17/1997   1,046.97 FA1234
SIGN OVER ZUMA BEACH
TOTAL THRU  1/17/1997   1,072.94
13   MA BELL                         1/23/1997      94.96 50577
PHONE LINE 555-6067
19   MA BELL                         1/23/1997      34.95 50577
PHONE LINE 555-9098
TOTAL THRU  1/23/1997   1,202.85
4   ABC PRINTING                    2/07/1997     104.19 CX-5055
LETTER HEAD
TOTAL THRU  2/07/1997   1,307.04
3   CHARLES SMITH AND SONS          2/22/1997      27.76 5057
OFFICE SUPPLIES
TOTAL THRU  2/22/1997   1,334.80

ANALYSIS: The TITLE-LINE is changed at lines 010600 and 010700. The main change is in the record selection logic in READ-NEXT-VALID-WORK at line 031200. A test has been added at line 031700 so that records are selected only when WORK-PAID-DATE = ZEROES and WORK-SELECTED = "Y". This additional test eliminates unselected records.

Completing the System

The last steps needed to tie all the programs together are to get all the parts on menus by creating a new menu, and making some changes to an existing menu. Listing 21.10 is a menu of the voucher processes in the order they are used in the bills processing system. This menu program calls VCHPAY02,which you should have created in Exercise 1 of the previous chapter, Day 20, "More Complex Data Entry." If you did not create it for that exercise, go back and do so now.

TYPE: Listing 21.10. A menu for voucher handling.

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID. VCHMNU01.
000300*-------------------------------
000400* Menu for Voucher Processing
000500*--------------------------------
000600 ENVIRONMENT DIVISION.
000700 INPUT-OUTPUT SECTION.
000800 FILE-CONTROL.
000900
001000 DATA DIVISION.
001100 FILE SECTION.
001200
001300 WORKING-STORAGE SECTION.
001400
001500 77  MENU-PICK                    PIC 9.
001600     88  MENU-PICK-IS-VALID       VALUES 0 THRU 7.
001700
001800 PROCEDURE DIVISION.
001900 PROGRAM-BEGIN.
002000     PERFORM OPENING-PROCEDURE.
002100     PERFORM MAIN-PROCESS.
002200     PERFORM CLOSING-PROCEDURE.
002300
002400 PROGRAM-EXIT.
002500     EXIT PROGRAM.
002600
002700 PROGRAM-DONE.
002800     STOP RUN.
002900
003000 OPENING-PROCEDURE.
003100
003200 CLOSING-PROCEDURE.
003300
003400 MAIN-PROCESS.
003500     PERFORM GET-MENU-PICK.
003600     PERFORM DO-THE-PICK
003700         UNTIL MENU-PICK = 0.
003800
003900*--------------------------------
004000* MENU
004100*--------------------------------
004200 GET-MENU-PICK.
004300     PERFORM DISPLAY-THE-MENU.
004400     PERFORM ACCEPT-MENU-PICK.
004500     PERFORM RE-ACCEPT-MENU-PICK
004600         UNTIL MENU-PICK-IS-VALID.
004700
004800 DISPLAY-THE-MENU.
004900     PERFORM CLEAR-SCREEN.
005000     DISPLAY "    PLEASE SELECT:".
005100     DISPLAY " ".
005200     DISPLAY "          1.  VOUCHER ENTRY".
005300     DISPLAY "          2.  BILLS REPORT".
005400     DISPLAY "          3.  SELECT VOUCHERS BY DUE DATE RANGE".
005500     DISPLAY "          4.  SELECT INDIVIDUAL VOUCHERS".
005600     DISPLAY "          5.  CLEAR PREVIOUS SELECTIONS".
005700     DISPLAY "          6.  CASH REQUIREMENTS REPORT".
005800     DISPLAY "          7.  PAID BILLS ENTRY".
005900     DISPLAY " ".
006000     DISPLAY "          0.  EXIT".
006100     PERFORM SCROLL-LINE 8 TIMES.
006200
006300 ACCEPT-MENU-PICK.
006400     DISPLAY "YOUR CHOICE (0-7)?".
006500     ACCEPT MENU-PICK.
006600
006700 RE-ACCEPT-MENU-PICK.
006800     DISPLAY "INVALID SELECTION - PLEASE RE-TRY.".
006900     PERFORM ACCEPT-MENU-PICK.
007000
007100 CLEAR-SCREEN.
007200     PERFORM SCROLL-LINE 25 TIMES.
007300
007400 SCROLL-LINE.
007500     DISPLAY " ".
007600
007700 DO-THE-PICK.
007800     IF MENU-PICK = 1
007900         PERFORM VOUCHER-ENTRY
008000     ELSE
008100     IF MENU-PICK = 2
008200         PERFORM BILLS-REPORT
008300     ELSE
008400     IF MENU-PICK = 3
008500         PERFORM DATE-SELECTION
008600     ELSE
008700     IF MENU-PICK = 4
008800         PERFORM SINGLE-SELECTION
008900     ELSE
009000     IF MENU-PICK = 5
009100         PERFORM CLEAR-SELECTIONS
009200     ELSE
009300     IF MENU-PICK = 6
009400         PERFORM CASH-REQUIREMENTS
009500     ELSE
009600     IF MENU-PICK = 7
009700         PERFORM PAID-ENTRY.
009800
009900     PERFORM GET-MENU-PICK.
010000
010100 VOUCHER-ENTRY.
010200     CALL "VCHMNT01".
010300
010400 BILLS-REPORT.
010500     CALL "BILRPT03".
010600
010700 DATE-SELECTION.
010800     CALL "VCHSEL01".
010900
011000 SINGLE-SELECTION.
011100     CALL "VCHPIC01".
011200
011300 CLEAR-SELECTIONS.
011400     CALL "VCHCLR01".
011500
011600 CASH-REQUIREMENTS.
011700     CALL "CSHREQ01".
011800
011900 PAID-ENTRY.
012000     CALL "VCHPAY02".
012100
012200

The following is the output:

OUTPUT:

PLEASE SELECT:
1.  VOUCHER ENTRY
2.  BILLS REPORT
3.  SELECT VOUCHERS BY DUE DATE RANGE
4.  SELECT INDIVIDUAL VOUCHERS
5.  CLEAR PREVIOUS SELECTIONS
6.  CASH REQUIREMENTS REPORT
7.  PAID BILLS ENTRY
0.  EXIT
YOUR CHOICE (0-7)?

Finally, the bills payment system main menu must be modified to call the new voucher-processing menu. Listing 21.11, bilmnu03.cbl, adds a single pick to the main menu.

Listing 21.11. An extended main menu.

000100 IDENTIFICATION DIVISION.
000200 PROGRAM-ID. BILMNU03.
000300*--------------------------------
000400* Menu for the bill payment system.
000500* Including Vouchers
000600*--------------------------------
000700 ENVIRONMENT DIVISION.
000800 INPUT-OUTPUT SECTION.
000900 FILE-CONTROL.
001000
001100 DATA DIVISION.
001200 FILE SECTION.
001300
001400 WORKING-STORAGE SECTION.
001500
001600 77  MENU-PICK                    PIC 9.
001700     88  MENU-PICK-IS-VALID       VALUES 0 THRU 3.
001800
001900 PROCEDURE DIVISION.
002000 PROGRAM-BEGIN.
002100     PERFORM OPENING-PROCEDURE.
002200     PERFORM MAIN-PROCESS.
002300     PERFORM CLOSING-PROCEDURE.
002400
002500 PROGRAM-EXIT.
002600     EXIT PROGRAM.
002700
002800 PROGRAM-DONE.
002900     STOP RUN.
003000
003100 OPENING-PROCEDURE.
003200
003300 CLOSING-PROCEDURE.
003400
003500 MAIN-PROCESS.
003600     PERFORM GET-MENU-PICK.
003700     PERFORM DO-THE-PICK
003800         UNTIL MENU-PICK = 0.
003900
004000*--------------------------------
004100* MENU
004200*--------------------------------
004300 GET-MENU-PICK.
004400     PERFORM DISPLAY-THE-MENU.
004500     PERFORM ACCEPT-MENU-PICK.
004600     PERFORM RE-ACCEPT-MENU-PICK
004700         UNTIL MENU-PICK-IS-VALID.
004800
004900 DISPLAY-THE-MENU.
005000     PERFORM CLEAR-SCREEN.
005100     DISPLAY "    PLEASE SELECT:".
005200     DISPLAY " ".
005300     DISPLAY "          1.  STATE CODE MAINTENANCE".
005400     DISPLAY "          2.  VENDOR MAINTENANCE".
005500     DISPLAY "          3.  VOUCHER PROCESSING".
005600     DISPLAY " ".
005700     DISPLAY "          0.  EXIT".
005800     PERFORM SCROLL-LINE 8 TIMES.
005900
006000 ACCEPT-MENU-PICK.
006100     DISPLAY "YOUR CHOICE (0-3)?".
006200     ACCEPT MENU-PICK.
006300
006400 RE-ACCEPT-MENU-PICK.
006500     DISPLAY "INVALID SELECTION - PLEASE RE-TRY.".
006600     PERFORM ACCEPT-MENU-PICK.
006700
006800 CLEAR-SCREEN.
006900     PERFORM SCROLL-LINE 25 TIMES.
007000
007100 SCROLL-LINE.
007200     DISPLAY " ".
007300
007400 DO-THE-PICK.
007500     IF MENU-PICK = 1
007600         PERFORM STATE-MAINTENANCE
007700     ELSE
007800     IF MENU-PICK = 2
007900         PERFORM VENDOR-MAINTENANCE
008000     ELSE
008100     IF MENU-PICK = 3
008200         PERFORM VOUCHER-PROCESSING.
008300
008400     PERFORM GET-MENU-PICK.
008500
008600*--------------------------------
008700* STATE
008800*--------------------------------
008900 STATE-MAINTENANCE.
009000     CALL "STCMNT04".
009100
009200*--------------------------------
009300* VENDOR
009400*--------------------------------
009500 VENDOR-MAINTENANCE.
009600     CALL "VNDMNT05".
009700
009800*--------------------------------
009900* VOUCHERS
010000*--------------------------------
010100 VOUCHER-PROCESSING.
010200     CALL "VCHMNU01".
010300

Here is the output:

OUTPUT:

PLEASE SELECT:
1.  STATE CODE MAINTENANCE
2.  VENDOR MAINTENANCE
3.  VOUCHER PROCESSING
0.  EXIT
YOUR CHOICE (0-3)?

In Closing

This course has not covered all of COBOL syntax, nor has it covered all the commands and their versions. It has covered working COBOL not just at an individual level, but at a system level, trying to give you an idea of how programs work together to get a job done.

A piece of advice frequently given to writers is, "If you want to learn how to write, write." The same is true of programming. If you want to learn how to program, you should program.

Go back to earlier sections of the book. Pick up the phone book maintenance program that was started, and work out how to do it better. Create an indexed phone file. Program your own phone book program with fields for home, office, car, beeper, and fax numbers. Design a report that prints all this information. Add an alternate key to the name field so that a phone number can be looked up by user name.

Write a program to keep track of your to-do list in a file containing the project description, priority, and due date. Write reports that print the to-do list in priority order and in due-date order.

It really doesn't matter what the project is or how simple it is; in fact, the simpler the better. Just keep writing!

This completes your 21-day course, and you now have an excellent grounding in COBOL. With practice, you can become an expert.

COBOL is a comprehensive language, and you never really stop learning about it. I still study it whenever I have the chance. To enable you to continue your progress in COBOL, this book includes six Bonus Day lessons! These expand on topics already covered and open up some new areas.

The Bonus Day chapters also cover the issue that is filling the computer news these days: the year 2000, its effect on COBOL programs, and what needs to be done to fix the problem.

So pat yourself on the back. You've done a terrific job so far. Onward to a few more days of work.

Summary

Reporting is the most visible part of any program. Today, you learned these basics:

process-records
     read-first-valid-record
     perform process-loop
          until file-at-end
process-loop
     process-this-record.
     read-next-valid-record
read-first-valid-record
     start-the-file
     read-next-valid-record
read-next-valid-record
     read-next-record
     perform read-next-record
          until file is at end
          or (the selection condition is met)

Q&A

Q Some of the fields in the VOUCHER-FILE are never used in reports such as the VOUCHER-DEDUCTIBLE. What happens to this field?

A See the exercises in the Workshop section.

Workshop

Quiz

1. What is the SORT command used for?

2. Before the following command is used, in which state must the VOUCHER-FILE and WORK-FILE be?
SORT SORT-FILE
  ON ASCENDING KEY SORT-DATE
  USING VOUCHER-FILE
  GIVING WORK-FILE
a. Open

b. Closed

c. Doesn't matter

Exercises

1. Copy cshreq01.cbl to deduct01.cbl, and modify the program to do the following:
a. Change the PROGRAM-ID to DEDUCT01.

b. Modify the comment to indicate that this will be the deductibles report.

c. Modify TITLE-LINE to read "DEDUCTIBLES".

d. Modify the column headings in COLUMN-LINE to read DATE and AMOUNT instead of DUE DATE and AMOUNT DUE.

e. Change the variable SAVE-DUE to SAVE-PAID-DATE.

f. Modify ACCEPT-OK-TO-PROCESS to display "PRINT DEDUCTIBLES REPORT (Y/N)?".

g. Sort by SORT-PAID-DATE.

h. Modify PROCESS-ALL-DATES and START-ONE-DATE to save WORK-PAID-DATE and process until WORK-PAID-DATE NOT = SAVE-PAID-DATE.

i. Modify PRINT-RUNNING-TOTAL to print SAVE-PAID-DATE instead of SAVE-DUE.

j. Modify PROCESS-THIS-VOUCHER to move WORK-PAID-AMOUNT to the print line instead of WORK-AMOUNT.

k. Modify PRINT-LINE-1 to print the WORK-PAID-AMOUNT and WORK-PAID-DATE.

2. Modify READ-NEXT-VALID-WORK to select records when (WORK-PAID-DATE NOT = ZEROES AND WORK-DEDUCTIBLE = "Y").

3. Compile and run this program. It should give you a report on any paid vouchers that have the VOUCHER-DEDUCTIBLE flag set to "Y".


Previous chapterNext chapterContents


© Copyright, Macmillan Computer Publishing. All rights reserved.