TABLES
Table use within COBOL
TABLES in COBOL allow the programmer to access data that is set up in WORKING-STORAGE
based on a code. As we have seen, it is more efficient to store a code on a file as opposed to
storing the full description of the item. An example is the code for type of employee, F for
full time, P for part time, C for consultant and T for temporary. Instead of storing the
description of the employee, the programmer has stored the code. Letter codes can be used to
access a table using a search methodology, but for now we are going to discuss simple tables
and simple tables need numeric codes starting at the beginning of the number sequence without
gaps. In previous examples, the programmer has converted the code into the name by using level
88s or by using decision making. This example presents another option: using the code to access
the table and retrieve the name associated with the code.
To illustrate, we are going to change the employee type code on the input file to a numeric
field and make 1 the code for full time, 2 the code for part time, 3 the code for consultant
and 4 the code for temporary.
FD INPUT-FILE.
01 INPUT-REC.
05 EMP-TYPE-CODE PIC 9.
Tables are set up so that the EMP-TYPE-CODE of 1 will access the first element in the table, the
EMP-TYPE-CODE of 2 will access the second element in the table etc. The setup of the table
needed in this example would start like this:
01 EMPLOYEE-TABLE.
05 FILLER PIC X(10) VALUE "FULL TIME ".
05 FILLER PIC X(10) VALUE "PART TIME ".
05 FILLER PIC X(10) VALUE "CONSULTANT".
05 FILLER PIC X(10) VALUE "TEMPORARY ".
There are a couple of things you should notice:
- First, this is only the start of the table. In fact, it is not yet a table. It is
simply a listing of the four values that the programmer needs to be able to access to take the
code on the input and retrieve the correct name from the table.
- Second, the longest value is 10 characters, so in setting up the table the programmer needs
to make all of the PIC X(10). The VALUEs that do not need ten characters can have spaces added
up the programmer as shown in the example, or the VALUE can be less than 10 while the PIC
remains 10 and COBOL will internally deal with adding the spaces to make the VALUE the
appropriate length.
- Third, the VALUE that goes with the employee type code of 1 is the first entry in the table,
the VALUE that goes with the employee type code of 2 is the second entry in the table etc.
- As an aside, remember that the word FILLER is never required so this table could have been
set up with the PIC and the VALUE clauses only.
To turn the list of names into a table, the programmer first needs to REDEFINE the list of
elements or VALUEs shown in the example above. In the redefinition, the programmer will
use the OCCURS clause to tell how many occurrences there are of the elements or VALUES
defined in the original table layout. In our example there are 4 different elements and
therefore 4 different occurrences. The OCCURS clause is what makes a TABLE. In defining the
number of occurrences, each occurrence or element is given the same field name.
01 EMPLOYEE-TABLE.
05 FILLER PIC X(10) VALUE "FULL TIME ".
05 FILLER PIC X(10) VALUE "PART TIME ".
05 FILLER PIC X(10) VALUE "CONSULTANT".
05 FILLER PIC X(10) VALUE "TEMPORARY ".
01 RDF-EMPLOYEE-TABLE REDEFINES EMPLOYEE-TABLE
05 TYPE-EMP PIC X(10) OCCURS 4 TIMES.
The reason for making each field ten characters long becomes clearer when we look at the
redefinition. The occurs clause says there are 4 elements and the picture says each of these
elements is 10 characters long. The data in memory was set up like this in the original
EMPLOYEE-TABLE.
FULL TIME PART TIME CONSULTANTTEMPORARY
When it is divided by the redefines, think of it as COBOL going and counting 10 characters and
putting a marker to say this is the first occurrence of TYPE-EMP and then going in ten more
characters and putting another marker and saying this is the second occurrence of TYPE-EMP etc.
FULL TIME |PART TIME |CONSULTANT|TEMPORARY |
If the data had been set up as simply the length of the fields, the redefinition would be wrong,
for example:
Invalid definition: FULL TIMEPART TIMECONSULTANTTEMPORARY
Using the redefinition: FULL TIMEP|ART TIMECO|NSULTANTTE|MPORARY
In the invalid definition above, you can see the problem if each field is not 10 characters
long, the redefinition is taking 10 character groupings so the results will be garbage.
Looking at the redefinition, it is clear that each element is given the same name TYPE-EMP and
that since TYPE-EMP OCCURS 4 TIMES there are essentially 4 fields called TYPE-EMP. This
presents a problem, clearly if the programmer wrote a MOVE statement that said MOVE TYPE-EMP
there would be an error condition because there are now four fields called TYPE-EMP and there is
no way of knowing which one the programmer wants to move. The problem is solved with the use
of a SUBSCRIPT. A SUBSCRIPT is essentially a pointer that will be used to tell which TYPE-EMP
field needs to be moved. The SUBSCRIPT is written in parenthesis after the data name - remember,
the data name we are talking about here is the data name that occurs. For example, to move the
elements from the table to a field on the printline called TYPE-EMP-PR, the following statements
could be used:
To move the first element in the table: MOVE TYPE-EMP (1) TO TYPE-EMP-PR.
To move the second element in the table: MOVE TYPE-EMP (2) TO TYPE-EMP-PR.
To move the third element in the table: MOVE TYPE-EMP (3) TO TYPE-EMP-PR.
To move the fourth element in the table: MOVE TYPE-EMP (4) TO TYPE-EMP-PR.
This is not very practical, in actual code, so instead of using the number of the element as the
SUBSCRIPT, the programmer uses a field that contains the code that is to be the SUBSCRIPT. In
our example, that field is the EMP-TYPE-CODE that is on the input file. The move statement
would be:
MOVE TYPE-EMP (EMP-TYPE-CODE) TO TYPE-EMP-PR.
If EMP-TYPE-CODE is 1 then the first element from the table (FULL TIME) will be moved to the
field on the printline, if the EMP-TYPE-CODE is 2 then the second element from the table
(PART TIME) will be moved to the field on the printline. Following this pattern, if the
SUBSCRIPT is 3 then CONSULTANT will be accessed and moved and 4 will result in TEMPORARY being
accessed and moved.
This is a limited example using a SUBSCRIPT with only 4 possible codes, however if there were 25
codes, it is clear that the table approach puts the main burden on the definition in
Working-Storage and allows for a very straight forward coding structure in the Procedure
Division.
In should be noted that TABLES in COBOL are frequently called ARRAYS in other languages.
To further clarify the concept of tables, other examples are illustrated below:
EXAMPLE #1:
The first example is five departments in a clothing store: MENS, WOMENS, INFANTS, GIRLS, BOYS.
Instead of carrying the name of the department on the file, a code number will be assigned to
each name and that code number will be carried on the file. In our example, MENS will have a
code of 1, WOMENS will have a code of 2, INFANTS will have a code of 3, GIRLS will have a code
of 4 and BOYS will have a code of 5. Since the longest of these names is INFANTS at 7
characters, each of the elements in the table will be 7 characters long.
01 DEPT-NAM-TABLE.
05 FILLER PIC X(7) VALUE "MENS ".
05 FILLER PIC X(7) VALUE "WOMENS ".
05 FILLER PIC X(7) VALUE "INFANTS".
05 FILLER PIC X(7) VALUE "GIRLS ".
05 FILLER PIC X(7) VALUE "BOYS ".
01 RDF-DEPT-NAM-TABLE REDEFINES DEPT-NAM-TABLE.
05 DEPT-NAM PIC X(7) OCCURS 5 TIMES.
In this example, there is a field on the input called DEPT-NO which will be used as the
SUBSCRIPT or pointer to take the correct DEPT-NAM from the table and move it to the print line.
FD INPUT-FILE...
01 INPUT-REC.
05 DEPT-NO PIC 9.
In the paragraph or routine where the programmer wants to move the correct department name from
the table to a field on the printline, the input field DEPT-NO is the pointer or SUBSCRIPT. The
move statement will be:
MOVE DEPT-NAM (DEPT-NO) TO DEPT-NAM-PR.
This will work fine as long as we are guaranteed that the data has been edited and that there
will be no number other than 1 through 5 in DEPT-NO. If there is a danger of DEPT-NO being
non-numeric or a number other than 1, 2, 3, 4, or 5, the programmer should include a validity
check, because if the subscript is 0 or the subscript is greater than the number in the OCCURS
clause or if the subscript is non-numeric, the program will ABORT. One way to do this is to use
a level 88 with the DEPT-NO field:
05 DEPT-NO PIC 9.
88 VALID-DEPT-NO VALUE 1 THRU 5.
Then in the routine that moves the department name, the programmer can code the following:
IF VALID-DEPT-NO
MOVE DEPT-NAM (DEPT-NO) TO DEPT-NAM-PR.
This could also be handled without the level 88, by asking the specific questions in the test
for a valid DEPT-NO:
IF DEPT-NO IS NUMERIC
IF DEPT-NO > 0 AND DEPT-NO < 6
MOVE DEPT-NAM (DEPT-NO) TO DEPT-NAM-PR
ELSE
MOVE "INVALID" TO DEPT-NAM-PR
ELSE
MOVE "NOT # " TO DEPT-NAM-PR.
An alternative, but not recommended, way to set up the table used in this example is shown
below:
01 DEPT-NAM-TABLE.
05 FILLER PIC X(35)
VALUE "MENS WOMENS INFANTSGIRLS BOYS ".
01 RDF-DEPT-NAM-TABLE REDEFINES DEPT-NAM-TABLE.
05 DEPT-NAM PIC X(7) OCCURS 5 TIMES.
CAUTION: The literal in the value clause cannot be more than 120 characters.
The data can be set up in any way as long as there is a stream of 35 characters that when
divided into 5 groups of 7 characters each makes sense. Another example could be:
01 DEPT-NAM-TABLE.
05 FILLER PIC X(14) VALUE "MENS WOMENS ".
05 FILLER PIC X(21) VALUE "INFANTSGIRLS BOYS ".
01 RDF-DEPT-NAM-TABLE REDEFINES DEPT-NAM-TABLE.
05 DEPT-NAM PIC X(7) OCCURS 5 TIMES.
NOTE: In each of these table setups, the field that OCCURS is called DEPT-NAM, therefore any of
the MOVE statements issued in the example above would work equally well with any of the table
setups.
EXAMPLE #2:
The second example involves setting up numeric data in the table. For example, lets assume that
we have the following information:
Item # Price
1 $50.00
2 $35.95
3 $25.99
4 $19.99
5 $ 9.95
6 $ 5.00
The item number comes in on the input: 05 ITEM-NO PIC 9.
The programmer need to set up a price table so that the price can be extracted from the table
and printed on the printline. Since the programmer may want to use the price in calculations,
it must be stored as an unedited numeric field. Therefore, the $ will not be used. Remember,
when the programmer sets up constants, and the prices will be constants in the price table, the
decimal point is included to align correctly with the V in the picture clause. Looking at the
pricing information above, it is clear that each price should have room for two whole numbers
and two decimal numbers, so the price should be defined as 99V99. Note also that since these
are numeric constants, there are no quotes around the VALUE leading zero has been included when
the data did not include a digit in the tens position.
01 PRICE-TABLE.
05 FILLER PIC 99V99 VALUE 50.00.
05 FILLER PIC 99V99 VALUE 35.95.
05 FILLER PIC 99V99 VALUE 25.99.
05 FILLER PIC 99V99 VALUE 19.99.
05 FILLER PIC 99V99 VALUE 09.95.
05 FILLER PIC 99V99 VALUE 05.00.
01 RDF-PRICE-TABLE REDEFINES PRICE-TABLE.
05 PRICE PIC 99V99 OCCURS 6 TIMES.
Using this table and the code on the input (ITEM-N0), the programmer can move the item price to
the printline using the following MOVE statement.
MOVE PRICE (ITEM-NO) TO PRICE-PR.
PRICE-PR could be defined as an edited field on the printline with the picture of ZZ.99 or
$ZZ.99 depending on how the programmer wanted to print the price.
An alternative way of setting up the table takes advantage of the fact that the table is a
redefinition of the original data setup:
01 PRICE-TABLE.
05 FILLER PIC 9(4) VALUE 5000.
05 FILLER PIC 9(4) VALUE 3595.
05 FILLER PIC 9(4) VALUE 2599.
05 FILLER PIC 9(4) VALUE 1999.
05 FILLER PIC 9(4) VALUE 0995.
05 FILLER PIC 9(4) VALUE 0500.
01 RDF-PRICE-TABLE REDEFINES PRICE-TABLE.
05 PRICE PIC 99V99 OCCURS 6 TIMES.
In this example, the original numbers were setup as whole numbers. When the redefinition is
done to turn the data into a table, an alternative way of looking at the data is presented by
giving the picture of 99V99. When the data is used by means of referring to PRICE, the picture
of 99V99 will be used which will assume a decimal place between the second and third digits.
PRICE from the table can be used in other ways, For example PRICE could be multiplied by the
field NUMBER-SOLD to get the answer WORTH-WS.
MULTIPLY PRICE(ITEM-NO) BY NUMBER-SOLD
GIVING WORTH-WS.
Example #3:
Suppose that you want to store the department name, and the manager name in the same table so
that when you access the table using the department number from the input record as a subscript,
you can get the information to print out both the department name and the manager name. To do
this, the programmer can put two pieces of information in the table as a unit.
Subscript on the input record: 05 DEPT-NO PIC 9.
01 DEPARTMENT-TABLE
05 FILLER PIC X(17) VALUE "MENS SMITH ".
05 FILLER PIC X(17) VALUE "WOMENS JOHNSON ".
05 FILLER PIC X(17) VALUE "INFANTS LEE ".
05 FILLER PIC X(17) VALUE "GIRLS HALL ".
05 FILLER PIC X(17) VALUE "BOYS WILLIAMSON".
01 RDF-DEPARTMENT-TABLE REDEFINES DEPARTMENT-TABLE.
05 DEPT-GROUP OCCURS 5 TIMES.
10 DEPT-NAME PIC X(7).
10 MANAGER-NAME PIC X(10).
In this table the department name and manager have been grouped together at each 05 level. In
setting up the VALUE clause, the programmer had to determine the longest department name (in
this case INFANTS at 7 characters) and the longest manager name (in this case WILLIAMSON at 10
characters). This means that each PIC is the sum of these lengths or 17 characters. It also
means that the department name uses the first 7 characters and the manager name uses the last 10
characters. The manager name must start in position 8.
When the table is redefined, the department name and manager name are grouped as DEPT-GROUP and
the OCCURS clause tells that there are 5 of these groups (one group for each of the 05 levels in
the original data above the redefines). Because the programmer needs access to the department
name and manager name individually to move them to different fields on the printline, DEPT-GROUP
is broken down into two parts:
DEPT-NAME is the first 7 characters of DEPT-GROUP and MANAGER-NAME is the next 10 characters of
DEPT-GROUP.
The programmer can now use the DEPT-NO on the input record to move the DEPT-NAME and the
MANAGER-NAME to fields on the printline using the following MOVES:
MOVE DEPT-NAME (DEPT-NO) TO DEPT-NAME-PR.
MOVE MANAGER-NAME (DEPT-NO) TO MANAGER-NAME-PR.
If DEPT-NO is 2, the DEPT-NAME will be WOMENS and the MANAGER-NAME will be JOHNSON. These two
fields will be moved to the printline.
If the DEPT-NO is 5, the DEPT-NAME will be BOYS and the MANAGER-NAME will be WILLIAMSON. These
two fields will be moved to the printline.
Example #4:
The company gives a pay bonus depending on job category. The job category code comes in as a
number from 1 to 3 on the input record. The table to give the name of the job category and the
amount of the bonus is set up in WORKING-STORAGE. Using the job category code the programmer
needs to move the job category and the amount of the bonus to the print line.
Input: 05 JOB-CODE PIC 9.
Line: 01 PRINTZ.
...
05 JOB-CATEGORY-PR PIC X(17).
05 FILLER PIC X(10).
05 BONUS-PR PIC $Z,ZZZ.99.
Table in WORKING-STORAGE.
01 JOB-BONUS-TABLE.
05 FILLER PIC X(23) VALUE "UPPER MANAGEMENT 300000".
05 FILLER PIC X(23) VALUE "MIDDLE MANAGEMENT200000".
05 FILLER PIC X(23) VALUE "SUPPORT 100000".
01 RDF-JOB-BONUS-TABLE REDEFINES JOB-BONUS-TABLE.
05 JOB-GROUP OCCURS 3 TIMES.
10 JOB-CATEGORY PIC X(17).
10 BONUS PIC 9(4)V99.
Move statements:
MOVE JOB-CATEGORY (JOB-CODE) TO JOB-CATEGORY-PR.
MOVE BONUS (JOB-CODE) TO BONUS-PR.
Since BONUS is part of an X field in the original data layout, notice that there is no decimal
point in the data. The BONUS data is coded as if it were a whole number. When the table is
redefined, the programmer has the opportunity to redefine the way those 6 numeric characters
that comprise bonus are defined. This redefinition allows the PIC of 9999V99 thereby putting
the assumed decimal point between the fourth and the fifth characters. The programmer could not
have put a decimal point in the original data that was a part of the X picture or it would not
have been interpreted correctly.