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:
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.
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.
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.
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.
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:
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.
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.
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.
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.
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.
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:
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.
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
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.
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 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.
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.
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.
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.
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)?
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.
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)
SORT SORT-FILE ON ASCENDING KEY SORT-DATE USING VOUCHER-FILE GIVING WORK-FILE
© Copyright, Macmillan Computer Publishing. All rights reserved.