Indexed files make it easy to change or delete the contents of a file while maintaining the order of records in the file. Today, you learn about the following topics:
A COPY file is a convenient way of cutting down on the amount of typing you do and reducing the possibility for errors in a program. How do you use them? In Day 11, "Indexed File I/O," you created six programs that accessed the vendor file: vndbld01.cbl, vnderr01.cbl, vnderr02.cbl, vndnew01.cbl, vndnew02.cbl, and vnddsp02.cbl. Regardless of whatever else was going on in the programs, all of them had identical SELECT statements and file descriptors for the vendor file.
You have yet to write programs to change, delete, and print records; these also need to describe the vendor file. This brings the total number of programs to at least nine, and there are probably more. It seems wasteful (and increases the possibility of errors) to have to retype the SELECT and FD every time they are used. Is there a solution? The COPY statement to the rescue!
Any part of a COBOL program can be written in a separate file. In the main file, you can include the separate program file by using a COPY statement. When the main program is compiled, the compiler includes the text in the COPY file, as though you had typed the text into the main file.
001200 COPY "FDVENDOR.CBL".
The COPY statement starts in Area B (columns 12 through 72) and is followed immediately by the name of the file to COPY and a period. For most MS-DOS COBOL compilers, enclose the filename in double quotation marks and then end the statement with a period. If you are working on another machine, check your manual.
The COPY statement can include comments, and it is organized like a standard COBOL source file with a sequence area, indicator area, Area A, and Area B.
Listings 12.1 and 12.2 are each complete edited files containing the SELECT statement and FD for the vendor file. Listing 12.3 is vndbld02.cbl, a revised version of vndbld01.cbl. It uses COPY statements to include slvnd01.cbl and fdvnd01.cbl. Both of these listings are used in Listing 12.3 to create a vendor file. You should create them now.
000100*-------------------------------- 000200* SLVND01.CBL 000300*-------------------------------- 000400 SELECT VENDOR-FILE 000500 ASSIGN TO "vendor" 000600 ORGANIZATION IS INDEXED 000700 RECORD KEY IS VENDOR-NUMBER 000800 ACCESS MODE IS DYNAMIC. 000900
000100*-------------------------------- 000200* FDVND01.CBL 000300*-------------------------------- 000400 FD VENDOR-FILE 000500 LABEL RECORDS ARE STANDARD. 000600 01 VENDOR-RECORD. 000700 05 VENDOR-NUMBER PIC 9(5). 000800 05 VENDOR-NAME PIC X(30). 000900 05 VENDOR-ADDRESS-1 PIC X(30). 001000 05 VENDOR-ADDRESS-2 PIC X(30). 001100 05 VENDOR-CITY PIC X(20). 001200 05 VENDOR-STATE PIC X(2). 001300 05 VENDOR-ZIP PIC X(10). 001400 05 VENDOR-CONTACT PIC X(30). 001500 05 VENDOR-PHONE PIC X(15). 001600
Listing 12.3 is an example of a Vendor file creation program. If you run it, it will delete any existing vendor file. You might want to copy your current vendor file to backup directory before running this program. After you have tested that a vendor file is created, you can restore your originals.
000100 IDENTIFICATION DIVISION. 000200 PROGRAM-ID. VNDBLD02. 000300*------------------------------------------------ 000400* Create an Empty Vendor File. 000500*------------------------------------------------ 000600 ENVIRONMENT DIVISION. 000700 INPUT-OUTPUT SECTION. 000800 FILE-CONTROL. 000900 001000 COPY "SLVND01.CBL". 001100 001200 DATA DIVISION. 001300 FILE SECTION. 001400 001500 COPY "FDVND01.CBL". 001600 001700 WORKING-STORAGE SECTION. 001800 001900 PROCEDURE DIVISION. 002000 PROGRAM-BEGIN. 002100 OPEN OUTPUT VENDOR-FILE. 002200 CLOSE VENDOR-FILE. 002300 002400 PROGRAM-DONE. 002500 STOP RUN. 002600
ANALYSIS: The result of compiling vndbld02.cbl using the two COPY files is a program that is identical in function to the original vndbld01.cbl.
New Term: The COPY command is not a programming command. It is a command to the compiler to tell it to pull the pieces of different files together into one file and then compile the resulting file. A command that controls the compiler's behavior is called a compiler directive, and the COPY command is sometimes called the COPY directive.
The COPY directive makes it possible to code the SELECT and FD for a file only once, and then to include it in all programs that access that file.
If all programs use the COPY directive for files, how do you know the names of variables in a file description? Most systems have many files. An accounts payable system has a vendor file, a bills-due file and possibly a historical bills-paid file, and a check file used for check reconciliation. It also has some sort of control file that is used to store the next check number to be used and the next vendor number to be used. These are enough for a small accounts payable system.
The primary way of keeping track of all these is to print the FD for each of the files in the system and keep them in a loose-leaf binder. Each member of the programming staff might have one of these binders, or binders can be placed centrally so that everyone has access to them.
The FD should include helpful comments that can be used by the programmer, and the comments do not necessarily need to relate only to the programming side of the computer system.
Listings 12.4, 12.5, and 12.6 are sample file descriptors that could be printed. The printed copy of the FD could be kept on hand when coding a program as an aid to help with program design. If the FD is adequately commented, there usually is no need to include a printout of the COPY file for the SELECT statement. You should code these files and keep them on hand as you will be using them in this and subsequent chapters.
000100*-------------------------------- 000200* FDVND02.CBL 000300* Primary Key - VENDOR-NUMBER 000400* VENDOR-ADDRESS-2 not always used 000500* so may be SPACES 000600* VENDOR-PHONE is usually the 000700* number for VENDOR-CONTACT 000800* All fields should be entered in 000900* UPPER case. 001000*-------------------------------- 001100 FD VENDOR-FILE 001200 LABEL RECORDS ARE STANDARD. 001300 01 VENDOR-RECORD. 001400 05 VENDOR-NUMBER PIC 9(5). 001500 05 VENDOR-NAME PIC X(30). 001600 05 VENDOR-ADDRESS-1 PIC X(30). 001700 05 VENDOR-ADDRESS-2 PIC X(30). 001800 05 VENDOR-CITY PIC X(20). 001900 05 VENDOR-STATE PIC X(2). 002000 05 VENDOR-ZIP PIC X(10). 002100 05 VENDOR-CONTACT PIC X(30). 002200 05 VENDOR-PHONE PIC X(15). 002300
000100*-------------------------------- 000200* FDCHK01.CBL 000300* Primary Key - CHECK-KEY 000400* if you use more than 1 check 000500* account to pay bills, using 000600* check numbers only may 000700* cause duplicates. 000800* CHECK-INVOICE is the vendor's 000900* invoice that this check paid 001000* and can be blank. 001100* CHECK-CLEARED = "Y" once the 001200* the check is reported cashed 001300* on a bank statement. Setting 001400* this flag is done in the 001500* check clearance program 001600* chkclr.cbl. 001700* CHECK-REFERENCE for any notes 001800* about the check. 001900* CHECK-VENDOR can be zero for a 002000* general check to someone who 002100* is not a regular vendor, but 002200* CHECK-REFERENCE should be 002300* filled in with payee. 002400*-------------------------------- 002500 FD CHECK-FILE 002600 LABEL RECORDS ARE STANDARD. 002700 01 CHECK-RECORD. 002800 05 CHECK-KEY. 002900 10 CHECK-ACCOUNT PIC 9(10). 003000 10 CHECK-NUMBER PIC 9(6). 003100 05 CHECK-AMOUNT PIC S9(6)V99. 003200 05 CHECK-INVOICE PIC X(15). 003300 05 CHECK-VENDOR PIC 9(5). 003400 05 CHECK-REFERENCE PIC X(30). 003500 05 CHECK-CLEARED PIC X. 003600
000100*-------------------------------- 000200* FDBILL01.CBL 000300* Primary Key - BILL-NUMBER 000400* BILL-DATE, BILL-DUE and BILL-PAID 000500* are all dates in CCYYMMDD format. 000600*-------------------------------- 000700 FD BILL-FILE 000800 LABEL RECORDS ARE STANDARD. 000900 01 CHECK-RECORD. 001000 05 BILL-NUMBER PIC 9(6). 001100 05 BILL-DATE PIC 9(8). 001200 05 BILL-DUE PIC 9(8). 001300 05 BILL-AMOUNT PIC S9(6)V99. 001400 05 BILL-INVOICE PIC X(15). 001500 05 BILL-VENDOR PIC 9(5). 001600 05 BILL-NOTES PIC X(30). 001700 05 BILL-PAID PIC 9(8). 001800
If pieces of the program are in other files, how do you ever get to see the whole program?
New Term: A listing file, source listing, or simply a listing is a report produced by the compiler on the program that it has just compiled. This can be sent directly to the printer, or it can be created as a separate file that can be displayed or sent to the printer.
A listing file contains the code of the original file being compiled and all COPY files included in their correct places in the file. The listing file usually will include additional information about how the compile went, whether any warnings or errors were given by the compiler, and sometimes information on how variables are used in the program. It sometimes includes a list of all paragraph names in the program and what lines perform these paragraphs.
The method of producing a listing file varies enormously from compiler to compiler. Check your COBOL manual index under listing, and you should find instructions for producing a listing file.
In Micro Focus Personal COBOL, you specify whether you want a listing file created and what information that you want in your listing file just before compiling (checking) the program. The program vndnew03.cbl copies slvnd01.cbl and fdvnd02.cbl. In Figure 12.1, the Micro Focus Personal COBOL compiler is set up and ready to compile and produce a listing to the printer. To set this up, press F2 until check is ready to run, press F4 until the list option is displayed as Print, and then press F7 until XRef+Ref is selected. See the highlighted entries.
Listing files are notorious for being poorly documented. I have never found in any manual or other reference material a clear explanation of a listing file produced by a COBOL compiler. Listing files also differ from compiler to compiler. You usually have to carefully analyze a listing file to learn how to extract the information you need from it and to ignore the rest.
Figure 12.1.
Micro Focus Personal COBOL ready to generate a listing at the printer.
Listing 12.7 shows the listing file generated by Micro Focus Personal COBOL for vndnew03.cbl. The vndnew03.cbl program is a minor revision on vndnew02.cbl that includes COPY files to illustrate the parts of a listing file.
* Micro Focus Personal COBOL v2.0.02 L2.0 revision 002 02-Jan-94 03:58 Page 1 * VNDNEW03.CBL * Options: WB ERRQ EDITOR(MF) LIST() XREF REF ANIM ENSUITE(2) CONFIRM 1 IDENTIFICATION DIVISION. 0 2 PROGRAM-ID. VNDNEW03. 230 3*------------------------------------------------ 4* Add a record to an indexed Vendor File. 5*------------------------------------------------ 6 ENVIRONMENT DIVISION. 230 7 INPUT-OUTPUT SECTION. 230 8 FILE-CONTROL. 230 9 230 * 10 COPY "SLVND01.CBL". 230 11*-------------------------------- 12* SLVND01.CBL 13*-------------------------------- 14 SELECT VENDOR-FILE 230 15 ASSIGN TO "vendor" 230 16 ORGANIZATION IS INDEXED 230 17 RECORD KEY IS VENDOR-NUMBER 230 18 ACCESS MODE IS DYNAMIC. 2C3 19 2C3 20 2C3 21 DATA DIVISION. 2C3 22 FILE SECTION. 2C3 23 2C3 * 24 COPY "FDVND02.CBL". 2C3 25*-------------------------------- 26* FDVND01.CBL 27* Primary Key - VENDOR-NUMBER 28* VENDOR-ADDRESS-2 not always used 29* so may be SPACES 30* VENDOR-PHONE is usually the 31* number for VENDOR-CONTACT 32* All fields should be entered in 33* UPPER case. 34*-------------------------------- 35 FD VENDOR-FILE 2C3 36 LABEL RECORDS ARE STANDARD. 2C3 37 01 VENDOR-RECORD. 2C8 38 05 VENDOR-NUMBER PIC 9(5). 2C8 39 05 VENDOR-NAME PIC X(30). 2CD 40 05 VENDOR-ADDRESS-1 PIC X(30). 2EB 41 05 VENDOR-ADDRESS-2 PIC X(30). 309 42 05 VENDOR-CITY PIC X(20). 327 43 05 VENDOR-STATE PIC X(2). 33B 44 05 VENDOR-ZIP PIC X(10). 33D 45 05 VENDOR-CONTACT PIC X(30). 347 46 05 VENDOR-PHONE PIC X(15). 365 47 374 48 374 49 WORKING-STORAGE SECTION. 378 50 378 51 01 VENDOR-NUMBER-FIELD PIC Z(5). 378 52 378 53 PROCEDURE DIVISION. 0 54 PROGRAM-BEGIN. 39 55 OPEN I-O VENDOR-FILE. 3A 56 PERFORM GET-NEW-VENDOR-NUMBER. 56 57 PERFORM ADD-RECORDS 59 * Micro Focus Personal COBOL v2.0.02 L2.0 revision 002 02-Jan-94 03:58 Page 2 * VNDNEW03.CBL 58 UNTIL VENDOR-NUMBER = ZEROES. 67 59 CLOSE VENDOR-FILE. 67 60 7D 61 PROGRAM-DONE. 7D 62 STOP RUN. 7E 63 7F 64 GET-NEW-VENDOR-NUMBER. 7F 65 PERFORM INIT-VENDOR-RECORD. 80 66 PERFORM ENTER-VENDOR-NUMBER. 83 67 86 68 INIT-VENDOR-RECORD. 86 69 MOVE SPACE TO VENDOR-RECORD. 87 70 MOVE ZEROES TO VENDOR-NUMBER. 8E 71 94 72 ENTER-VENDOR-NUMBER. 94 73 DISPLAY "ENTER VENDOR NUMBER (1-99999)". 95 74 DISPLAY "ENTER 0 TO STOP ENTRY". B5 75 ACCEPT VENDOR-NUMBER-FIELD. CD 76*OR ACCEPT VENDOR-NUMBER-FIELD WITH CONVERSION. 77 D5 78 MOVE VENDOR-NUMBER-FIELD TO VENDOR-NUMBER. D5 79*OR MOVE WITH CONVERSION VENDOR-NUMBER-FIELD 80* TO VENDOR-NUMBER. 81 DC 82 ADD-RECORDS. DC 83 PERFORM ENTER-REMAINING-FIELDS. DD 84 PERFORM WRITE-VENDOR-RECORD. E0 85 PERFORM GET-NEW-VENDOR-NUMBER. E3 86 E6 87 WRITE-VENDOR-RECORD. E6 88 WRITE VENDOR-RECORD E7 89 INVALID KEY E7 90 DISPLAY "RECORD ALREADY ON FILE". 107 91 122 92 ENTER-REMAINING-FIELDS. 122 93 PERFORM ENTER-VENDOR-NAME. 123 94 PERFORM ENTER-VENDOR-ADDRESS-1. 126 95 PERFORM ENTER-VENDOR-ADDRESS-2. 129 96 PERFORM ENTER-VENDOR-CITY. 12C 97 PERFORM ENTER-VENDOR-STATE. 12F 98 PERFORM ENTER-VENDOR-ZIP. 132 99 PERFORM ENTER-VENDOR-CONTACT. 135 100 PERFORM ENTER-VENDOR-PHONE. 138 101 13B 102 ENTER-VENDOR-NAME. 13B 103 DISPLAY "ENTER VENDOR NAME". 13C 104 ACCEPT VENDOR-NAME. 150 105 155 106 ENTER-VENDOR-ADDRESS-1. 155 107 DISPLAY "ENTER VENDOR ADDRESS-1". 156 108 ACCEPT VENDOR-ADDRESS-1. 16F 109 174 110 ENTER-VENDOR-ADDRESS-2. 174 111 DISPLAY "ENTER VENDOR ADDRESS-2". 175 112 ACCEPT VENDOR-ADDRESS-2. 18E 113 193 114 ENTER-VENDOR-CITY. 193 115 DISPLAY "ENTER VENDOR CITY". 194 * Micro Focus Personal COBOL v2.0.02 L2.0 revision 002 02-Jan-94 03:58 Page 3 * VNDNEW03.CBL 116 ACCEPT VENDOR-CITY. 1A8 117 1AD 118 ENTER-VENDOR-STATE. 1AD 119 DISPLAY "ENTER VENDOR STATE". 1AE 120 ACCEPT VENDOR-STATE. 1C3 121 1C8 122 ENTER-VENDOR-ZIP. 1C8 123 DISPLAY "ENTER VENDOR ZIP". 1C9 124 ACCEPT VENDOR-ZIP. 1DC 125 1E1 126 ENTER-VENDOR-CONTACT. 1E1 127 DISPLAY "ENTER VENDOR CONTACT". 1E2 128 ACCEPT VENDOR-CONTACT. 1F9 129 1FE 130 ENTER-VENDOR-PHONE. 1FE 131 DISPLAY "ENTER VENDOR PHONE". 1FF 132 ACCEPT VENDOR-PHONE. 214 133 219 * Micro Focus Personal COBOL v2.0.02 L2.0 revision 002 * * Total Messages: 0 * Data: 1012 Code: 563 Dictionary: 1515 * Micro Focus Personal COBOL v2.0.02 L2.0 revision 002 02-Jan-94 03:58 Page 4 * VNDNEW03.CBL (XREF) FILES * VENDOR-FILE Indexed * 14# 35 55 59 (X 4) * * * 1 files * Micro Focus Personal COBOL v2.0.02 L2.0 revision 002 02-Jan-94 03:58 Page 5 * VNDNEW03.CBL (XREF) DATA * VENDOR-ADDRESS-1 Alphanumeric * 40# 108* (X 2) * * VENDOR-ADDRESS-2 Alphanumeric * 41# 112* (X 2) * * VENDOR-CITY Alphanumeric * 42# 116* (X 2) * * VENDOR-CONTACT Alphanumeric * 45# 128* (X 2) * * VENDOR-NAME Alphanumeric * 39# 104* (X 2) * * VENDOR-NUMBER Numeric DISPLAY * 17 38# 58? 70* 78* (X 5) * * VENDOR-NUMBER-FIELD Numeric edited * 51# 75* 78 (X 3) * * VENDOR-PHONE Alphanumeric * 46# 132* (X 2) * * VENDOR-RECORD Group length 172 * 37# 69* 88 (X 3) * * VENDOR-STATE Alphanumeric * 43# 120* (X 2) * * VENDOR-ZIP Alphanumeric * 44# 124* (X 2) * * VNDNEW03 Program name * 2# (X 1) * * * 12 data-names * Micro Focus Personal COBOL v2.0.02 L2.0 revision 002 02-Jan-94 03:58 Page 6 * VNDNEW03.CBL (XREF) PROCS * ADD-RECORDS Paragraph * 57 82# (X 2) * * ENTER-REMAINING-FIELDS Paragraph * 83 92# (X 2) * * ENTER-VENDOR-ADDRESS-1 Paragraph * 94 106# (X 2) * * ENTER-VENDOR-ADDRESS-2 Paragraph * 95 110# (X 2) * * ENTER-VENDOR-CITY Paragraph * 96 114# (X 2) * * ENTER-VENDOR-CONTACT Paragraph * 99 126# (X 2) * * ENTER-VENDOR-NAME Paragraph * 93 102# (X 2) * * ENTER-VENDOR-NUMBER Paragraph * 66 72# (X 2) * * ENTER-VENDOR-PHONE Paragraph * 100 130# (X 2) * * ENTER-VENDOR-STATE Paragraph * 97 118# (X 2) * * ENTER-VENDOR-ZIP Paragraph * 98 122# (X 2) * * GET-NEW-VENDOR-NUMBER Paragraph * 56 64# 85 (X 3) * * INIT-VENDOR-RECORD Paragraph * 65 68# (X 2) * * PROGRAM-BEGIN Paragraph * 54# (X 1) * * PROGRAM-DONE Paragraph * 61# (X 1) * * WRITE-VENDOR-RECORD Paragraph * 84 87# (X 2) * * * 16 procedure-names * End of cross reference listing
ANALYSIS: The first thing you need to notice is that all COBOL line numbers have been stripped away and replaced with simple sequence numbers down the left side of the page. Every line not part of the original source code file (vndnew03.cbl) starts with an asterisk.
The COPY files have been included in full at lines 10 through 18 and lines 24 through 46. The numbers down the right side of the page represent addresses in memory where data or code is stored. The first few lines describe the options that were set on the compiler when this listing was created. You essentially can ignore these.
At the end of the listing, after line 128, some statistics about the program are printed, giving the sizes of the data and code created.
I requested a cross-reference (Xref+Ref), which begins on page 4 of the listing. The first page of the cross-reference lists the files used in the program and every line number on which the file is referenced. To the right of this is the number of times the file is referenced. Compare the line numbers listed under VENDOR-FILE (14, 35, 55, and 59) with the actual lines in the listing and you will see that VENDOR-FILE does indeed appear on those lines.
The next page of the cross-reference, page 5 of the listing, is a cross-reference of DATA, the variables used in the program, and the line numbers on which they are used.
Page 6 is a cross-reference of PROCS (paragraph names) in the PROCEDURE DIVISION used in the program. The PROCS listing is very useful in large programs, because every paragraph except PROGRAM-BEGIN and PROGRAM-DONE should appear at least twice in the cross-reference: once when the paragraph is defined, and at least once when it is performed. This part of the listing can be used to spot paragraphs that are never used.
You can use cross-reference listings when you are working on a program away from a computer and also when you are trying to fight your way through a complicated listing.
If a program includes some variable with an ambiguous name such as the OK-TO-DO-IT-FLAG, you have no way of guessing how this flag is really used. A cross-reference listing lets you zero in on every place that the flag is used, and it might help to isolate its purpose.
Now that you know how to use COPY files, you can get back to the business at hand--indexed files.
In order to change a record in an indexed file, two conditions must be met: the record must exist in the file before it can be changed, and the primary key field of a record cannot be changed in a file.
To change a record in an indexed file, you first must locate the record. To locate a record in an indexed file, use MOVE to move a value to the field that is the primary key to the file and use READ to read the file record. If a record exists with that key value, it is read from the disk. If a record does not exist with that key value, a file error condition occurs that you must trap. The trap for a READ is also INVALID KEY. Use the following syntax:
READ file-name RECORD INVALID KEY do something
Here is an example:
PERFORM ENTER-VENDOR-NUMBER. READ VENDOR-FILE RECORD INVALID KEY MOVE "N" TO RECORD-FOUND.
Changing a record involves moving new values to the fields of a record and using the REWRITE verb to rewrite the record. You cannot change the value in the primary key field. You must read the record successfully in the first place before you can execute a REWRITE. A REWRITE also uses INVALID KEY to trap any file error. This is the syntax:
REWRITE file-record INVALID KEY do something
The following is an example:
REWRITE VENDOR-RECORD INVALID KEY DISPLAY "ERROR ON REWRITE"
On some larger systems where files are shared with many users, there sometimes is an additional requirement that you must be able to lock the record before you perform the REWRITE. This prevents two users from modifying the same record at the same time.
The syntax for a lock varies for different versions of COBOL, but it usually is READ WITH LOCK or READ WITH HOLD. You do not need to use WITH HOLD or WITH LOCK unless the program complains about being unable to rewrite a record.
Record-locking is a fairly complex subject and beyond the scope of this book, but one of these two should be enough syntax to get your programs to work correctly:
READ file-name RECORD WITH LOCK INVALID KEY do something READ file-name RECORD WITH HOLD INVALID KEY do something
Here are two examples:
READ VENDOR-FILE RECORD WITH LOCK INVALID KEY MOVE "N" TO RECORD-FOUND READ VENDOR-FILE RECORD WITH HOLD INVALID KEY MOVE "N" TO RECORD-FOUND
A program that allows changes to an indexed file can be broken into two simple tasks:
Listing 12.8, vndchg01.cbl, asks the user to supply the vendor number for the record to be changed. It then displays the values in the record fields and asks the user which one to change. The record must exist in the file before it can be changed, and the primary key field of the record cannot be changed.
000100 IDENTIFICATION DIVISION. 000200 PROGRAM-ID. VNDCHG01. 000300*-------------------------------- 000400* Change records in Vendor File. 000500*-------------------------------- 000600 ENVIRONMENT DIVISION. 000700 INPUT-OUTPUT SECTION. 000800 FILE-CONTROL. 000900 001000 COPY "SLVND01.CBL". 001100 001200 DATA DIVISION. 001300 FILE SECTION. 001400 001500 COPY "FDVND02.CBL". 001600 001700 WORKING-STORAGE SECTION. 001800 001900 77 WHICH-FIELD PIC 9. 002000 77 RECORD-FOUND PIC X. 002100 002200 77 VENDOR-NUMBER-FIELD PIC Z(5). 002300 002400 PROCEDURE DIVISION. 002500 PROGRAM-BEGIN. 002600 OPEN I-O VENDOR-FILE. 002700 PERFORM GET-VENDOR-RECORD. 002800 PERFORM CHANGE-RECORDS 002900 UNTIL VENDOR-NUMBER = ZEROES. 003000 CLOSE VENDOR-FILE. 003100 003200 PROGRAM-DONE. 003300 STOP RUN. 003400 003500*-------------------------------- 003600* TO GET A VENDOR RECORD, ASK FOR 003700* VENDOR NUMBER, AND THEN TRY TO 003800* READ THE RECORD. 003900*-------------------------------- 004000 GET-VENDOR-RECORD. 004100 PERFORM INIT-VENDOR-RECORD. 004200 PERFORM ENTER-VENDOR-NUMBER. 004300 MOVE "N" TO RECORD-FOUND. 004400 PERFORM FIND-VENDOR-RECORD 004500 UNTIL RECORD-FOUND = "Y" OR 004600 VENDOR-NUMBER = ZEROES. 004700 004800 INIT-VENDOR-RECORD. 004900 MOVE SPACE TO VENDOR-RECORD. 005000 MOVE ZEROES TO VENDOR-NUMBER. 005100 005200 ENTER-VENDOR-NUMBER. 005300 DISPLAY " ". 005400 DISPLAY "ENTER VENDOR NUMBER OF THE VENDOR" . 005500 DISPLAY "TO CHANGE (1-99999)". 005600 DISPLAY "ENTER 0 TO STOP ENTRY". 005700 ACCEPT VENDOR-NUMBER-FIELD. 005800*OR ACCEPT VENDOR-NUMBER-FIELD WITH CONVERSION. 005900 006000 MOVE VENDOR-NUMBER-FIELD TO VENDOR-NUMBER. 006100 006200 FIND-VENDOR-RECORD. 006300 PERFORM READ-VENDOR-RECORD. 006400 IF RECORD-FOUND = "N" 006500 DISPLAY "RECORD NOT FOUND" 006600 PERFORM ENTER-VENDOR-NUMBER. 006700 006800 READ-VENDOR-RECORD. 006900 MOVE "Y" TO RECORD-FOUND. 007000 READ VENDOR-FILE RECORD 007100 INVALID KEY 007200 MOVE "N" TO RECORD-FOUND. 007300 007400*or READ VENDOR-FILE RECORD WITH LOCK 007500* INVALID KEY 007600* MOVE "N" TO RECORD-FOUND. 007700 007800*or READ VENDOR-FILE RECORD WITH HOLD 007900* INVALID KEY 008000* MOVE "N" TO RECORD-FOUND. 008100 008200 CHANGE-RECORDS. 008300 PERFORM GET-FIELD-TO-CHANGE. 008400 PERFORM CHANGE-ONE-FIELD 008500 UNTIL WHICH-FIELD = ZERO. 008600 PERFORM GET-VENDOR-RECORD. 008700 008800*-------------------------------- 008900* DISPLAY ALL FIELDS, ASK THE USER 009000* WHICH TO CHANGE. 009100*-------------------------------- 009200 GET-FIELD-TO-CHANGE. 009300 PERFORM DISPLAY-ALL-FIELDS. 009400 PERFORM ASK-WHICH-FIELD. 009500 009600*-------------------------------- 009700* DISPLAY ALL FIELDS WITH BLANK 009800* LINES ABOVE AND BELOW. 009900*-------------------------------- 010000 DISPLAY-ALL-FIELDS. 010100 DISPLAY " ". 010200 PERFORM DISPLAY-VENDOR-NUMBER. 010300 PERFORM DISPLAY-VENDOR-NAME. 010400 PERFORM DISPLAY-VENDOR-ADDRESS-1. 010500 PERFORM DISPLAY-VENDOR-ADDRESS-2. 010600 PERFORM DISPLAY-VENDOR-CITY. 010700 PERFORM DISPLAY-VENDOR-STATE. 010800 PERFORM DISPLAY-VENDOR-ZIP. 010900 PERFORM DISPLAY-VENDOR-CONTACT. 011000 PERFORM DISPLAY-VENDOR-PHONE. 011100 DISPLAY " ". 011200 011300 DISPLAY-VENDOR-NUMBER. 011400 DISPLAY " VENDOR NUMBER: " VENDOR-NUMBER. 011500 011600 DISPLAY-VENDOR-NAME. 011700 DISPLAY "1. VENDOR NAME: " VENDOR-NAME. 011800 011900 DISPLAY-VENDOR-ADDRESS-1. 012000 DISPLAY "2. VENDOR ADDRESS-1: " VENDOR-ADDRESS-1. 012100 012200 DISPLAY-VENDOR-ADDRESS-2. 012300 DISPLAY "3. VENDOR ADDRESS-2: " VENDOR-ADDRESS-2. 012400 012500 DISPLAY-VENDOR-CITY. 012600 DISPLAY "4. VENDOR CITY: " VENDOR-CITY. 012700 012800 DISPLAY-VENDOR-STATE. 012900 DISPLAY "5. VENDOR STATE: " VENDOR-STATE. 013000 013100 DISPLAY-VENDOR-ZIP. 013200 DISPLAY "6. VENDOR ZIP: " VENDOR-ZIP. 013300 013400 DISPLAY-VENDOR-CONTACT. 013500 DISPLAY "7. VENDOR CONTACT: " VENDOR-CONTACT. 013600 013700 DISPLAY-VENDOR-PHONE. 013800 DISPLAY "8. VENDOR PHONE: " VENDOR-PHONE. 013900 014000 ASK-WHICH-FIELD. 014100 DISPLAY "ENTER THE NUMBER OF THE FIELD". 014200 DISPLAY "TO CHANGE (1-8) OR 0 TO EXIT". 014300 ACCEPT WHICH-FIELD. 014400 IF WHICH-FIELD > 8 014500 DISPLAY "INVALID ENTRY". 014600 014700*-------------------------------- 014800* GET DATA ENTRY FOR THE NEW FIELD. 014900* THEN ASK FOR THE NEXT FIELD 015000* TO CHANGE. 015100* CONTINUE UNTIL USER ENTERS 0. 015200*-------------------------------- 015300 CHANGE-ONE-FIELD. 015400 PERFORM CHANGE-THIS-FIELD. 015500 PERFORM GET-FIELD-TO-CHANGE. 015600 015700*-------------------------------- 015800* ACCEPT DATA ENTRY FOR THE FIELD 015900* SPECIFIED, AND THEN REWRITE THE 016000* RECORD. 016100*-------------------------------- 016200 CHANGE-THIS-FIELD. 016300 IF WHICH-FIELD = 1 016400 PERFORM ENTER-VENDOR-NAME. 016500 IF WHICH-FIELD = 2 016600 PERFORM ENTER-VENDOR-ADDRESS-1. 016700 IF WHICH-FIELD = 3 016800 PERFORM ENTER-VENDOR-ADDRESS-2. 016900 IF WHICH-FIELD = 4 017000 PERFORM ENTER-VENDOR-CITY. 017100 IF WHICH-FIELD = 5 017200 PERFORM ENTER-VENDOR-STATE. 017300 IF WHICH-FIELD = 6 017400 PERFORM ENTER-VENDOR-ZIP. 017500 IF WHICH-FIELD = 7 017600 PERFORM ENTER-VENDOR-CONTACT. 017700 IF WHICH-FIELD = 8 017800 PERFORM ENTER-VENDOR-PHONE. 017900 018000 PERFORM REWRITE-VENDOR-RECORD. 018100 018200 ENTER-VENDOR-NAME. 018300 DISPLAY "ENTER VENDOR NAME". 018400 ACCEPT VENDOR-NAME. 018500 018600 ENTER-VENDOR-ADDRESS-1. 018700 DISPLAY "ENTER VENDOR ADDRESS-1". 018800 ACCEPT VENDOR-ADDRESS-1. 018900 019000 ENTER-VENDOR-ADDRESS-2. 019100 DISPLAY "ENTER VENDOR ADDRESS-2". 019200 ACCEPT VENDOR-ADDRESS-2. 019300 019400 ENTER-VENDOR-CITY. 019500 DISPLAY "ENTER VENDOR CITY". 019600 ACCEPT VENDOR-CITY. 019700 019800 ENTER-VENDOR-STATE. 019900 DISPLAY "ENTER VENDOR STATE". 020000 ACCEPT VENDOR-STATE. 020100 020200 ENTER-VENDOR-ZIP. 020300 DISPLAY "ENTER VENDOR ZIP". 020400 ACCEPT VENDOR-ZIP. 020500 020600 ENTER-VENDOR-CONTACT. 020700 DISPLAY "ENTER VENDOR CONTACT". 020800 ACCEPT VENDOR-CONTACT. 020900 021000 ENTER-VENDOR-PHONE. 021100 DISPLAY "ENTER VENDOR PHONE". 021200 ACCEPT VENDOR-PHONE. 021300 021400 REWRITE-VENDOR-RECORD. 021500 REWRITE VENDOR-RECORD 021600 INVALID KEY 021700 DISPLAY "ERROR REWRITING VENDOR RECORD". 021800
An example of the output from vndchg01.cbl follows. User entries are in bold type.
OUTPUT:
ENTER VENDOR NUMBER OF THE VENDOR TO CHANGE (1-99999) ENTER 0 TO STOP ENTRY 00003 VENDOR NUMBER: 00003 1. VENDOR NAME: CHARLES SMITH AND SONS 2. VENDOR ADDRESS-1: 1212 NORTH STREET 3. VENDOR ADDRESS-2: 4. VENDOR CITY: LOS ANGELES 5. VENDOR STATE: CA 6. VENDOR ZIP: 90064 7. VENDOR CONTACT: CHARLES SMITH 8. VENDOR PHONE: (213) 555-4432 ENTER THE NUMBER OF THE FIELD TO CHANGE (1-8) OR 0 TO EXIT 2 ENTER VENDOR ADDRESS-1 1435 SOUTH STREET VENDOR NUMBER: 00003 1. VENDOR NAME: CHARLES SMITH AND SONS 2. VENDOR ADDRESS-1: 1435 SOUTH STREET 3. VENDOR ADDRESS-2: 4. VENDOR CITY: LOS ANGELES 5. VENDOR STATE: CA 6. VENDOR ZIP: 90064 7. VENDOR CONTACT: CHARLES SMITH 8. VENDOR PHONE: (213) 555-4432 ENTER THE NUMBER OF THE FIELD TO CHANGE (1-8) OR 0 TO EXIT 7 ENTER VENDOR CONTACT MARTHA HARRISON VENDOR NUMBER: 00003 1. VENDOR NAME: CHARLES SMITH AND SONS 2. VENDOR ADDRESS-1: 1435 SOUTH STREET 3. VENDOR ADDRESS-2: 4. VENDOR CITY: LOS ANGELES 5. VENDOR STATE: CA 6. VENDOR ZIP: 90064 7. VENDOR CONTACT: MARTHA HARRISON 8. VENDOR PHONE: (213) 555-4432 ENTER THE NUMBER OF THE FIELD TO CHANGE (1-8) OR 0 TO EXIT 0 ENTER VENDOR NUMBER OF THE VENDOR TO CHANGE (1-99999) ENTER 0 TO STOP ENTRY 0 C> C>
ANALYSIS: The control of the main processing loop is at lines 002700 through 002900. This logic starts at 002700 by performing GET-VENDOR-RECORD. Then CHANGE-RECORDS is performed until VENDOR-NUMBER = ZEROES.
The CHANGE-RECORDS processing loop ends by performing GET-VENDOR-RECORD. Figure 12.2 illustrates the relationship between the main processing loop and the loop control logic.
The loop body of CHANGE-RECORDS is itself just another set of loop controls for a lower-level loop at CHANGE-ONE-FIELD, as shown in Figure 12.3.
The GET-VENDOR-RECORD and FIND-VENDOR-RECORD routines at lines 004000 and 006200 are an interesting pair of paragraphs. At lines 004400 through 004600, a perform is requested until two conditions are met. FIND-VENDOR-RECORD is a processing loop that has no body. All the work is done by changing the loop control variables at line 006300. The perform of READ-VENDOR-RECORD changes the RECORD-FOUND variable, and at line 006600, the perform of ENTER-VENDOR-NUMBER changes the VENDOR-NUMBER variable. This is shown in Figure 12.4.
Figure 12.2.
The main processing loop and the loop control.
Figure 12.3.
A loop within a loop.
Figure 12.4.
A processing loop with no loop body.
If you haven't already coded Listing 12.1, slvnd01.cbl, and Listing 12.4, fdvnd02.cbl, do so now because you need them for vndchg01.cbl.
This program is the longest one you've coded so far. You might find it easier to understand if you code it, compile it, and print out the program (by entering PRINT vndchg01.cbl for MS-DOS). Then run the program while reading the printed code, and follow where you are in the logic at each point of the program.
Indexed files make it easy to change or delete the contents of a file while maintaining the order of records in the file. Today, you learned these basics about indexed files:
The following code fragment is supposed to read a record in a file. If the record is found, new values are moved in and the record is rewritten. If the record is not found, the same values are used to create a brand-new record by loading the record and writing it. At least, that is what it is supposed to do. Why does it not work that way?
003200 ADD-OR-UPDATE. 003300 MOVE "Y" TO RECORD-FOUND-FLAG. 003400 MOVE NEW-NUMBER TO VENDOR-NUMBER. 003500 READ VENDOR-RECORD 003600 INVALID KEY 003700 MOVE "N" TO RECORD-FOUND-FLAG. 003800 IF RECORD-FOUND-FLAG = "N" 003900 PERFORM CHANGE-THIS-RECORD 004000 ELSE 004100 PERFORM ADD-THIS-RECORD. 004200 004300 CHANGE-THIS-RECORD. 004400 PERFORM LOAD-RECORD-VALUES. 004500 REWRITE VENDOR-RECORD 004600 INVALID KEY 004700 DISPLAY "ERROR CHANGING THE RECORD". 004800 004900 ADD-THIS-RECORD. 005000 PERFORM LOAD-RECORD-VALUES. 005100 WRITE VENDOR-RECORD 005200 INVALID KEY 005300 DISPLAY "ERROR ADDING THE RECORD". 005400 005500 LOAD-RECORD-VALUES. 005600 MOVE NEW-NAME TO VENDOR-NAME. 005700 MOVE NEW-ADDRESS-1 TO VENDOR-ADDRESS-1. 005800 MOVE NEW-ADDRESS-2 TO VENDOR-ADDRESS-2. 005900 MOVE NEW-CITY TO VENDOR-CITY. 006000 MOVE NEW-STATE TO VENDOR-STATE. 006100 MOVE NEW-ZIP TO VENDOR-ZIP. 006200 MOVE NEW-CONTACT TO VENDOR-CONTACT. 006300 MOVE NEW-PHONE TO VENDOR-PHONE. 006400
© Copyright, Macmillan Computer Publishing. All rights reserved.