sams_teach_yourself_cobol_in_24_hours_-_hour_12_tables

Sams Teach Yourself COBOL in 24 Hours - Hour 12 Tables

Return to Teach Yourself COBOL in 24 Hours, COBOL bibliography, COBOL, COBOL DevOps, Awesome COBOL, Awesome IBM Mainframe, IBM Mainframe development, IBM Mainframe bibliography, Fortran

“ (TYCb24H 1998)

Hour 12 Tables

Tables are the COBOL version of an array. Tables have a variety of uses, from subtotal tracking to data validation. Table handling is an integral part of many COBOL programs. In this hour, you learn the different aspects of table handling, including

• The definition of a table

• Populating a table in Working-Storage

• Table searches

• Handling variable-length tables

Defining a Table Image

A table is a set of different data items with identical definitions. They are defined so that the individual items in the set can be accessed via a reference, known as a subscript. Tables are also known as arrays. When a table is defined, the number of individual items, or elements, in the table is established. You can access the individual elements of the table by using the proper COBOL syntax.

A table is like a box of sequentially numbered index cards. You can locate a particular card by using its number and then counting the cards until you get to that number. The computer can perform this process faster than a person can because it can go directly to that card using the subscript value and because all the elements of the table have the same definition. The computer uses the subscript value to find the offset in the table and immediately access the element. This method is similar to what a person might do if the thickness of each card in the box of index cards is known. The number of the card sought can be determined and then, based on the thickness of the cards, the deck can be measured to immediately find the location of the card being sought. With the computer, table access is very fast.

A table is defined by using the Occurs clause in the Data Division. The Occurs clause may not be used on a level 01 or level 77 data item. In the following example, a table stores the names of the months in the year.

000010 01 Month-Table. 000011 03 Month-Name Pic X(9) Occurs 12 Times. The Occurs clause in line 11 specifies that this field is repeated 12 times; in other words, the table has 12 elements. The subscript associated with the first element is 1, and the subscript associated with the last is 12.

The Occurs clause may also be used at the Group Level to create an array containing several elementary items. The next example might be used to define a table containing the different state abbreviations and state names.

000012 01 State-Table. 000013 03 State-Abbrev-Name Occurs 51 Times. 000014 05 State-Abbrev Pic X(2). 000015 05 State-Name Pic X(30). Notice that the Occurs clause is specified only at the Group Level above the two associated elementary items. Therefore, the pairing of State-Abbrev and State-Name repeats 51 times. The table can be defined as follows:

000012 01 State-Table. 000013 03 State-Abbrev-Name. 000014 05 State-Abbrev Pic X(2) Occurs 51 Times. 000015 05 State-Name Pic X(30) Occurs 51 Times. Note that the Occurs clause appears only with the elementary items. In this example, if you looked at the table in memory within the computer, you would see the 50 state abbreviates listed together, followed by the 50 state descriptions. This arrangement becomes an important consideration as values are assigned to the individual table elements.

Basic Table Handling To reference an element within a table, you need to specify the subscript. The first element of the table has a subscript value of 1. Subscripts are specified by stating the subscript, enclosed in parentheses, after the field name. For example:

000060 Display State-Name (24) This line of code displays the 24th occurrence of State-Name.

You may use a table entry in the same way you use any other COBOL data item. You may move data into it or out if it. If it is a numeric data item, you may perform mathematical functions against the field.

Populating a Table in Working-Storage Before a table can be of much use, values must be assigned to the table’s individual elements. Consider a table that is to contain the individual month names.

000010 01 Month-Table. 000011 03 Month-Name Pic X(9) Occurs 12 Times. One way to get the individual month names into the table is to move them individually.

000061 Move “January” To Month-Name (1) 000062 Move “February” To Month-Name (2) This code is repeated for each month. The subscript references in this example are numeric literals. This need not be the case, as a numeric data item can be used instead.

After the table is loaded, the individual fields can be referenced by using the subscript.

000063 Display Month-Name (10) This line displays October.

The Redefines Clause Image

In some cases, loading a table with individual Move statements makes sense. However, for the preceding example, in which the values in the table never need to change, a better way to initialize the table is to use a Data Division feature called the Redefines clause. In this case, the contents of the table can be defined in Working-Storage, instead of being loaded in the Procedure Division.

The Redefines allows you to specify a different Picture clause for a previously defined data item. An individual item may be the subject of multiple Redefines clauses. Examine this example:

000040 01 Data-Group. 000041 03 Numeric-Item Pic 9(5)V99. 000042 03 Numeric-Split Redefines Numeric-Item. 000043 05 Numeric-Whole-Portion Pic 9(5). 000044 05 Numeric-Decimal-Portion Pic 9(2). The two fields, Numeric-Item and Numeric-Split, reference the same physical location in storage. The group item Numeric-Split is further defined as two individual fields: The first part makes up the whole number, and the second portion makes up the decimal position of Numeric-Item. If you move 12.99 to Numeric-Item, then Numeric-Whole-Portion contains 00012 and Numeric-Decimal-Portion contains 99.

Image

When using Redefines, you must make sure that the item you are redefining is the same size as the item in your Redefines clause. The compiler warns you of a size difference if the Redefines clause does not redefine a level 01 item. In contrast, level 01 items may redefine items with differing size; in this case, no compiler warning message is issued or required. Because this practice can cause problems, I suggest that you do not redefine items at the 01 level.

You can take advantage of the Redefines clause to populate the month table in Working-Storage. First, an area is defined with the different month descriptions listed in order.

000025 01 Month-Table-Area. 000026 03 Month-Descriptions. 000027 05 Filler Pic X(9) Value “January”. 000028 05 Filler Pic X(9) Value “February”. 000029 05 Filler Pic X(9) Value “March”. 000030 05 Filler Pic X(9) Value “April”. 000031 05 Filler Pic X(9) Value “May”. 000032 05 Filler Pic X(9) Value “June”. 000033 05 Filler Pic X(9) Value “July”. 000034 05 Filler Pic X(9) Value “August”. 000035 05 Filler Pic X(9) Value “September”. 000036 05 Filler Pic X(9) Value “October”. 000037 05 Filler Pic X(9) Value “November”. 000038 05 Filler Pic X(9) Value “December”. The next step is to redefine this data area with the month table. Then the table is automatically populated, or loaded, with the appropriate data values.

000039 03 Month-Table Redefines Month-Descriptions. 000040 05 Month-Name Pic X(9) Occurs 12 Times. Image

When you use redefines to establish initial values for the elements of a table, you cannot use the Initialize verb to reset the table to these values. Initialize moves spaces or zeros, as appropriate, to each element of a table, thus clearing your predefined values.

There are many ways to put tables to good use. One way to take advantage of a table involves the program you wrote (see Listing 12.1) as an answer to the exercise problem in Hour 10, “Processing Loops.” This problem involved accepting a date and then reformatting the date to spell out the month, creating a nicely edited date. You probably used the Evaluate statement to find and use the correct month name. Using a table simplifies the program.

Listing 12.1 Display the Name of the Month Corresponding to the Date

000001 @OPTIONS MAIN,TEST 000002 Identification Division. 000003 Program-Id. Chapt12a. 000004 Environment Division. 000005 Configuration Section. 000006 Special-Names. 000007 Crt Status Is Keyboard-Status. 000008 Source-Computer. IBM-PC. 000009 Object-Computer. IBM-PC. 000010 Data Division. 000011 Working-Storage Section. 000012 01 Keyboard-Status. 000013 03 Accept-Status Pic 9. 000014 03 Function-Key Pic X. 000015 88 F1-Pressed Value X”01”. 000016 03 System-Use Pic X. 000017 01 Date-Field Pic 9(8) Value Zeros. 000018 01 Date-Field-Split Redefines Date-Field. 000019 03 Month-Portion Pic 99. 000020 03 Filler Pic X(6). 000021 01 Edited-Date-Field Pic X(20) Value Spaces. 000022 01 Error-Flag Pic X Value Spaces. 000023 88 Month-Error Value “Y”. 000024 01 Error-Message Pic X(50) Value Spaces. 000025 01 Month-Table-Area. 000026 03 Month-Descriptions. 000027 05 Filler Pic X(9) Value “January”. 000028 05 Filler Pic X(9) Value “February”. 000029 05 Filler Pic X(9) Value “March”. 000030 05 Filler Pic X(9) Value “April”. 000031 05 Filler Pic X(9) Value “May”. 000032 05 Filler Pic X(9) Value “June”. 000033 05 Filler Pic X(9) Value “July”. 000034 05 Filler Pic X(9) Value “August”. 000035 05 Filler Pic X(9) Value “September”. 000036 05 Filler Pic X(9) Value “October”. 000037 05 Filler Pic X(9) Value “November”. 000038 05 Filler Pic X(9) Value “December”. 000039 03 Month-Table Redefines Month-Descriptions. 000040 05 Month-Name Pic X(9) Occurs 12 Times. 000041 Screen Section. 000042 01 Date-Entry Blank Screen. 000043 03 Line 01 Column 01 Value “ Enter Date: ”. 000044 03 Line 01 Column 14 Pic 99/99/9999 Using Date-Field. 000045 03 Line 02 Column 01 Value “Edited Date: ”. 000046 03 Line 02 Column 14 Pic X(20) From Edited-Date-Field. 000047 03 Line 05 Column 01 Pic X(50) From Error-Message. 000048 03 Line 20 Column 01 Value “Press F1 to Exit”. 000049 Procedure Division. 000050 Chapt12a-Start. 000051 Perform Until F1-Pressed 000052 Display Date-Entry 000053 Accept Date-Entry 000054* Clear The Error Message For The Next Display 000055 Move Spaces To Error-Message 000056* If They Did Not Press F1 To Exit, It’s Ok To Process The Input 000057 If Not F1-Pressed 000058 Perform Process-Input 000059 End-If 000060 End-Perform 000061 Stop Run 000062 . 000063 Process-Input. 000064* Reset The Error Flag. 000065 Move Spaces To Error-Flag 000066 If Month-Portion < 01 Or Month-Portion > 12 000067 Set Month-Error To True 000068 Move “Invalid Month” To Error-Message 000069 Else 000070 Move Spaces To Edited-Date-Field 000071 String Month-Name (Month-Portion) Delimited By Space 000072 Space 000073 Date-Field (3:2) 000074 “,” 000075 Date-Field (5:4) 000076 Delimited By Size 000077 Into Edited-Date-Field 000078 End-String 000079 End-If 000080 . Redefines appears in two places in the listing. The first Redefines clause, in line 18, handles the user-entered date. This clause allows numeric fields that contain only the month. This month is first checked to make sure that it is within the bounds, or “limits,” of the table. The bounds of this table are 1 through 12. Most compilers have an option that allows you to capture a so-called boundary violation, or to not report the error if reported by default. If you reference a table element that is outside the bounds of your table, you receive a boundary violation.

Image

I suggest that you always write your programs to check for and eliminate any possible boundary violations. This does not mean that you have to code your programs with compares before every table element reference. Simply make sure that any invalid value that can occupy the field is not used as a table reference.

The second use of Redefines populates the table. This method requires far less code than you used in the Procedure Division method. The month is formatted using fewer instructions. Notice that the String statement uses multiple delimiters. The first is by spaces, so the end of the month name can be detected, and the rest are by size. This program produces a perfectly formatted date.

Image

The preceding examples have shown the simplest use of a table. Another use for a table is as a lookup. You can use a small table, with its extremely fast lookup, to find associated information. For example, you might have a state table. The states, themselves, do not allow for easy table access. You can’t subscript a table using a state abbreviation. Instead, you can search the table for the particular value required. Listing 12.2 is one example of a state search against a state table.

Listing 12.2 State Name Lookup

000001 @OPTIONS MAIN,TEST 000002 Identification Division. 000003 Program-Id. Chapt12b. 000004 Environment Division. 000005 Configuration Section. 000006 Source-Computer. IBM-PC. 000007 Object-Computer. IBM-PC. 000008 Data Division. 000009 Working-Storage Section. 000010 01 State-Table-Area. 000011 03 State-Table-Data. 000012 05 Filler Pic X(22) Value “ALAlabama”. 000013 05 Filler Pic X(22) Value “AKAlaska”. 000014 05 Filler Pic X(22) Value “AZArizona”. 000015 05 Filler Pic X(22) Value “ARArkansas”. 000016 05 Filler Pic X(22) Value “CACalifornia”. 000017 05 Filler Pic X(22) Value “COColorado”. 000018 05 Filler Pic X(22) Value “CTConnecticut”. 000019 05 Filler Pic X(22) Value “DCDistrict of Columbia”. 000020 05 Filler Pic X(22) Value “DEDelaware”. 000021 05 Filler Pic X(22) Value “FLFlorida”. 000022 05 Filler Pic X(22) Value “GAGeorgia”. 000023 05 Filler Pic X(22) Value “HIHawaii”. 000024 05 Filler Pic X(22) Value “IDIdaho”. 000025 05 Filler Pic X(22) Value “ILIllinois”. 000026 05 Filler Pic X(22) Value “INIndiana”. 000027 05 Filler Pic X(22) Value “IAIowa”. 000028 05 Filler Pic X(22) Value “KSKansas”. 000029 05 Filler Pic X(22) Value “KYKentucky”. 000030 05 Filler Pic X(22) Value “LALouisiana”. 000031 05 Filler Pic X(22) Value “MEMaine”. 000032 05 Filler Pic X(22) Value “MDMaryland”. 000033 05 Filler Pic X(22) Value “MAMassachusetts”. 000034 05 Filler Pic X(22) Value “MIMichigan”. 000035 05 Filler Pic X(22) Value “MNMinnesota”. 000036 05 Filler Pic X(22) Value “MSMississippi”. 000037 05 Filler Pic X(22) Value “MOMissouri”. 000038 05 Filler Pic X(22) Value “MTMontana”. 000039 05 Filler Pic X(22) Value “NENebraska”. 000040 05 Filler Pic X(22) Value “NVNevada”. 000041 05 Filler Pic X(22) Value “NHNew Hampshire”. 000042 05 Filler Pic X(22) Value “NJNew Jersey”. 000043 05 Filler Pic X(22) Value “NMNew Mexico”. 000044 05 Filler Pic X(22) Value “NYNew York”. 000045 05 Filler Pic X(22) Value “NCNorth Carolina”. 000046 05 Filler Pic X(22) Value “NDNorth Dakota”. 000047 05 Filler Pic X(22) Value “OHOhio”. 000048 05 Filler Pic X(22) Value “OKOklahoma”. 000049 05 Filler Pic X(22) Value “OROregon”. 000050 05 Filler Pic X(22) Value “PAPennsylvania”. 000051 05 Filler Pic X(22) Value “RIRhode Island”. 000052 05 Filler Pic X(22) Value “SCSouth Carolina”. 000053 05 Filler Pic X(22) Value “SDSouth Dakota”. 000054 05 Filler Pic X(22) Value “TNTennessee”. 000055 05 Filler Pic X(22) Value “TXTexas”. 000056 05 Filler Pic X(22) Value “UTUtah”. 000057 05 Filler Pic X(22) Value “VTVermont”. 000058 05 Filler Pic X(22) Value “VAVirginia”. 000059 05 Filler Pic X(22) Value “WAWashington”. 000060 05 Filler Pic X(22) Value “WVWest Virginia”. 000061 05 Filler Pic X(22) Value “WIWisconsin”. 000062 05 Filler Pic X(22) Value “WYWyoming”. 000063 03 State-Table Redefines State-Table-Data. 000064 05 State-Table-Occurrences Occurs 51 Times. 000065 10 State-Abbrev Pic XX. 000066 10 State-Name Pic X(20). 000067 01 State-Subscript Pic 99 Value Zeros. 000068 Procedure Division. 000069 Chapt12b-Start. 000070* Search For Texas, By Abbreviation 000071 Perform Varying State-Subscript From 1 By 1 Until 000072 State-Subscript > 51 Or 000073 State-Abbrev (State-Subscript) = “TX” 000074 Continue 000075 End-Perform 000076 If State-Subscript > 51 000077 Display “State Not Found” 000078 Else 000079 Display “TX = ” 000080 State-Name (State-Subscript) 000081 End-If 000082 Stop Run 000083 . The Redefines clause allows the table to be loaded in Working-Storage. The search is an inline Perform that continues until it reaches the end of the table or until it gets a match. Before displaying the state description found, the subscript field is checked to ensure it is within the table boundary. If it is not, you know that the abbreviation was not found in the table.

The Search Statement Image

COBOL provides a quick way to Search a table for particular values. For you to use this feature, the table must have an associated index. An index is a system-assigned data field that references the different elements of a table—you do not define this field in your program. Although an index behaves like a numeric data item, you cannot adjust it using mathematical statements as you would normal numeric data items. An index is specified by using the Indexed By clause on the same line as the Occurs clause. Specify a unique data name after the words Indexed By.

Image

The compiler vendor determines the actual contents of an index. In most cases, it is an absolute offset in characters to the particular item within the table. However, you may not reference the item as a number, and the index does not contain an element number, even though it may be tested in perform loops as if it does. The compiler handles the actual interpretation of the value for you.

000058 03 Month-Table Redefines Month-Descriptions. 000059 05 Month-Name Pic X(9) Occurs 12 Times Indexed by 000060 Table-Index. To manipulate the value of an index, you must use the Set statement. You may Set an index to a particular value or adjust its value up or down by specific amounts.

000061 Set Table-Index To 1 000062 Set Table-Index Up by 2 000063 Set Table-Index Down by 1 Image

Using index values provides faster table access than using a regular numeric data item or numeric literal. You must remember, however, that you cannot change an index value using standard mathematical statements. If you need to adjust an index, use the Set statement.

An indexed table may be searched using the COBOL verb Search, which has two formats. The first format searches the table from the top to the bottom. In the Search statement, you specify the condition that causes the Search to end. Optionally, you may specify some statements to perform if the Search does not find any items in the table that satisfy your test condition.

When coding the Search statement, the data item that is specified for the Search is the one for which the Occurs clause has been coded. The conditions that end the Search are coded using When, in a manner very similar to that used with the Evaluate statement. The statements that are executed when the Search fails are coded after the clause At End. The Search proceeds from the present value of the associated index. Consequently, you must be careful to Set the value of the table’s index to 1 before the Search begins. Failing to do so causes the Search to begin at an entry in the table other than the first.

If the state table is defined with the index Table-Index, the following code will perform the same test as the inline Perform from the earlier example. In fact, the following Search statement can replace the entire Procedure Division from Listing 12.2.

000215 Search State-Table-Occurrences 000216 At End Display “State Not Found” 000217 When State-Abbrev (Table-Index) = “TX” 000218 Display “TX = ” 000219 State-Name (Table-Index) 000220 End-Search Image

When coding the Search statement, the At End condition, if present, must occur before any When clauses. At End is optional. If not coded, nothing happens when the Search ends without meeting your conditions.

You may use multiple When clauses within the Search statement. If any one of them is true, the statements after the associated When are executed. As soon as a When condition is true, the searching stops.

The End-Search explicit scope terminator is valid with the Search statement. I strongly suggest that you use it with every Search statement to clearly separate the code after the When from the rest of your program.

Image

Remember that the index of a table has a special internal representation. The only COBOL statements you can use to address this index are the Set, Search, and Perform with Varying statements. If you want to do something in your program based on the actual element number of the found item, COBOL provides a method to increment another data item during the Search. This method involves the Tally clause. The item being incremented can be the index for another table or a numeric variable.

The Varying clause specifies the other data item. You should remember that this item is being adjusted by the Search in addition to the index specified for the table, not instead of that index.

Image

Because the data item is incremented separately and independently of the table’s defined index, it is important to initialize that data item in addition to the table’s index. For example, if the numeric data item started with a value of 10 and the table element that satisfied the search was element 5, the resulting value in the numeric data item is 15, not 5 like you might expect.

000221 Move Zeros to Numeric-Data-Item 000222 Set Table-Index to 1 000223 Search State-Table-Occurrences 000224 Varying Numeric-Data-Item 000225 At End Display “State Not Found” 000226 When State-Abbrev (Table-Index) = “TX” 000227 Display “TX = ” 000228 State-Name (Table-Index) 000229 End-Search The Search statement, which starts at the front of the table and searches to the end, is not very efficient on large tables. COBOL provides another format of the Search statement that allows much faster searching. This format is Search All. For a program to use Search All, the table must be indexed and keyed. The elements of the table must be in ascending or descending key sequence as specified in the field’s definition. The key fields are defined in the Data Division, on the same line as the Occurs clause. The previous example, using the state table, was sorted in ascending state-name sequence. Therefore, Search All can be used against the state name. However, Search All cannot be used on the state abbreviations because they are not in sequence. The definition of the state table keyed on state name follows.

000199 03 State-Table Redefines State-Table-Data. 000200 05 State-Table-Occurrences Occurs 51 Times 000201 Indexed By Table-Index 000202 Ascending Key State-Name. 000203 10 State-Abbrev Pic XX. 000204 10 State-Name Pic X(20). Here’s how the Search All statement is coded to find the abbreviation of a state name such as Texas:

000230 Search All State-Table-Occurrences 000231 At End Display “State Not Found” 000232 When State-Name (Table-Index) = “Texas” 000233 Display “Texas = ” 000234 State-Abbrev (Table-Index) 000235 End-Search The rules governing Search and Search All are not exactly the same. With Search All, there may be only one When clause. The When clause must reference one of the key fields. However, the When may be coded with one or more And statements. The And statements allow you to test for multiple conditions and must also reference one of the key fields in the table. The key field must immediately follow the word When.

The Search All performs a binary search. A binary search starts around the middle of the table and determines whether the value is greater or less than the key being searched. If the value is greater, the search looks in the higher half of the table. The program continues to split the table into smaller and smaller search areas until the Search is satisfied or until no more items are in the table. Because of the binary search, the setting of the table index to 1 before the Search is unnecessary. The initial value of the index is ignored.

Listing 12.3 shows an example of Search All with When and And clauses. The table being searched contains multiple city and state entries allowing the program to find the state that corresponds with the city.

Listing 12.3 Search All Example

000001 @OPTIONS MAIN,TEST 000002 Identification Division. 000003 Program-Id. Chapt12e. 000004 Environment Division. 000005 Configuration Section. 000006 Source-Computer. IBM-PC. 000007 Object-Computer. IBM-PC. 000008 Data Division. 000009 Working-Storage Section. 000010 01 State-Table-Area. 000011 03 State-Table-Data. 000012 05 Filler Pic X(37) Value “ALBirmingham Alabama”. 000013 05 Filler Pic X(37) Value “ALMontgomery Alabama”. 000014 05 Filler Pic X(37) Value “AZPhoenix Arizona”. 000015 05 Filler Pic X(37) Value “AZTucson Arizona”. 000016 03 State-Table Redefines State-Table-Data. 000017 05 State-Table-Occurrences Occurs 4 Times 000018 Indexed By Table-Index 000019 Ascending Key State-Abbrev City-Name. 000020 10 State-Abbrev Pic XX. 000021 10 City-Name Pic X(15). 000022 10 State-Name Pic X(20). 000023 Procedure Division. 000024 Chapt12e-Start. 000025 Search All State-Table-Occurrences 000026 At End Display “State Not Found” 000027 When State-Abbrev (Table-Index) = “AZ” 000028 And City-Name (Table-Index) = “Phoenix” 000029 Display “State = ” 000030 State-Name (Table-Index) 000031 End-Search 000032 Stop Run 000033 . First, notice that the table is keyed by two key fields. This technique can be useful in case two states have cities with the same name. The key sequence, as defined, is city within state abbreviation. Second, notice the When and the And clauses in the Search All statement. Each clause refers to a key as defined on the Occurs line. This syntax is required for the Search All statement. Finally, realize that the Search does not stop until both conditions, the When and the And, are satisfied.

Multidimensional Tables Image

Thus far, the tables discussed here have been one-dimensional. However, in COBOL tables can have up to seven dimensions. A two-dimensional table is a table within a table. You can visualize a two-dimensional table as a file within a drawer in a file cabinet. The file cabinet is the table. The first dimension is the drawer number, and the second is the file within the drawer. The table might be described in your data division as follows:

000040 01 File-Cabinet. 000041 03 Drawer-Number Occurs 3 Times Indexed By Drawer-Index. 000042 05 File-Number Pic 9(3) Occurs 10 Times Indexed By 000043 File-Index. To reference a particular file number, a two-dimensional table reference is coded. This is accomplished by coding both index values within the parenthetical reference to the data item. For example, the following code references the fifth file in the third drawer:

000100 Display File-Number (3,5) The comma is optional but helps to make the table reference more readable. The highest level index is specified first. Another example might make this syntax clearer.

000101 Set Drawer-Index To 3 000102 Set File-Index To 5 000103 Display File-Number (Drawer-Index, File-Index) You may Search a multidimensional table using the Search verb. The higher-level index values must be Set before the basic, or lowest-level index can be searched. When you specify the table level to be searched in the Search statement, you do not need to provide the full reference. However, any When statements must specify the full qualification of the table entry.

000104 Set Drawer-Index To 2 000105 Search File-Number 000106 At End Display “File Not Found” 000107 When File-Number (Drawer-Index, File-Index) = 123 000108 Display “File Found” 000109 End-Search In this example, File-Number is being searched. It is a table that exists as the second dimension of the larger table, Drawer-Number. Note that in the Search line the element of Drawer-Number is not specified. The Search statement uses the current index value associated with the Drawer-Number for its search. Also note that the When statement specifies the full table reference for the purposes of the test condition.

Now examine a more complex example of multidimensional tables. Consider this classic logic puzzle: “As I was going to St. Ives, I met a man with seven wives. Every wife had seven sacks, every sack had seven cats, and every cat had seven kits. Kits, cats, sacks and wives, how many were going to St. Ives?”

Ignore the basic question being asked by the puzzle. To describe this condition in a table, you might code:

000040 01 The-Man-On-The-Road. 000041 03 Wife Occurs 7 Times Indexed By Wife-Index. 000042 05 Wife-Name Pic X(20). 000043 05 Sack Occurs 7 Times Indexed By Sack-Index. 000044 10 Sack-Color Pic X(10). 000045 10 Cat Occurs 7 Times Indexed By Cat-Index. 000046 15 Cat-Name Pic X(20). 000047 15 Kitten Occurs 7 Times Indexed By Kitten-Index. 000048 20 Kitten-Name Pic X(20). Notice that the tables are not just tables within tables. The Wife-Name has the same level number as the Sack table, which allows the tracking of each wife and her associated sacks. Each Sack-Color has the same level number as the Cat table beneath it, which allows each sack color to be tracked.

How might you code a COBOL program to find which wife is carrying a kitten named “Hershey”? You need to search through each and every cat, in every sack, carried by every wife, until you either find a match or don’t find the kitten in any sack. Listing 12.4 is one way to code the Search.

Listing 12.4 Search A Multidimensional Table

000001 @OPTIONS MAIN,TEST 000002 Identification Division. 000003 Program-Id. Chapt12g. 000004 Environment Division. 000005 Configuration Section. 000006 Source-Computer. IBM-PC. 000007 Object-Computer. IBM-PC. 000008 Data Division. 000009 Working-Storage Section. 000010 01 The-Man-On-The-Road. 000011 03 Wife Occurs 7 Times 000012 Indexed By Wife-Index. 000013 05 Wife-Name Pic X(20). 000014 05 Sack Occurs 7 Times 000015 Indexed By Sack-Index. 000016 10 Sack-Color Pic X(10). 000017 10 Cat Occurs 7 Times 000018 Indexed By Cat-Index. 000019 15 Cat-Name Pic X(20). 000020 15 Kitten Occurs 7 Times 000021 Indexed By Kitten-Index. 000022 20 Kitten-Name Pic X(20). 000023 01 Found-Flag Pic X Value Spaces. 000024 88 Kitten-Found Value “Y”. 000025 Procedure Division. 000026 Chapt12g-Start. 000027 Move “Hershey” To Kitten-Name (1, 3, 2, 6) 000028 Move “Darlene” To Wife-Name (1) 000029 Move “Yellow” To Sack-Color (1, 3) 000030 Perform With Test After 000031 Varying Wife-Index From 1 By 1 Until 000032 Wife-Index = 7 Or 000033 Kitten-Found 000034 Perform With Test After 000035 Varying Sack-Index From 1 By 1 Until 000036 Sack-Index = 7 Or 000037 Kitten-Found 000038 Perform With Test After 000039 Varying Cat-Index From 1 By 1 Until 000040 Cat-Index = 7 Or 000041 Kitten-Found 000042 Set Kitten-Index To 1 000043 Search Kitten 000044 When 000045 Kitten-Name (Wife-Index, Sack-Index, 000046 Cat-Index, Kitten-Index) = 000047 “Hershey” Set Kitten-Found To True 000048 End-Search 000049 End-Perform 000050 End-Perform 000051 End-Perform 000052 If Kitten-Found 000053 Display “Hershey found in the ” 000054 Sack-Color (Wife-Index, Sack-Index) 000055 “ Sack, Being carried by ” 000056 Wife-Name (Wife-Index) 000057 Else 000058 Display “Hershey Escaped” 000059 End-If 000060 Stop Run 000061 . Examine this program line by line. The entry to be searched for is first loaded into the table. In actuality, the full table would be loaded. The specific entry is loaded only as an example.

Next, note the use of the inline Perform statements, which allow nested Perform statements to search each dimension of the table. Remember that when using Varying with a Perform, the data item being varied is incremented before each loop through the Perform. Therefore, the behavior of the Perform has been changed to Test After. This change allows the different indices to remain set to the values they are on when the Search completes successfully. Notice also that no At End clause is coded in the Search statement. The clause is not necessary. Compile and run the program. Experiment with setting different locations for “Hershey”. Run the program in the debugger and watch what is happening. Remember to link the program with the debug option enabled.

Variable-Length Tables Tables do not have to be of fixed length. You can define a table that contains from one to any number of entries. You might want to have a variable-length table for several reasons. For example, you might choose a variable-length table to shorten the response time on a Search or Search All statement.

You might have a table in which you don’t know the maximum number of entries. It might be loaded from user input or from a data file. It might even be created during the course of a program’s execution. If you always allow for the table’s maximum size, you will be wasting time during the Search operations. Additionally, it will be virtually impossible to provide a sorted table for Search All. If your table has 1,000 entries, but you load it with only 100, the other 900 entries in the table must be in ascending sequence. One solution is to load the remaining entries with High-Values, but that approach wastes time. Instead, you should use a variable-length table.

You create a variable-length table by specifying Depending On in the Occurs clause on the item definition. You must have a data item defined that will contain the number of items in the table. This item is the one that the number of occurrences in the table depends on and can change during the course of the program. In addition to specifying the Depending On clause, you must specify the minimum and maximum number of occurrences in the table.

The following table contains dealer numbers and names from your antique store. You can have any number of dealers, but the number may fluctuate. You might need a table to find the dealer name with the associated dealer number.

000040 01 Dealer-Table. 000041 03 Dealers Occurs 1 To 1000 Times Depending On 000042 Number-Of-Dealers 000043 Indexed By Dealer-Index 000044 Ascending Key Dealer-Number. 000045 05 Dealer-Number Pic 9(4). 000046 05 Dealer-Name Pic X(20). 000047 01 Number-Of-Dealers Pic 9(4) Value 1. Image

A variable-length table must have at least one occurrence. The memory required to contain the maximum size the table may obtain is usually reserved by the compiler (some COBOL vendors dynamically allocate the storage space). You should be aware that some compilers limit the maximum size of a table. You should refer to your compiler documentation to find out what limit, if any, is specified for your compiler.

Image

Variable-length tables may be specified only for the highest level of a table. If your table is multidimensional, the tables that make up the dimensions under the main table may not be variable length.

When this table is loaded, the Number-Of-Dealers has to be incremented in the program. You should not reference an element of the table that is higher in number than the Depending On data item. Doing so will cause a table-boundary violation.

Summary In this hour, you learned the following:

• Tables are groups of like items arranged in such a way that individual elements of the group can be referenced.

• Table elements can be initialized to specific values in Working-Storage by setting up a data area with the various values and using the Redefines clause.

• Tables elements can be referenced by numeric literals, numeric data items, or index values.

• Index items may be specified by using Indexed By on the same line as the Occurs clause.

• Index items are not like normal numeric data items. You must use the Set statement to set or change the values of index items.

• Tables may be searched using the Search verb.

• For Search All, the items in the table must be in key sequence.

• Tables may be created with multiple dimensions. COBOL supports up to seven dimensions in a table.

• Tables do not have to contain a fixed number of elements. They can contain a variable number of elements. Variable-length tables are defined by specifying the Depending On clause in the table’s definition.

Q&A Q When I want to Search a table, how can I remember which part of the table to code after the Search statement?

A Look for the Occurs clause. All of your Search statements Search the named data items on the same line as the Occurs clause.

Q I tried to use Search All, but I can’t seem to get it right. Can you give me some pointers?

A Some common mistakes are not specifying the key fields on the table. Other problems come from the data in the table not being in this key sequence. The key values can be either ascending or descending. When your table is created and data is loaded into it, if you are going to use Search All, you must ensure that the data in the table is in the proper sequence. Nothing in the COBOL language informs you that your table is out of sequence.

Q When I run my program, I get some strange results. I think I have a boundary violation, but the program is not reporting it. How do I get it to?

A With the Fujitsu Compiler you need to add the compiler option CHECK(1) to the top of the program. This option displays an error message the first time a boundary violation occurs and terminates the program. (See Program Chapt12z.Cob on the CD-ROM.)

Q What is a boundary violation?

A A boundary violation occurs when you try to access a table element that is out of the range of the table. If your table has 50 occurrences and you attempt to access an element with a subscript of 51, you will get a boundary violation. Some compilers report this error by default, and some do not. On those that do not, or where you have disabled boundary or index/subscript range checking, unpredictable results may occur.

Q My table searches using the Search verb are taking a long time. What can I do to speed them up?

A You can try to limit the search time by using Search All if it is feasible. If not, try limiting the table size to the actual number of items you have in the table by making the table variable length. You do this by using the Depending On clause with the Occurs clause.

Workshop To help reinforce your understanding of the material presented in this hour, refer to the section “Quiz and Exercise Questions and Answers” that can be found on the CD. This section contains quiz questions and exercises for you to complete, as well as the corresponding answers.

Fair Use Sources

COBOL: COBOL Fundamentals, COBOL Inventor - COBOL Language Designer: 1959 by Howard Bromberg, Norman Discount, Vernon Reeves, Jean E. Sammet, William Selden, Gertrude Tierney, with indirect influence from Grace Hopper, CODASYL, ANSI COBOL, ISO/IEC COBOL; Modern COBOL - Legacy COBOL, IBM COBOL, COBOL keywords, COBOL data structures - COBOL algorithms, COBOL syntax, Visual COBOL, COBOL on Windows, COBOL on Linux, COBOL on UNIX, COBOL on macOS, Mainframe COBOL, IBM i COBOL, IBM Mainframe DevOps, COBOL Standards, COBOL Paradigms (Imperative COBOL, Procedural COBOL, Object-Oriented COBOL - COBOL OOP, Functional COBOL), COBOL syntax, COBOL installation, COBOL containerization, COBOL configuration, COBOL compilers, COBOL IDEs, COBOL development tools, COBOL DevOps - COBOL SRE, COBOL data science - COBOL DataOps, COBOL machine learning, COBOL deep learning, COBOL concurrency, COBOL history, COBOL bibliography, COBOL glossary, COBOL topics, COBOL courses, COBOL Standard Library, COBOL libraries, COBOL frameworks, COBOL research, Grace Hopper, COBOL GitHub, Written in COBOL, COBOL popularity, COBOL Awesome list, COBOL Versions. (navbar_cobol)


Cloud Monk is Retired (for now). Buddha with you. © 2005 - 2024 Losang Jinpa or Fair Use. Disclaimers

SYI LU SENG E MU CHYWE YE. NAN. WEI LA YE. WEI LA YE. SA WA HE.


sams_teach_yourself_cobol_in_24_hours_-_hour_12_tables.txt · Last modified: 2022/05/16 03:22 by 127.0.0.1