Teach Yourself COBOL in 21 days, Second Edition

Previous chapterNext chapterContents


- Day 15 -
Data Integrity

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:

What Is Data Integrity?

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.

What Is Valid Data?

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.

TYPE: Listing 15.1. Vendor file FD.

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.

Deciding Whether to Validate Data

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.


When to Validate Data

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

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.

TYPE: Listing 15.2. The FD for the state code file.

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

TYPE: Listing 15.3. The SELECT statement for the state code file.

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.

TYPE: Listing 15.4. Creating a new state code file.

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.

TYPE: Listing 15.5. Validating field entry.

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.

Standard Field Entry

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.

TYPE: Listing 15.6. The pseudocode for standard field entry.

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.

TYPE: Listing 15.7. A standard field-entry routine including edit-check-the-data.

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.

Change Mode for Simple Files

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.

TYPE: Listing 15.8. Skip asking the user which field.

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 a Code File

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.

TYPE: Listing 15.9. Report on the state codes file.

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

Converting to Uppercase

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.

TYPE: Listing 15.10. Converting 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.

TYPE: Listing 15.11. Validating by converting to uppercase.

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."

Summary

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.

Q&A

Q Is data validation part of the COBOL language?

A No. COBOL provides commands that make it possible to validate data, but the actual validation is part of the design of the program. You can write a program that enables you to put any old junk into a file and COBOL will not complain about it, although the users most certainly will.

Workshop

Quiz

1. When should data be validated?

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.

Exercises

1. Design a standard data entry routine to accept entry for a field called VENDOR-NAME. Assume that appropriate UPPER-ALPHA and LOWER-ALPHA conversion fields exist in WORKING-STORAGE. The field must be entered by the user, and it must be converted to uppercase after the entry is completed. Do this using pencil and paper.

Hint: You could use ENTER-STATE-NAME as a basis for the routine.

2. Next to the design you have written, write down the parts of the standard field-entry routine.


Previous chapterNext chapterContents


© Copyright, Macmillan Computer Publishing. All rights reserved.