As computer systems become larger and larger, the amount of data stored on the computers increases. It is important that this data be as correct as it can be. In today's lesson, you create a file containing state codes, enter data into it using various levels of validation, and learn about the following topics:
You probably have heard the phrase, "Garbage in, garbage out." Recall from Day 1, "Your First COBOL Program," that a computer is a stupid machine. It will do only what you tell it to do and cannot make sensible decisions. If you put a silly program into the computer (garbage in), it will execute the silliness without question (garbage out). If you put invalid data into the data files, a program will return that invalid data to you every time you ask for it.
Creating data integrity is the process of ensuring that every field in every record of every file in a system contains only valid data. It is most efficient to do this when the data first is added to a file in the maintenance program.
Valid data can be broken down into two categories:
Program-level data must be valid to match the criteria of the specified computer or programming language. A numeric variable must contain numeric data, even if it is only zeroes. A record in an indexed file must contain a unique value for the primary key. Invalid data at the program level usually causes a program to fail or crash, and therefore it is fairly easy to spot.
Application-level data must be valid to enable the user to use the system correctly. For example, a program that is used to maintain a file of phone numbers that are critical to a business requires extra care to ensure that phone numbers are entered correctly. How much validation is enough depends on the application.
Listing 15.1 shows the now-familiar logical description of the vendor file.
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
ANALYSIS: The FD contains some notes at lines 000400 through 000900 about valid data, but this could extend further. If the bill paying system prints envelopes for mailing checks to creditors, the system should be designed so that every record in the vendor file has a valid address that can be printed on the envelopes. If the company that uses this bill-paying system operates in such a way that it is common to call creditors on the phone, the system design requires that VENDOR-CONTACT and VENDOR-PHONE be filled in.
The design of any system probably requires that the VENDOR-NAME always must be filled in. The add and change maintenance portions of the program should be set up to complain to the user if an attempt is made to add a vendor but leave the name blank.
It would be ideal if application-level data validation could check not only that the VENDOR-NAME is entered, but also that the VENDOR-NAME is correct. This is impractical because there is no way the computer could contain a list of all known possible vendors to check against the name. In a case such as VENDOR-NAME, a program usually is designed to enforce that something is entered into this field. Of course, the user could enter XYZ or type ABC Corporashun, and the computer would have no way of recognizing the error.
VENDOR-STATE could be validated by content. The 51 state abbreviations-- 50 states plus DC--could be put in another file, and when the user entered the state abbreviation, it could be looked up in the state code file. This style of validation is precise and prevents an error in the VENDOR-STATE field.
Other validations fall somewhere between these two. It might be possible to break down the VENDOR-PHONE and check that it contains the correct number of digits. It might even be possible to look up the area code in an area code file, but it is impractical for the computer to verify that the phone number is correct for that vendor, unless the entire phone directory already exists in the computer for a lookup.
A lot of validation of computer data is done by human inspection of the data. Phone numbers, addresses, and names are some examples, but where the data can be validated by the computer, it should be. The more important the data, the more effort should go into the validation.
All data to be put into a computer file should be validated, but only some of the validation can be done by the computer. The rest must be left to a person who will read the report on a file and specify what corrections to make.
Data should be validated by the computer if the validation is easy to perform, if the data is critical, or if the volume of data is large. Easy validations usually can be coded into the program quickly. They should not be overlooked. The fact that they are easy to do doesn't mean they are unimportant.
Suppose that in a bill-paying system, a design decision is made that vendor numbers will start at 10,000. In the program, this validation becomes the following:
001100 IF VENDOR-NUMBER < 10000 001200 DISPLAY 001300 "VENDOR NUMBER MUST NOT BE LESS THAN 10000".
Critical data can become trickier to validate. A mailing-list company that advertises that it has the most accurate mailing lists might go to the trouble of creating a zip-code file with all the zip codes in the United States and the state for each zip code. When a data-entry operator enters a state and zip code in the main file, the zip code might be looked up in the zip-code file and the state for that zip code would be compared to the state that the operator entered. An error message would be provided if the state and zip code did not match.
Large amounts of data are important to validate because it becomes harder for a human to read all the information and check it. The same mailing-list company might go so far as to include a spelling check on the address fields that would warn the operator that there might be a spelling error in the address, and then ask the operator to double-check it.
DO/DON'T:
DO use the computer to validate data, and write validation routines into your program wherever and whenever possible.DON'T neglect to validate critical data in your program.
Every maintenance program (a program that enables you to add, change, and delete records) for a file--especially add and change modes--must include the full validation for each field that requires validation.
TIP: Always validate data before it is written to the file.
If you are working with a file that contains invalid data, you should track down the program or programs that are putting invalid data in the file and correct the programs. Then correct the data in the file, either by changing the records in change mode or by writing a program that tests all the fields for valid data and reports on the faulty records. The faulty records then can be corrected, possibly with a separate program to do the correction.
You make a serious mistake the first time you see a record or field containing invalid data if you then try to modify a report or any other program to "work around" the invalid data. You have left the error in the data file. The fix in your program has to be made to all other programs that access the file, and the program causing the error in the first place will continue to generate errors.
DO/DON'T:
DO track down programs that are putting invalid data into files and correct them.DON'T attempt to work around bad data.
DO correct bad data in a data file.
Required entry validation is the simplest type of validation. It is used to ensure that a user fills in a field that must be filled in. For this example, you are creating a new file of state codes. Listings 15.2 and 15.3 are the logical and physical descriptions of a state code file that contains the two-character codes for state abbreviations and the names of the states.
000100*-------------------------------- 000200* FDSTATE.CBL 000300* Primary Key - STATE-CODE 000400* NAME is required 000500* NAME and CODE should be upper case 000600*-------------------------------- 000700 FD STATE-FILE 000800 LABEL RECORDS ARE STANDARD. 000900 01 STATE-RECORD. 001000 05 STATE-CODE PIC X(2). 001100 05 STATE-NAME PIC X(20). 001200
000100*-------------------------------- 000200* SLSTATE.CBL 000300*-------------------------------- 000400 SELECT STATE-FILE 000500 ASSIGN TO "STATE" 000600 ORGANIZATION IS INDEXED 000700 RECORD KEY IS STATE-CODE 000800 ACCESS MODE IS DYNAMIC. 000900
Listing 15.4 is similar to vndbld01.cbl. It simply opens output for a new state file. Code the SELECT and FD for the state (shown in Listings 15.2 and 15.3), and then code, compile, and run Listing 15.4, stcbld01.cbl.
000100 IDENTIFICATION DIVISION. 000200 PROGRAM-ID. STCBLD01. 000300*------------------------------------------------ 000400* Create an Empty State Code File. 000500*------------------------------------------------ 000600 ENVIRONMENT DIVISION. 000700 INPUT-OUTPUT SECTION. 000800 FILE-CONTROL. 000900 001000 COPY "SLSTATE.CBL". 001100 001200 DATA DIVISION. 001300 FILE SECTION. 001400 001500 COPY "FDSTATE.CBL". 001600 001700 WORKING-STORAGE SECTION. 001800 001900 PROCEDURE DIVISION. 002000 PROGRAM-BEGIN. 002100 OPEN OUTPUT STATE-FILE. 002200 CLOSE STATE-FILE. 002300 002400 PROGRAM-DONE. 002500 STOP RUN.
Listing 15.5, stcmnt01.cbl, is a simple maintenance program that incorporates add, change, inquire, and delete modes in one program, and it is similar to vndmnt01.cbl.
000100 IDENTIFICATION DIVISION. 000200 PROGRAM-ID. STCMNT01. 000300*-------------------------------- 000400* Add, Change, Inquire and Delete 000500* for the State Code. 000600*-------------------------------- 000700 ENVIRONMENT DIVISION. 000800 INPUT-OUTPUT SECTION. 000900 FILE-CONTROL. 001000 001100 COPY "SLSTATE.CBL". 001200 001300 DATA DIVISION. 001400 FILE SECTION. 001500 001600 COPY "FDSTATE.CBL". 001700 001800 WORKING-STORAGE SECTION. 001900 002000 77 MENU-PICK PIC 9. 002100 88 MENU-PICK-IS-VALID VALUES 0 THRU 4. 002200 002300 77 THE-MODE PIC X(7). 002400 77 OK-TO-DELETE PIC X. 002500 77 RECORD-FOUND PIC X. 002600 77 WHICH-FIELD PIC 9. 002700 002800 002900 003000 003100 003200 003300 PROCEDURE DIVISION. 003400 PROGRAM-BEGIN. 003500 PERFORM OPENING-PROCEDURE. 003600 PERFORM MAIN-PROCESS. 003700 PERFORM CLOSING-PROCEDURE. 003800 003900 PROGRAM-DONE. 004000 STOP RUN. 004100 004200 OPENING-PROCEDURE. 004300 OPEN I-O STATE-FILE. 004400 004500 CLOSING-PROCEDURE. 004600 CLOSE STATE-FILE. 004700 004800 004900 MAIN-PROCESS. 005000 PERFORM GET-MENU-PICK. 005100 PERFORM MAINTAIN-THE-FILE 005200 UNTIL MENU-PICK = 0. 005300 005400*-------------------------------- 005500* MENU 005600*-------------------------------- 005700 GET-MENU-PICK. 005800 PERFORM DISPLAY-THE-MENU. 005900 PERFORM ACCEPT-MENU-PICK. 006000 PERFORM RE-ACCEPT-MENU-PICK 006100 UNTIL MENU-PICK-IS-VALID. 006200 006300 DISPLAY-THE-MENU. 006400 PERFORM CLEAR-SCREEN. 006500 DISPLAY " PLEASE SELECT:". 006600 DISPLAY " ". 006700 DISPLAY " 1. ADD RECORDS". 006800 DISPLAY " 2. CHANGE A RECORD". 006900 DISPLAY " 3. LOOK UP A RECORD". 007000 DISPLAY " 4. DELETE A RECORD". 007100 DISPLAY " ". 007200 DISPLAY " 0. EXIT". 007300 PERFORM SCROLL-LINE 8 TIMES. 007400 007500 ACCEPT-MENU-PICK. 007600 DISPLAY "YOUR CHOICE (0-4)?". 007700 ACCEPT MENU-PICK. 007800 007900 RE-ACCEPT-MENU-PICK. 008000 DISPLAY "INVALID SELECTION - PLEASE RE-TRY.". 008100 PERFORM ACCEPT-MENU-PICK. 008200 008300 CLEAR-SCREEN. 008400 PERFORM SCROLL-LINE 25 TIMES. 008500 008600 SCROLL-LINE. 008700 DISPLAY " ". 008800 008900 MAINTAIN-THE-FILE. 009000 PERFORM DO-THE-PICK. 009100 PERFORM GET-MENU-PICK. 009200 009300 DO-THE-PICK. 009400 IF MENU-PICK = 1 009500 PERFORM ADD-MODE 009600 ELSE 009700 IF MENU-PICK = 2 009800 PERFORM CHANGE-MODE 009900 ELSE 010000 IF MENU-PICK = 3 010100 PERFORM INQUIRE-MODE 010200 ELSE 010300 IF MENU-PICK = 4 010400 PERFORM DELETE-MODE. 010500 010600*-------------------------------- 010700* ADD 010800*-------------------------------- 010900 ADD-MODE. 011000 MOVE "ADD" TO THE-MODE. 011100 PERFORM GET-NEW-STATE-CODE. 011200 PERFORM ADD-RECORDS 011300 UNTIL STATE-CODE = "ZZ". 011400 011500 GET-NEW-STATE-CODE. 011600 PERFORM INIT-STATE-RECORD. 011700 PERFORM ENTER-STATE-CODE. 011800 MOVE "Y" TO RECORD-FOUND. 011900 PERFORM FIND-NEW-STATE-RECORD 012000 UNTIL RECORD-FOUND = "N" OR 012100 STATE-CODE = "ZZ". 012200 012300 FIND-NEW-STATE-RECORD. 012400 PERFORM READ-STATE-RECORD. 012500 IF RECORD-FOUND = "Y" 012600 DISPLAY "RECORD ALREADY ON FILE" 012700 PERFORM ENTER-STATE-CODE. 012800 012900 ADD-RECORDS. 013000 PERFORM ENTER-REMAINING-FIELDS. 013100 PERFORM WRITE-STATE-RECORD. 013200 PERFORM GET-NEW-STATE-CODE. 013300 013400 ENTER-REMAINING-FIELDS. 013500 PERFORM ENTER-STATE-NAME. 013600 013700*-------------------------------- 013800* CHANGE 013900*-------------------------------- 014000 CHANGE-MODE. 014100 MOVE "CHANGE" TO THE-MODE. 014200 PERFORM GET-STATE-RECORD. 014300 PERFORM CHANGE-RECORDS 014400 UNTIL STATE-CODE = "ZZ". 014500 014600 CHANGE-RECORDS. 014700 PERFORM GET-FIELD-TO-CHANGE. 014800 PERFORM CHANGE-ONE-FIELD 014900 UNTIL WHICH-FIELD = ZERO. 015000 015100 015200 PERFORM GET-STATE-RECORD. 015300 015400 GET-FIELD-TO-CHANGE. 015500 PERFORM DISPLAY-ALL-FIELDS. 015600 PERFORM ASK-WHICH-FIELD. 015700 015800 ASK-WHICH-FIELD. 015900 PERFORM ACCEPT-WHICH-FIELD. 016000 PERFORM RE-ACCEPT-WHICH-FIELD 016100 UNTIL WHICH-FIELD NOT > 1. 016200 016300 016400 ACCEPT-WHICH-FIELD. 016500 DISPLAY "ENTER THE NUMBER OF THE FIELD". 016600 DISPLAY "TO CHANGE (1) OR 0 TO EXIT". 016700 ACCEPT WHICH-FIELD. 016800 016900 RE-ACCEPT-WHICH-FIELD. 017000 DISPLAY "INVALID ENTRY". 017100 PERFORM ACCEPT-WHICH-FIELD. 017200 017300 CHANGE-ONE-FIELD. 017400 PERFORM CHANGE-THIS-FIELD. 017500 PERFORM GET-FIELD-TO-CHANGE. 017600 017700 CHANGE-THIS-FIELD. 017800 IF WHICH-FIELD = 1 017900 PERFORM ENTER-STATE-NAME. 018000 018100 PERFORM REWRITE-STATE-RECORD. 018200 018300*-------------------------------- 018400* INQUIRE 018500*-------------------------------- 018600 INQUIRE-MODE. 018700 MOVE "DISPLAY" TO THE-MODE. 018800 PERFORM GET-STATE-RECORD. 018900 PERFORM INQUIRE-RECORDS 019000 UNTIL STATE-CODE = "ZZ". 019100 019200 INQUIRE-RECORDS. 019300 PERFORM DISPLAY-ALL-FIELDS. 019400 PERFORM GET-STATE-RECORD. 019500 019600*-------------------------------- 019700* DELETE 019800*-------------------------------- 019900 DELETE-MODE. 020000 MOVE "DELETE" TO THE-MODE. 020100 PERFORM GET-STATE-RECORD. 020200 PERFORM DELETE-RECORDS 020300 UNTIL STATE-CODE = "ZZ". 020400 020500 DELETE-RECORDS. 020600 PERFORM DISPLAY-ALL-FIELDS. 020700 020800 PERFORM ASK-OK-TO-DELETE 020900 IF OK-TO-DELETE = "Y" 021000 PERFORM DELETE-STATE-RECORD. 021100 021200 PERFORM GET-STATE-RECORD. 021300 021400 ASK-OK-TO-DELETE. 021500 PERFORM ACCEPT-OK-TO-DELETE. 021600 PERFORM RE-ACCEPT-OK-TO-DELETE 021700 UNTIL OK-TO-DELETE = "Y" OR "N". 021800 021900 ACCEPT-OK-TO-DELETE. 022000 DISPLAY "DELETE THIS RECORD (Y/N)?". 022100 ACCEPT OK-TO-DELETE. 022200 IF OK-TO-DELETE = "y" 022300 MOVE "Y" TO OK-TO-DELETE. 022400 IF OK-TO-DELETE = "n" 022500 MOVE "N" TO OK-TO-DELETE. 022600 022700 RE-ACCEPT-OK-TO-DELETE. 022800 DISPLAY "YOU MUST ENTER YES OR NO". 022900 PERFORM ACCEPT-OK-TO-DELETE. 023000 023100*-------------------------------- 023200* Routines shared by all modes 023300*-------------------------------- 023400 INIT-STATE-RECORD. 023500 MOVE SPACE TO STATE-RECORD. 023600 023700 ENTER-STATE-CODE. 023800 PERFORM ACCEPT-STATE-CODE. 023900 PERFORM RE-ACCEPT-STATE-CODE 024000 UNTIL STATE-CODE NOT = SPACE. 024100 024200 ACCEPT-STATE-CODE. 024300 DISPLAY " ". 024400 DISPLAY "ENTER STATE CODE OF THE STATE" . 024500 DISPLAY "TO " THE-MODE 024600 "(2 UPPER CASE CHARACTERS)". 024700 DISPLAY "ENTER ZZ TO STOP ENTRY". 024800 ACCEPT STATE-CODE. 024900 025000 025100 025200 025300 025400 RE-ACCEPT-STATE-CODE. 025500 DISPLAY "STATE CODE MUST BE ENTERED". 025600 PERFORM ACCEPT-STATE-CODE. 025700 025800 GET-STATE-RECORD. 025900 PERFORM INIT-STATE-RECORD. 026000 PERFORM ENTER-STATE-CODE. 026100 MOVE "N" TO RECORD-FOUND. 026200 PERFORM FIND-STATE-RECORD 026300 UNTIL RECORD-FOUND = "Y" OR 026400 STATE-CODE = "ZZ". 026500 026600*-------------------------------- 026700* Routines shared Add and Change 026800*-------------------------------- 026900 FIND-STATE-RECORD. 027000 PERFORM READ-STATE-RECORD. 027100 IF RECORD-FOUND = "N" 027200 DISPLAY "RECORD NOT FOUND" 027300 PERFORM ENTER-STATE-CODE. 027400 027500 ENTER-STATE-NAME. 027600 PERFORM ACCEPT-STATE-NAME. 027700 PERFORM RE-ACCEPT-STATE-NAME 027800 UNTIL STATE-NAME NOT = SPACES. 027900 028000 ACCEPT-STATE-NAME. 028100 DISPLAY "ENTER STATE NAME". 028200 ACCEPT STATE-NAME. 028300 028400 028500 028600 028700 028800 RE-ACCEPT-STATE-NAME. 028900 DISPLAY "STATE NAME MUST BE ENTERED". 029000 PERFORM ACCEPT-STATE-NAME. 029100 029200*-------------------------------- 029300* Routines shared by Change, 029400* Inquire and Delete 029500*-------------------------------- 029600 DISPLAY-ALL-FIELDS. 029700 DISPLAY " ". 029800 PERFORM DISPLAY-STATE-CODE. 029900 PERFORM DISPLAY-STATE-NAME. 030000 DISPLAY " ". 030100 030200 DISPLAY-STATE-CODE. 030300 DISPLAY " STATE CODE: " STATE-CODE. 030400 030500 DISPLAY-STATE-NAME. 030600 DISPLAY "1. STATE NAME: " STATE-NAME. 030700 030800*-------------------------------- 030900* File I-O Routines 031000*-------------------------------- 031100 READ-STATE-RECORD. 031200 MOVE "Y" TO RECORD-FOUND. 031300 READ STATE-FILE RECORD 031400 INVALID KEY 031500 MOVE "N" TO RECORD-FOUND. 031600 031700*or READ STATE-FILE RECORD WITH LOCK 031800* INVALID KEY 031900* MOVE "N" TO RECORD-FOUND. 032000 032100*or READ STATE-FILE RECORD WITH HOLD 032200* INVALID KEY 032300* MOVE "N" TO RECORD-FOUND. 032400 032500 WRITE-STATE-RECORD. 032600 WRITE STATE-RECORD 032700 INVALID KEY 032800 DISPLAY "RECORD ALREADY ON FILE". 032900 033000 REWRITE-STATE-RECORD. 033100 REWRITE STATE-RECORD 033200 INVALID KEY 033300 DISPLAY "ERROR REWRITING STATE RECORD". 033400 033500 DELETE-STATE-RECORD. 033600 DELETE STATE-FILE RECORD 033700 INVALID KEY 033800 DISPLAY "ERROR DELETING STATE RECORD". 033900
The following output examples of stcmnt01.cbl include the start-up menu, an example of entering a blank state code, a correct state code, and a state code and state name in lowercase:
OUTPUT:
PLEASE SELECT: 1. ADD RECORDS 2. CHANGE A RECORD 3. LOOK UP A RECORD 4. DELETE A RECORD 0. EXIT YOUR CHOICE (0-4)?
OUTPUT:
ENTER STATE CODE OF THE STATE TO ADD (2 UPPER CASE CHARACTERS) ENTER ZZ TO STOP ENTRY
(User pressed Enter here with no entry.)
STATE CODE MUST BE ENTERED ENTER STATE CODE OF THE STATE TO ADD (2 UPPER CASE CHARACTERS) ENTER ZZ TO STOP ENTRY LA ENTER STATE NAME LOUISIANA ENTER STATE CODE OF THE STATE TO ADD (2 UPPER CASE CHARACTERS) ENTER ZZ TO STOP ENTRY
ANALYSIS: stcmnt01.cbl differs from vndmnt01.cbl in one main area: validation. In vndmnt01.cbl, the user can enter any values, and even enter no values. At lines 023700 through 025700, the ENTER-STATE-CODE routine has been broken into two separate routines: ACCEPT-STATE-CODE to enter the data, and RE-ACCEPT-STATE-CODE designed to force the user to enter something. At lines 023900 and 024000, RE-ACCEPT-STATE-CODE is performed until STATE-CODE NOT = SPACES. The reaccept logic is executed only if the user has entered spaces, which are invalid for this field. The RE-ACCEPT-STATE-CODE routine at line 025400 displays an error message and then performs the original routine to get the data--ACCEPT-STATE-CODE. The RE-ACCEPT-STATE-CODE loop will continue until the user's entry is valid. The identical logic is used at lines 027500 through 029100 for the state name.
The STATE-CODE is an alphanumeric field, so instead of entering zero to end data entry, the user is asked to enter "ZZ" to end the entry. "ZZ" is not a valid state code, so it can be used.
The style of entry and validation of fields used in stcmnt01.cbl can be reduced to a simple formula. This formula is best expressed in the pseudocode shown in Listing 15.6. Note that I have chosen to include periods in this example of pseudocode. Again, the style to use in pseudocode is your choice unless your company has a standard specification on pseudocode style.
enter-the-data. PERFORM accept-the-data. PERFORM re-accept-the-data. UNTIL the-data is valid. accept-the-data. DISPLAY a-prompt. ACCEPT the-data. re-accept-the-data. DISPLAY error-message. PERFORM accept-the-data.
Figure 15.1 compares the ENTER-STATE-NAME routine to the pseudocode for a standard field-entry routine.
Figure 15.1.
ENTER-STATE-NAME as a standard field-entry routine.
Figure 15.2 compares the ENTER-STATE-CODE routine to the pseudocode for a standard field-entry routine. In ACCEPT-STATE-CODE, the logic that corresponds to DISPLAY a-prompt extends over several lines.
Figure 15.2.
ENTER-STATE-CODE as a standard field-entry routine.
This method of data entry does not have to be limited to fields for the file; it can be used for any field that the user must enter or any question that the user is asked. Figure 15.3 shows that ASK-WHICH-FIELD from stcmnt01.cbl also is based on the standard field-entry pattern.
Figure 15.3.
ASK-WHICH-FIELD as a standard field-entry routine.
Listing 15.6, the pseudocode for a standard field-entry routine, is missing one critical step that is included in Listing 15.7.
enter-the-data. PERFORM accept-the-data. PERFORM re-accept-the-data. UNTIL the-data is valid. accept-the-data. DISPLAY a-prompt. ACCEPT the-data. edit-check-the-data. re-accept-the-data. DISPLAY error-message. PERFORM accept-the-data.
ANALYSIS: Within accept-the-data, a line has been added to edit-check-the-data. This line actually represents two separate actions:
Editing and checking are combined into the single line edit-check-the-data because of the ways in which editing and checking can occur in a program. Some data is edited but not validated (required)--for example, a field that is not required (no validation) but that must be edited (changed) to convert it to uppercase. Some data is validated but not edited--for example, a required phone number field where the data is required but is not changed by the program. Some data, such as WHICH-FIELD, is neither edited nor validated.
Some data receives a bit of both editing and validation. A date field might be entered by the user as "1/7/97", and this format is hard to validate. The first step might be to edit the data by converting it to a standard format such as "19970107". This standard format can be validated as a date; then the field might be edited again and converted to "01/07/97". Because there is no ironclad rule such as "first you edit and then you check," edit-check-the-data is combined into a single line.
ASK-OK-TO-DELETE in Figure 15.4 also is a standard field-entry routine, but this is an example of a routine that uses the edit-check-the-data section of the pseudocode to edit the data, by converting y and n to their uppercase versions.
Figure 15.4.
ASK-OK-TO-DELETE as a standard field-entry routine.
The GET-MENU-PICK routine shown in Figure 15.5 is a standard field-entry routine with a slight variation. The prompt for the menu field actually is the whole menu followed by "YOUR CHOICE (0-4)?". This is a long and unnecessary prompt to repeat every time the user makes a mistake, so only "YOUR CHOICE (0-4)?" is repeated. This is done by making part of the prompt a separate paragraph, DISPLAY-THE-MENU, and then displaying it once at the beginning of GET-MENU-PICK.
Figure 15.5.
GET-MENU-PICK as a standard field-entry routine with a slight variation
to handle the large prompt for the field.
You can use this standard field-entry routine as a formula for entering and testing or editing any field.
It is important to understand that the standard field-entry routine in Listing 15.7 and other versions of it elsewhere are just a design. It is not a language requirement, and each COBOL site will have different requirements on how to formulate the steps of a standard field-entry routine.
One oddity develops from stcmnt01.cbl, shown in the following output example of changing the record for CA (California):
OUTPUT:
PLEASE SELECT: 1. ADD RECORDS 2. CHANGE A RECORD 3. LOOK UP A RECORD 4. DELETE A RECORD 0. EXIT YOUR CHOICE (0-4)? 2 ENTER STATE CODE OF THE STATE TO CHANGE (2 UPPER CASE CHARACTERS) ENTER ZZ TO STOP ENTRY CA STATE CODE: CA 1. STATE NAME: CALIFORNIA ENTER THE NUMBER OF THE FIELD TO CHANGE (1) OR 0 TO EXIT 1 ENTER STATE NAME CALIFORNIA STATE CODE: CA 1. STATE NAME: CALIFORNIA ENTER THE NUMBER OF THE FIELD TO CHANGE (1) OR 0 TO EXIT
ANALYSIS: Although there is only one modifiable field in the state code record, the user is asked to enter the number of the field to change. In vndmnt01.cbl, the user had the option of up to eight different fields to change. In stcmnt01.cbl, the STATE-CODE is the primary key that cannot be changed, so the user is left with only one field, STATE-NAME, that can be changed.
You can avoid this problem in the data entry by using the changes shown in Listing 15.8, a fragment from stcmnt02.cbl.
014600 CHANGE-RECORDS. 014700 PERFORM GET-FIELD-TO-CHANGE. 014800* PERFORM CHANGE-ONE-FIELD 014900* UNTIL WHICH-FIELD = ZERO. 015000 PERFORM CHANGE-ONE-FIELD. 015100 015200 PERFORM GET-STATE-RECORD. 015300 015400 GET-FIELD-TO-CHANGE. 015500 PERFORM DISPLAY-ALL-FIELDS. 015600 PERFORM ASK-WHICH-FIELD. 015700 015800 ASK-WHICH-FIELD. 015900* PERFORM ACCEPT-WHICH-FIELD. 016000* PERFORM RE-ACCEPT-WHICH-FIELD 016100* UNTIL WHICH-FIELD NOT > 1. 016200 MOVE 1 TO WHICH-FIELD. 016300 016400*ACCEPT-WHICH-FIELD. 016500* DISPLAY "ENTER THE NUMBER OF THE FIELD". 016600* DISPLAY "TO CHANGE (1) OR 0 TO EXIT". 016700* ACCEPT WHICH-FIELD. 016800* 016900*RE-ACCEPT-WHICH-FIELD. 017000* DISPLAY "INVALID ENTRY". 017100* PERFORM ACCEPT-WHICH-FIELD. 017200 017300 CHANGE-ONE-FIELD. 017400 PERFORM CHANGE-THIS-FIELD. 017500* PERFORM GET-FIELD-TO-CHANGE. 017600 017700 CHANGE-THIS-FIELD. 017800 IF WHICH-FIELD = 1 017900 PERFORM ENTER-STATE-NAME. 018000 018100 PERFORM REWRITE-STATE-RECORD. 018200
The modified output of stcmnt02.cbl skips asking the user for the field to enter and immediately asks for the new state name. In this example, the user re-enters the state name because of an error in the original data entry (CALIFORNIA is misspelled as CALIFORNIB).
OUTPUT:
PLEASE SELECT: 1. ADD RECORDS 2. CHANGE A RECORD 3. LOOK UP A RECORD 4. DELETE A RECORD 0. EXIT YOUR CHOICE (0-4)? 2 ENTER STATE CODE OF THE STATE TO CHANGE (2 UPPER CASE CHARACTERS) ENTER ZZ TO STOP ENTRY CA STATE CODE: CA 1. STATE NAME: CALIFORNIB ENTER STATE NAME CALIFORNIA ENTER STATE CODE OF THE STATE TO CHANGE (2 UPPER CASE CHARACTERS) ENTER ZZ TO STOP ENTRY
ANALYSIS: This is a modification to stcmnt01.cbl that changes the program so that CHANGE-ONE-FIELD is executed only once, and ASK-WHICH-FIELD is no longer entered by the user but is set to 1 by the computer. The original code is left in but commented out, and the new code appears at lines 015000 and 016200.
Copy stcmnt01.cbl to stcmnt02.cbl and make the changes to this area of the program; then compile and run the program.
Printing the state code is fairly simple. Figure 15.6 shows the layout chart for a simple state code report.
Figure 15.6.
Layout for the state codes report.
Listing 15.9, stcrpt01.cbl, is a simple report program based on the layout in Figure 15.6.
000100 IDENTIFICATION DIVISION. 000200 PROGRAM-ID. STCRPT01. 000300*-------------------------------- 000400* Report on the STATE File. 000500*-------------------------------- 000600 ENVIRONMENT DIVISION. 000700 INPUT-OUTPUT SECTION. 000800 FILE-CONTROL. 000900 001000 COPY "SLSTATE.CBL". 001100 001200 SELECT PRINTER-FILE 001300 ASSIGN TO PRINTER 001400 ORGANIZATION IS LINE SEQUENTIAL. 001500 001600 DATA DIVISION. 001700 FILE SECTION. 001800 001900 COPY "FDSTATE.CBL". 002000 002100 FD PRINTER-FILE 002200 LABEL RECORDS ARE OMITTED. 002300 01 PRINTER-RECORD PIC X(80). 002400 002500 WORKING-STORAGE SECTION. 002600 002700 01 DETAIL-LINE. 002800 05 PRINT-CODE PIC XX. 002900 05 FILLER PIC XXXX VALUE SPACE. 003000 05 PRINT-NAME PIC X(20). 003100 003200 01 COLUMN-LINE. 003300 05 FILLER PIC X(4) VALUE "CODE". 003400 05 FILLER PIC X(2) VALUE SPACE. 003500 05 FILLER PIC X(4) VALUE "NAME". 003600 003700 01 TITLE-LINE. 003800 05 FILLER PIC X(25) VALUE SPACE. 003900 05 FILLER PIC X(11) 004000 VALUE "STATE CODES". 004100 05 FILLER PIC X(15) VALUE SPACE. 004200 05 FILLER PIC X(5) VALUE "PAGE:". 004300 05 FILLER PIC X(1) VALUE SPACE. 004400 05 PRINT-PAGE-NUMBER PIC ZZZZ9. 004500 004600 77 FILE-AT-END PIC X. 004700 77 LINE-COUNT PIC 999 VALUE ZERO. 004800 77 PAGE-NUMBER PIC 99999 VALUE ZERO. 004900 77 MAXIMUM-LINES PIC 999 VALUE 55. 005000 005100 PROCEDURE DIVISION. 005200 PROGRAM-BEGIN. 005300 005400 PERFORM OPENING-PROCEDURE. 005500 MOVE ZEROES TO LINE-COUNT 005600 PAGE-NUMBER. 005700 005800 PERFORM START-NEW-PAGE. 005900 006000 MOVE "N" TO FILE-AT-END. 006100 PERFORM READ-NEXT-RECORD. 006200 IF FILE-AT-END = "Y" 006300 MOVE "NO RECORDS FOUND" TO PRINTER-RECORD 006400 PERFORM WRITE-TO-PRINTER 006500 ELSE 006600 PERFORM PRINT-STATE-FIELDS 006700 UNTIL FILE-AT-END = "Y". 006800 006900 PERFORM CLOSING-PROCEDURE. 007000 007100 PROGRAM-DONE. 007200 STOP RUN. 007300 007400 OPENING-PROCEDURE. 007500 OPEN I-O STATE-FILE. 007600 OPEN OUTPUT PRINTER-FILE. 007700 007800 CLOSING-PROCEDURE. 007900 CLOSE STATE-FILE. 008000 PERFORM END-LAST-PAGE. 008100 CLOSE PRINTER-FILE. 008200 008300 PRINT-STATE-FIELDS. 008400 IF LINE-COUNT > MAXIMUM-LINES 008500 PERFORM START-NEXT-PAGE. 008600 PERFORM PRINT-THE-RECORD. 008700 PERFORM READ-NEXT-RECORD. 008800 008900 PRINT-THE-RECORD. 009000 MOVE SPACE TO DETAIL-LINE. 009100 MOVE STATE-CODE TO PRINT-CODE. 009200 MOVE STATE-NAME TO PRINT-NAME. 009300 MOVE DETAIL-LINE TO PRINTER-RECORD. 009400 PERFORM WRITE-TO-PRINTER. 009500 009600 READ-NEXT-RECORD. 009700 READ STATE-FILE NEXT RECORD 009800 AT END MOVE "Y" TO FILE-AT-END. 009900 010000 WRITE-TO-PRINTER. 010100 WRITE PRINTER-RECORD BEFORE ADVANCING 1. 010200 ADD 1 TO LINE-COUNT. 010300 010400 LINE-FEED. 010500 MOVE SPACE TO PRINTER-RECORD. 010600 PERFORM WRITE-TO-PRINTER. 010700 010800 START-NEXT-PAGE. 010900 011000 PERFORM END-LAST-PAGE. 011100 PERFORM START-NEW-PAGE. 011200 011300 START-NEW-PAGE. 011400 ADD 1 TO PAGE-NUMBER. 011500 MOVE PAGE-NUMBER TO PRINT-PAGE-NUMBER. 011600 MOVE TITLE-LINE TO PRINTER-RECORD. 011700 PERFORM WRITE-TO-PRINTER. 011800 PERFORM LINE-FEED. 011900 MOVE COLUMN-LINE TO PRINTER-RECORD. 012000 PERFORM WRITE-TO-PRINTER. 012100 PERFORM LINE-FEED. 012200 012300 END-LAST-PAGE. 012400 PERFORM FORM-FEED. 012500 MOVE ZERO TO LINE-COUNT. 012600 012700 FORM-FEED. 012800 MOVE SPACE TO PRINTER-RECORD. 012900 WRITE PRINTER-RECORD BEFORE ADVANCING PAGE.
The example of the output from stcrpt01.cbl follows the organization designed in the printer layout chart:
OUTPUT:
STATE CODES PAGE: 1 CODE NAME AZ ARIZONA CA CALIFORNIA FL FLORIDA LA LOUISIANA NM NEW MEXICO WA WASHINGTON WI WISCONSIN
You still haven't done enough to validate the data in the state code file. Listing 15.2, the FD for the state code file, contained comments indicating that the STATE-CODE and STATE-NAME should both be entered in uppercase. When I described running stcmnt01.cbl, I said that you should enter the values in uppercase, but just ordering you to do it isn't good enough to ensure that the information really is entered in uppercase and stored in the file in uppercase.
It is possible to validate a field and check each character in the field to ensure that they are all uppercase, but it does involve quite a bit of coding. Instead, it is easier to force everything to become uppercase.
Listing 15.10, upper01.cbl, is a short program to demonstrate how to convert data to uppercase.
000100 IDENTIFICATION DIVISION. 000200 PROGRAM-ID. UPPER01. 000300*------------------------------------------------ 000400* Converts input to upper case. 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 UPPER-ALPHA PIC X(26) VALUE 001600 "ABCDEFGHIJKLMNOPQRSTUVWXYZ". 001700 77 LOWER-ALPHA PIC X(26) VALUE 001800 "abcdefghijklmnopqrstuvwxyz". 001900 002000 77 TEST-FIELD PIC X(30) VALUE SPACE. 002100 PROCEDURE DIVISION. 002200 PROGRAM-BEGIN. 002300 PERFORM ENTER-TEST-FIELD. 002400 PERFORM CONVERT-AND-ENTER 002500 UNTIL TEST-FIELD = SPACE. 002600 002700 PROGRAM-DONE. 002800 STOP RUN. 002900 003000 ENTER-TEST-FIELD. 003100 DISPLAY "Enter upper or lower case data". 003200 DISPLAY "Leave blank to end". 003300 ACCEPT TEST-FIELD. 003400 CONVERT-AND-ENTER. 003500 PERFORM CONVERT-TEST-FIELD. 003600 PERFORM ENTER-TEST-FIELD. 003700 003800 CONVERT-TEST-FIELD. 003900 INSPECT TEST-FIELD CONVERTING 004000 LOWER-ALPHA TO UPPER-ALPHA. 004100 DISPLAY TEST-FIELD.
ANALYSIS: This program accepts a 30-character field from the user, converts it to uppercase, and redisplays the converted field below the original. This process continues until the user enters a blank field.
This example uses a new COBOL command--INSPECT CONVERTING. At lines 003900 and 004000, each character in TEST-FIELD is compared to the list of 26 characters in LOWER-ALPHA. If any character is found to match, the character in TEST-FIELD is converted to the corresponding character in UPPER-ALPHA.
The INSPECT CONVERTING command treats all the variables as lists of individual characters. In Listing 15.10, TEST-FIELD is treated as a list of 30 characters to be converted, LOWER-ALPHA is treated as a list of 26 characters to search for in TEST-FIELD, and UPPER-ALPHA is a list of 26 characters to be used as replacements when a match occurs. Both LOWER-ALPHA and UPPER-ALPHA must be the same length.
In this example, INSPECT CONVERTING is used to convert lowercase letters to uppercase letters, but it could be used for any conversion. It happens that UPPER-ALPHA contains the uppercase equivalents of LOWER-ALPHA, but the INSPECT CONVERTING command doesn't care about the content of UPPER-ALPHA. It could contain any 26 characters, numbers, and punctuation marks.
The INSPECT CONVERTING command will perform a character-by-character translation of a field. The syntax is the following:
INSPECT alphanumeric variable CONVERTING compare value TO replace value.
Here is an example:
CONVERT-TO-UPPER. INSPECT DATA-FIELD CONVERTING LOWER-ALPHA TO UPPER-ALPHA
Listing 15.11, stcmnt03.cbl, includes the earlier changes put into stcmnt02.cbl and adds uppercase conversion in the validation routines at lines 025000 through 025200 and 028400 through 028600.
000100 IDENTIFICATION DIVISION. 000200 PROGRAM-ID. STCMNT03. 000300*-------------------------------- 000400* Add, Change, Inquire and Deletes 000500* for the State Code. 000600*-------------------------------- 000700 ENVIRONMENT DIVISION. 000800 INPUT-OUTPUT SECTION. 000900 FILE-CONTROL. 001000 001100 COPY "SLSTATE.CBL". 001200 001300 DATA DIVISION. 001400 FILE SECTION. 001500 001600 COPY "FDSTATE.CBL". 001700 001800 WORKING-STORAGE SECTION. 001900 002000 77 MENU-PICK PIC 9. 002100 88 MENU-PICK-IS-VALID VALUES 0 THRU 4. 002200 002300 77 THE-MODE PIC X(7). 002400 77 OK-TO-DELETE PIC X. 002500 77 RECORD-FOUND PIC X. 002600 77 WHICH-FIELD PIC 9. 002700 002800 77 UPPER-ALPHA PIC X(26) VALUE 002900 "ABCDEFGHIJKLMNOPQRSTUVWXYZ". 003000 77 LOWER-ALPHA PIC X(26) VALUE 003100 "abcdefghijklmnopqrstuvwxyz". 003200 003300 PROCEDURE DIVISION. 003400 PROGRAM-BEGIN. 003500 PERFORM OPENING-PROCEDURE. 003600 PERFORM MAIN-PROCESS. 003700 PERFORM CLOSING-PROCEDURE. 003800 003900 PROGRAM-DONE. 004000 STOP RUN. 004100 004200 OPENING-PROCEDURE. 004300 OPEN I-O STATE-FILE. 004400 004500 CLOSING-PROCEDURE. 004600 CLOSE STATE-FILE. 004700 004800 004900 MAIN-PROCESS. 005000 PERFORM GET-MENU-PICK. 005100 PERFORM MAINTAIN-THE-FILE 005200 UNTIL MENU-PICK = 0. 005300 005400*-------------------------------- 005500* MENU 005600*-------------------------------- 005700 GET-MENU-PICK. 005800 PERFORM DISPLAY-THE-MENU. 005900 PERFORM ACCEPT-MENU-PICK. 006000 PERFORM RE-ACCEPT-MENU-PICK 006100 UNTIL MENU-PICK-IS-VALID. 006200 006300 DISPLAY-THE-MENU. 006400 PERFORM CLEAR-SCREEN. 006500 DISPLAY " PLEASE SELECT:". 006600 DISPLAY " ". 006700 DISPLAY " 1. ADD RECORDS". 006800 DISPLAY " 2. CHANGE A RECORD". 006900 DISPLAY " 3. LOOK UP A RECORD". 007000 DISPLAY " 4. DELETE A RECORD". 007100 DISPLAY " ". 007200 DISPLAY " 0. EXIT". 007300 PERFORM SCROLL-LINE 8 TIMES. 007400 007500 ACCEPT-MENU-PICK. 007600 DISPLAY "YOUR CHOICE (0-4)?". 007700 ACCEPT MENU-PICK. 007800 007900 RE-ACCEPT-MENU-PICK. 008000 DISPLAY "INVALID SELECTION - PLEASE RE-TRY.". 008100 PERFORM ACCEPT-MENU-PICK. 008200 008300 CLEAR-SCREEN. 008400 PERFORM SCROLL-LINE 25 TIMES. 008500 008600 SCROLL-LINE. 008700 DISPLAY " ". 008800 008900 MAINTAIN-THE-FILE. 009000 PERFORM DO-THE-PICK. 009100 PERFORM GET-MENU-PICK. 009200 009300 DO-THE-PICK. 009400 IF MENU-PICK = 1 009500 PERFORM ADD-MODE 009600 ELSE 009700 IF MENU-PICK = 2 009800 PERFORM CHANGE-MODE 009900 ELSE 010000 IF MENU-PICK = 3 010100 PERFORM INQUIRE-MODE 010200 ELSE 010300 IF MENU-PICK = 4 010400 PERFORM DELETE-MODE. 010500 010600*-------------------------------- 010700* ADD 010800*-------------------------------- 010900 ADD-MODE. 011000 MOVE "ADD" TO THE-MODE. 011100 PERFORM GET-NEW-STATE-CODE. 011200 PERFORM ADD-RECORDS 011300 UNTIL STATE-CODE = "ZZ". 011400 011500 GET-NEW-STATE-CODE. 011600 PERFORM INIT-STATE-RECORD. 011700 PERFORM ENTER-STATE-CODE. 011800 MOVE "Y" TO RECORD-FOUND. 011900 PERFORM FIND-NEW-STATE-RECORD 012000 UNTIL RECORD-FOUND = "N" OR 012100 STATE-CODE = "ZZ". 012200 012300 FIND-NEW-STATE-RECORD. 012400 PERFORM READ-STATE-RECORD. 012500 IF RECORD-FOUND = "Y" 012600 DISPLAY "RECORD ALREADY ON FILE" 012700 PERFORM ENTER-STATE-CODE. 012800 012900 ADD-RECORDS. 013000 PERFORM ENTER-REMAINING-FIELDS. 013100 PERFORM WRITE-STATE-RECORD. 013200 PERFORM GET-NEW-STATE-CODE. 013300 013400 ENTER-REMAINING-FIELDS. 013500 PERFORM ENTER-STATE-NAME. 013600 013700*-------------------------------- 013800* CHANGE 013900*-------------------------------- 014000 CHANGE-MODE. 014100 MOVE "CHANGE" TO THE-MODE. 014200 PERFORM GET-STATE-RECORD. 014300 PERFORM CHANGE-RECORDS 014400 UNTIL STATE-CODE = "ZZ". 014500 014600 CHANGE-RECORDS. 014700 PERFORM GET-FIELD-TO-CHANGE. 014800* PERFORM CHANGE-ONE-FIELD 014900* UNTIL WHICH-FIELD = ZERO. 015000 PERFORM CHANGE-ONE-FIELD. 015100 015200 PERFORM GET-STATE-RECORD. 015300 015400 GET-FIELD-TO-CHANGE. 015500 PERFORM DISPLAY-ALL-FIELDS. 015600 PERFORM ASK-WHICH-FIELD. 015700 015800 ASK-WHICH-FIELD. 015900* PERFORM ACCEPT-WHICH-FIELD. 016000* PERFORM RE-ACCEPT-WHICH-FIELD 016100* UNTIL WHICH-FIELD NOT > 1. 016200 MOVE 1 TO WHICH-FIELD. 016300 016400*ACCEPT-WHICH-FIELD. 016500* DISPLAY "ENTER THE NUMBER OF THE FIELD". 016600* DISPLAY "TO CHANGE (1) OR 0 TO EXIT". 016700* ACCEPT WHICH-FIELD. 016800* 016900*RE-ACCEPT-WHICH-FIELD. 017000* DISPLAY "INVALID ENTRY". 017100* PERFORM ACCEPT-WHICH-FIELD. 017200 017300 CHANGE-ONE-FIELD. 017400 PERFORM CHANGE-THIS-FIELD. 017500* PERFORM GET-FIELD-TO-CHANGE. 017600 017700 CHANGE-THIS-FIELD. 017800 IF WHICH-FIELD = 1 017900 PERFORM ENTER-STATE-NAME. 018000 018100 PERFORM REWRITE-STATE-RECORD. 018200 018300*-------------------------------- 018400* INQUIRE 018500*-------------------------------- 018600 INQUIRE-MODE. 018700 MOVE "DISPLAY" TO THE-MODE. 018800 PERFORM GET-STATE-RECORD. 018900 PERFORM INQUIRE-RECORDS 019000 UNTIL STATE-CODE = "ZZ". 019100 019200 INQUIRE-RECORDS. 019300 PERFORM DISPLAY-ALL-FIELDS. 019400 PERFORM GET-STATE-RECORD. 019500 019600*-------------------------------- 019700* DELETE 019800*-------------------------------- 019900 DELETE-MODE. 020000 MOVE "DELETE" TO THE-MODE. 020100 PERFORM GET-STATE-RECORD. 020200 PERFORM DELETE-RECORDS 020300 UNTIL STATE-CODE = "ZZ". 020400 020500 DELETE-RECORDS. 020600 PERFORM DISPLAY-ALL-FIELDS. 020700 020800 PERFORM ASK-OK-TO-DELETE 020900 IF OK-TO-DELETE = "Y" 021000 PERFORM DELETE-STATE-RECORD. 021100 021200 PERFORM GET-STATE-RECORD. 021300 021400 ASK-OK-TO-DELETE. 021500 PERFORM ACCEPT-OK-TO-DELETE. 021600 PERFORM RE-ACCEPT-OK-TO-DELETE 021700 UNTIL OK-TO-DELETE = "Y" OR "N". 021800 021900 ACCEPT-OK-TO-DELETE. 022000 DISPLAY "DELETE THIS RECORD (Y/N)?". 022100 ACCEPT OK-TO-DELETE. 022200 022300 INSPECT OK-TO-DELETE 022400 CONVERTING LOWER-ALPHA 022500 TO UPPER-ALPHA. 022600 022700 RE-ACCEPT-OK-TO-DELETE. 022800 DISPLAY "YOU MUST ENTER YES OR NO". 022900 PERFORM ACCEPT-OK-TO-DELETE. 023000 023100*-------------------------------- 023200* Routines shared by all modes 023300*-------------------------------- 023400 INIT-STATE-RECORD. 023500 MOVE SPACE TO STATE-RECORD. 023600 023700 ENTER-STATE-CODE. 023800 PERFORM ACCEPT-STATE-CODE. 023900 PERFORM RE-ACCEPT-STATE-CODE 024000 UNTIL STATE-CODE NOT = SPACE. 024100 024200 ACCEPT-STATE-CODE. 024300 DISPLAY " ". 024400 DISPLAY "ENTER STATE CODE OF THE STATE" . 024500 DISPLAY "TO " THE-MODE 024600 "(2 UPPER CASE CHARACTERS)". 024700 DISPLAY "ENTER ZZ TO STOP ENTRY". 024800 ACCEPT STATE-CODE. 024900 025000 INSPECT STATE-CODE 025100 CONVERTING LOWER-ALPHA 025200 TO UPPER-ALPHA. 025300 025400 RE-ACCEPT-STATE-CODE. 025500 DISPLAY "STATE CODE MUST BE ENTERED". 025600 PERFORM ACCEPT-STATE-CODE. 025700 025800 GET-STATE-RECORD. 025900 PERFORM INIT-STATE-RECORD. 026000 PERFORM ENTER-STATE-CODE. 026100 MOVE "N" TO RECORD-FOUND. 026200 PERFORM FIND-STATE-RECORD 026300 UNTIL RECORD-FOUND = "Y" OR 026400 STATE-CODE = "ZZ". 026500 026600*-------------------------------- 026700* Routines shared Add and Change 026800*-------------------------------- 026900 FIND-STATE-RECORD. 027000 PERFORM READ-STATE-RECORD. 027100 IF RECORD-FOUND = "N" 027200 DISPLAY "RECORD NOT FOUND" 027300 PERFORM ENTER-STATE-CODE. 027400 027500 ENTER-STATE-NAME. 027600 PERFORM ACCEPT-STATE-NAME. 027700 PERFORM RE-ACCEPT-STATE-NAME 027800 UNTIL STATE-NAME NOT = SPACES. 027900 028000 ACCEPT-STATE-NAME. 028100 DISPLAY "ENTER STATE NAME". 028200 ACCEPT STATE-NAME. 028300 028400 INSPECT STATE-NAME 028500 CONVERTING LOWER-ALPHA 028600 TO UPPER-ALPHA. 028700 028800 RE-ACCEPT-STATE-NAME. 028900 DISPLAY "STATE NAME MUST BE ENTERED". 029000 PERFORM ACCEPT-STATE-NAME. 029100 029200*-------------------------------- 029300* Routines shared by Change, 029400* Inquire and Delete 029500*-------------------------------- 029600 DISPLAY-ALL-FIELDS. 029700 DISPLAY " ". 029800 PERFORM DISPLAY-STATE-CODE. 029900 PERFORM DISPLAY-STATE-NAME. 030000 DISPLAY " ". 030100 030200 DISPLAY-STATE-CODE. 030300 DISPLAY " STATE CODE: " STATE-CODE. 030400 030500 DISPLAY-STATE-NAME. 030600 DISPLAY "1. STATE NAME: " STATE-NAME. 030700 030800*-------------------------------- 030900* File I-O Routines 031000*-------------------------------- 031100 READ-STATE-RECORD. 031200 MOVE "Y" TO RECORD-FOUND. 031300 READ STATE-FILE RECORD 031400 INVALID KEY 031500 MOVE "N" TO RECORD-FOUND. 031600 031700*or READ STATE-FILE RECORD WITH LOCK 031800* INVALID KEY 031900* MOVE "N" TO RECORD-FOUND. 032000 032100*or READ STATE-FILE RECORD WITH HOLD 032200* INVALID KEY 032300* MOVE "N" TO RECORD-FOUND. 032400 032500 WRITE-STATE-RECORD. 032600 WRITE STATE-RECORD 032700 INVALID KEY 032800 DISPLAY "RECORD ALREADY ON FILE". 032900 033000 REWRITE-STATE-RECORD. 033100 REWRITE STATE-RECORD 033200 INVALID KEY 033300 DISPLAY "ERROR REWRITING STATE RECORD". 033400 033500 DELETE-STATE-RECORD. 033600 DELETE STATE-FILE RECORD 033700 INVALID KEY 033800 DISPLAY "ERROR DELETING STATE RECORD". 033900
The output of stcmnt03.cbl shows an example of adding fl florida in lowercase, but finding that it is stored in uppercase:
OUTPUT:
PLEASE SELECT: 1. ADD RECORDS 2. CHANGE A RECORD 3. LOOK UP A RECORD 4. DELETE A RECORD 0. EXIT YOUR CHOICE (0-4)? 1 ENTER STATE CODE OF THE STATE TO ADD (2 UPPER CASE CHARACTERS) ENTER ZZ TO STOP ENTRY fl ENTER STATE NAME florida ENTER STATE CODE OF THE STATE TO ADD (2 UPPER CASE CHARACTERS) ENTER ZZ TO STOP ENTRY zz
OUTPUT:
PLEASE SELECT: 1. ADD RECORDS 2. CHANGE A RECORD 3. LOOK UP A RECORD 4. DELETE A RECORD 0. EXIT YOUR CHOICE (0-4)? 3 ENTER STATE CODE OF THE STATE TO DISPLAY(2 UPPER CASE CHARACTERS) ENTER ZZ TO STOP ENTRY fl STATE CODE: FL 1. STATE NAME: FLORIDA ENTER STATE CODE OF THE STATE TO DISPLAY(2 UPPER CASE CHARACTERS) ENTER ZZ TO STOP ENTRY
ANALYSIS: The uppercase conversion is added to the program at lines 002800 through 003100, 025000 though 025200, and 028400 through 028600.
This program also took advantage of the availability of uppercase conversion in the ACCEPT-OK-TO-DELETE routine at line 021900. The tests are replaced with an INSPECT CONVERTING at lines 022300 through 022500.
Code, compile, and run stcmnt03.cbl, and deliberately enter some lowercase values. Then look up the record and you will see that they have been stored in uppercase.
The addition of the conversion to uppercase for the STATE-CODE and the STATE-NAME now takes advantage of the edit-check-the-data section of the pseudocode for a standard field-entry routine. Figures 15.7 and 15.8 compare the new routines to the standard field-entry routine.
Figure 15.7.
ENTER-STATE-CODE with uppercase editing.
Figure 15.8.
ENTER-STATE-NAME with uppercase editing.
There are other ways to convert values to uppercase or lowercase, and these are covered in Bonus Day 5, "Intrinsic Functions and the Year 2000."
As computer systems become larger and larger, the amount of data stored on the computers increases. In today's lesson, you created a file containing state codes, and you entered data into it using various levels of validation. You also learned the following basics:
enter-the-data. PERFORM accept-the-data. PERFORM re-accept-the-data. UNTIL the-data is valid. accept-the-data. DISPLAY a-prompt. ACCEPT the-data. edit-check-the-data. re-accept-the-data. DISPLAY error-message. PERFORM accept-the-data.
2. What COBOL command can be used to convert a field to uppercase?
3. If the following listing converts DATA-FIELD to uppercase, how
would you convert DATA-FIELD to lowercase?
010300 INSPECT DATA FIELD 010400 CONVERTING LOWER-ALPHA 010500 TO UPPER-ALPHA.
© Copyright, Macmillan Computer Publishing. All rights reserved.