CHAPTER 13
Multiple -Le vel Arrays and Table s
OBJECTIVES
To familiarize you with
1.
How to establish a series of items using a double-level
OCCURS
clause.
2.
How to store data in a double-level or two-dimensional array.
3.
How to look up data stored in a double-level or two-dimensional table.
4.
How to access and manipulate data defined with a triple-level (or more)
OCCURS
clause.
CONTENTS
D
OUBLE-L
EVELOCCURS C
LAUSEDefining a Double-Level or Two-Dimensional
Array
Accessing a Double-Level or Two-Dimensional
Array
Using Nested PERFORMs
Using PERFORM ... VARYING ... AFTER
Self-Test
Using a Double-Level or Two-Dimensional
Array for Accumulating Totals
Loading Input Data into a Double-Level or
Two-Dimensional Array
Self-Test
Performing a Look-Up Using a Double-Level
OCCURS
Performing a Full Table Look-Up
Searching Only Part of a Table
Searching Elements in an Array
T
RIPLE-L
EVELOCCURS C
LAUSE ANDM
OREE
ND-
OF-C
HAPTERA
IDS1-AM-TEMP 2-AM-TEMP MIDNIGHT-TEMP
MIDNIGHT-TEMP
MIDNIGHT-TEMP 1-AM-TEMP 2-AM-TEMP 1-AM-TEMP 2-AM-TEMP
DAY 7 (SAT) DAY 2 (MON)
DAY 1 (SUN)
• • • • • • • • • • • •
TEMPERATURE-ARRAY
D
OUBLE
- L
EVEL
OCCURS C
LAUSE
When describing an area of storage, more than one level of
OCCURS
may be used. As
many as seven levels of
OCCURS
are permitted with COBOL 85, and as many as three
levels are permitted with COBOL 74.
Like a single-level
OCCURS
, multiple levels of
OCCURS
may be used for (1)
accumu-lating totals in an
array
or (2) storing a
table
for ‘‘look-up’’ purposes. We will look first
at multiple-level arrays and then at multiple-level tables.
De fining a Do uble - Le ve l o r Tw o - Dime ns io nal Array
Suppose we wish to establish in storage an array of hourly temperature readings for
Los Angeles or any other city
during a given week
. Once the array is established, we will
use it to perform various calculations. The array consists of 7
2
24 temperature
read-ings; that is, there are 24 hourly temperature readings for each of 7 days. The array is
represented as follows:
To define this array in
WORKI NG- STORAGE
with a
single
-level
OCCURS
would require
the following coding:
01 TEMPERATURE- ARRAY.
05 DAY- I N- WEEK OCCURS 7 TI MES.
10 1- AM- TEMP PI C S9( 3) . 10 2- AM- TEMP PI C S9( 3) . .
. .
10 11- PM- TEMP PI C S9( 3) . 10 MI DNI GHT PI C S9( 3) .
The ellipses or dots (...) indicate that 24 elementary items must be coded, which would
be rather cumbersome. Instead, we could use a
double-level
OCCURS
to define the array
as follows:
01 TEMPERATURE- ARRAY.
05 DAY- I N- WEEK OCCURS 7 TI MES. 10 HOUR OCCURS 24 TI MES.
15 TEMP PI C S9( 3) .
The following illustration shows how this array can be visualized in storage:
Hour
TEMPERATURE-
ARRAYDay-in-Week
1
A.
M.
2
A.
M.
3
A.
M.
4
A.
M.
. . .
11
P.
M. 12
MID.
Day 1 (Sun)
. . .
Day 2 (Mon)
. . .
Day 3 (Tue)
. . .
Day 4 (Wed)
. . .
7
ROWS
Day 5 (Thu)
. . .
Day 6 (Fri)
. . .
Day 7 (Sat)
. . .
For each
DAY- I N- WEEK
, we have 24
HOUR
figures, each of which will consist of a
TEMP
(average or mean temperature for that hour) that is three integers long. Thus, this array
defines a storage area of 504 positions (7
2
24
2
3). This
two-dimensional array
is
estab-lished as follows:
1. The array will have 7
rows
as indicated by the first
OCCURS
clause:
05 DAY- I N- WEEK OCCURS 7 TI MES.
2. Within this array, each row will have 24
columns
, as indicated by the second
OCCURS
clause:
10 HOUR OCCURS 24 TI MES.
3. Each of the
elements
in this 7
2
24 array will be large enough to hold three integers,
as indicated by the subordinate entry:
15 TEMP PI C S9( 3) .
To access any of the temperature figures, we use the data-name on the
lowest
OCCURS
level
or any data-name subordinate to it. Either
TEMP
or
HOUR
could be used to access
the temperatures. Because
HOUR
contains only one elementary item,
TEMP
and
HOUR
refer
to the same area of storage. Thus, the array could also have been defined as follows:
Alternative Coding
01 TEMPERATURE- ARRAY.
05 DAY- I N- WEEK OCCURS 7 TI MES.
10 HOUR OCCURS 24 TI MES PI C S9( 3) .
We have added the
PI C
clause to the second
OCCURS
level data-name, thereby
elimi-nating the reference to the data-name
TEMP
.
We will use the entry
TEMP
throughout, however, since it is clearer. Note that we
could
not
use
DAY- I N- WEEK
for accessing a single field in the array, since each
DAY- I
N-WEEK
actually refers to 24 temperatures.
Using Subscripts with Double-Level OCCURS Entries
Since
TEMP
is defined with two
OCCURS
, we must use
two
subscripts to access any hourly
temperature. The first subscript specified refers to the first or
major
-level
OCCURS
clause,
which, in this example, defines the
DAY- I N- WEEK
. The second subscript refers to the
second or
minor
OCCURS
level, which, in this example, defines the
HOUR
. Thus,
TEMP
(
1,
6
) refers to the temperature for Sunday (the first row) at 6
A.
M. (the sixth column in the
array). Assuming there is data in the array, we can display the temperature for Tuesday
at noon with the following instruction:
DI SPLAY ’ TEMPERATURE FOR TUESDAY AT NOON I S ’ , TEMP ( 3, 12) .
Interactive Processing.
Recall that a
DI SPLAY
can be used to display messages on a
screen and is commonly used for interactive processing.
The first subscript can vary from 1 to 7 since there are seven rows, one for each day.
The second subscript varies from 1 to 24, since there are 24 columns, one for each hour
of the day. The following subscripts are
not
valid:
Invalid Subscripts
TEMP
(
8, 4
) The first subscript can vary from 1 through 7.
TEMP
(
6, 25
) The second subscript can vary from 1 through 24.
Hour
Temperature-Array
Day-in-Week
1
A.
M.
2
A.
M.
3
A.
M.
4
A.
M.
. . .
11
P.
M.
12
MID.
Day 1 (Sun)
(1,1)
(1,2)
(1,3)
(1,4)
. . .
(1,23)
(1, 24)
Day 2 (Mon)
(2,1)
(2,2)
(2,3)
(2,4)
. . .
(2,23)
(2,24)
Day 3 (Tue)
(3,1)
(3,2)
(3,3)
(3,4)
. . .
(3,23)
(3, 24)
Day 4 (Wed)
(4,1)
(4,2)
(4,3)
(4,4)
. . .
(4,23)
(4, 24)
Day 5 (Thu)
(5,1)
(5,2)
(5,3)
(5,4)
. . .
(5,23)
(5, 24)
Day 6 (Fri)
(6,1)
(6,2)
(6,3)
(6,4)
. . .
(6,23)
(6, 24)
Day 7 (Sat)
(7,1)
(7,2)
(7,3)
(7,4)
. . .
(7,23)
(7, 24)
The following are rules for using a double-level
OCCURS
:
RULES FOR USING A DOUBLE-LEVEL OCCURS
1. If an item is defined by a
double-level
OCCURS
clause, it must be accessed by
two
subscripts.
2. The first subscript refers to the higher-level
OCCURS
; the second subscript
refers to the lower-level
OCCURS
.
3. The subscripts must be enclosed in parentheses.
4. Subscripts may consist of positive integers or data-names with positive
integer contents.
5. On most systems, the left parenthesis must be preceded by at least one space;
similarly, the right parenthesis must be followed by a period, if it is the end
of a sentence, or at least one space. The first subscript within parentheses is
followed by a comma and a space.
Examples of Invalid Coding
REASON IT IS INVALID (on some systems)
TEMP ( 6, 23) There is no space after the comma
TEMP( SUB1, SUB2) There is no space before the left parenthesis, and there is a space after the left parenthesis
Acce s s ing a Do uble - Le ve l o r Tw o - Dime ns io nal Array
Example 1
Suppose we wish to print an average temperature for the entire week. We need to add all the
array entries to a total and divide by 168 (7
2
24). We can use
nested
PERFORMs for this purpose.
The first
PERFORMvaries the major subscript, which we call
DAY- SUB, and the second
PERFORMvaries the minor subscript, which we call
HOUR- SUB:
600- AVERAGE- RTN. MOVE 0 TO TOTAL.
PERFORM 700- LOOP- ON- DAYS
VARYI NG DAY- SUB FROM 1 BY 1 UNTI L DAY- SUB > 7. COMPUTE WEEKLY- AVERAGE = TOTAL / 168.
WRI TE PRI NT- REC FROM OUT- REC AFTER ADVANCI NG 2 LI NES. 700- LOOP- ON- DAYS.
PERFORM 800- LOOP- ON- HOURS
VARYI NG HOUR- SUB FROM 1 BY 1 UNTI L HOUR- SUB > 24. 800- LOOP- ON- HOURS.
Using in-line
PERFORMs with COBOL 85, we could code the above as:
800- AVERAGE- RTN. MOVE 0 TO TOTAL.
PERFORM VARYI NG DAY- SUB FROM 1 BY 1 UNTI L DAY- SUB > 7 PERFORM VARYI NG HOUR- SUB FROM 1 BY 1 UNTI L HOUR- SUB > 24
ADD TEMP ( DAY- SUB, HOUR- SUB) TO TOTAL END- PERFORM
END- PERFORM.
COMPUTE WEEKLY- AVERAGE = TOTAL / 168. WRI TE PRI NT- REC FROM OUT- REC
AFTER ADVANCI NG 2 LI NES.
When using nested in-line
PERFORMs, there should be
no
periods until after the last
END- PER-FORM. A period would be optional after the last
END- PERFORMunless it was the last word in the
paragraph.
The PERFORM . . . VARYING with the AFTER Option
The following expanded format for the
PERFORM . . .
VARYI NG
will result in nested
PERFORM
s
without the need for two separate
PERFORM . . . VARYI NG
statements
:
Expanded Format
THROUGH
PERFORM
F
procedure-name-1
F
H
THRU
J
procedure-name-2
GG
BEFORE
WI TH TEST
H
JG
F
AFTER
identifier-3
identifier-2
VARYI NG
H
J
FROM
index-name-2
index-name-1
5
6
literal-1
identifier-4
BY
H
J
UNTI L
condition-1
literal-2
identifier-6
identifier-5
AFTER
FROM
index-name-4
F H
index-name-3
J
5
6
literal-3
identifier-7
BY
H
J
UNTI L
condition-2
G
...
literal-4
[ END- PERFORM]
*
*With COBOL 85 only.
This format is particularly useful for processing multiple-level arrays and tables. The
PERFORM . . . VARYI NG
varies the
major subscript
, and the
AFTER
clause varies the
minor
subscript.
Thus, we can simplify the preceding nested
PERFORM
as follows:
Alternative Coding
600- AVERAGE- RTN. MOVE 0 TO TOTAL. PERFORM 700- LOOP1
VARYI NG DAY- SUB FROM 1 BY 1 UNTI L DAY- SUB > 7 AFTER HOUR- SUB FROM 1 BY 1 UNTI L HOUR- SUB > 24. COMPUTE WEEKLY- AVERAGE = TOTAL / 168.
WRI TE PRI NT- REC FROM OUT- REC AFTER ADVANCI NG 2 LI NES. 700- LOOP1.
The sequence of values that these subscripts take on is (1, 1), (1, 2) . . . (1, 24), (2, 1),
(2, 2) . . . (2, 24) . . . (7, 1) . . . (7, 24). That is, with the
PERFORM . . . VARYI NG . . . AFTER,
DAY- SUB
is initialized at 1 and
HOUR- SUB
is varied from 1 to 24. Then
DAY- SUB
is
incre-mented to 2 and
HOUR- SUB
is varied again from 1 to 24. This continues until
HOUR- SUB
is varied from 1 to 24 with
DAY- SUB
at 7.
Example 2
Interactive Processing.
Suppose we want to enable users to make inquiries from the
TEMPERATURE- ARRAY
:
WORKI NG- STORAGE SECTI ON.
01 WS- DAY PI C 9.
01 WS- HOUR. PI C 99. .
.
DI SPLAY ’ ENTER DAY OF WEEK ( 1 = SUN, . . . 7 = SAT) ’ . ACCEPT WS- DAY.
DI SPLAY ’ ENTER HOUR ( 1 = 1 A. M. , . . . 24 = MI DNI GHT) ’ . ACCEPT WS- HOUR.
DI SPLAY ’ THE TEMPERATURE I S ’ , TEMP ( WS- DAY, WS- HOUR) .
Example 3
Consider the following double-level array and assume that data has been read into it:
01 POPULATI ON- ARRAY.
05 STATE OCCURS 50 TI MES. 10 COUNTY OCCURS 10 TI MES.
15 POPULATI ON PI C 9( 10) .
This array defines 500 fields of data or 5000 characters. Each of the 50 states is divided into 10
counties, each with 10 characters. We have arbitrarily selected 10 counties per state, each with a
POPULATI ON
of
9( 10),
for illustration purposes only.
In reality, the number of counties per state
varies from state to state, and counties will have populations that have fewer than 10 digits.
A pictorial representation of the array is as follows:
County
POPULATION-
ARRAYState
County 1
County 2
.
.
.
County 10
1 (Alabama)
(1,1)
(1,2)
. . .
(1,10)
2 (Alaska)
(2,1)
(2,2)
. . .
(2,10)
.
.
.
.
.
.
.
.
.
. . .
. . .
. . .
.
.
.
50 (Wyoming)
(50,1)
(50,2)
. . .
(50,10)
Note:The numbers in parentheses represent the subscripts for each entry.
Suppose we wish to accumulate a total United States population. We will add all 10 counties
for each of 50 states. We access elements in the array by using the lowest level item,
POPULATI ON.
POPULATI ON
must be accessed using
two
subscripts. The first defines the major level,
STATE, and
the second defines the minor level,
COUNTY. POPULATI ON ( 5, 10)refers to the population for
STATE 5
,
COUNTY 10. The first subscript varies from 1 to 50; the second varies from 1 to 10.
To perform the required addition, we will first accumulate all
COUNTYfigures for
STATE 1.
Thus, the second or minor subscript will vary from 1 to 10. After 10 additions for
STATE 1are
performed, we will accumulate the
10 COUNTYfigures for
STATE 2. That is, we will increment the
major subscript to 2 and then add
COUNTY ( 2, 1),
COUNTY ( 2, 2),
. . . COUNTY ( 2, 10)before
we add the figures for
STATE 3.
The required operations may be performed in two ways:
Using Nested PERFORMs
PERFORM 700- USA- TOT. .
. . 700- USA- TOT.
PERFORM 800- MAJ OR- LOOP
VARYI NG STATE- SUB FROM 1 BY 1 UNTI L STATE- SUB > 50. PERFORM 1000- PRI NT- TOTAL.
800- MAJ OR- LOOP.
PERFORM 900- MI NOR- LOOP
VARYI NG COUNTY- SUB FROM 1 BY 1 UNTI L COUNTY- SUB > 10. 900- MI NOR- LOOP.
ADD POPULATI ON ( STATE- SUB, COUNTY- SUB) TO TOTAL1. .
. .
With in-line nested
PERFORM
s, this would be coded as:
PERFORM VARYI NG STATE- SUB FROM 1 BY 1 UNTI L STATE- SUB > 50 PERFORM VARYI NG COUNTY- SUB FROM 1 BY 1
UNTI L COUNTY- SUB > 10 ADD POPULATI ON ( STATE- SUB, COUNTY- SUB)
TO TOTAL1 END- PERFORM END- PERFORM.
PERFORM 1000- PRI NT- TOTAL.
Using PERFORM . . . VARYING . . . AFTER
Using the
AFTER
option of the
PERFORM VARYI NG
, we can simplify the coding as follows:
Alternative Coding
PERFORM 700- USA- TOT. .
. . 700- USA- TOT.
PERFORM 800- ADD- POP
VARYI NG STATE- SUB FROM 1 BY 1 UNTI L STATE- SUB > 50 AFTER COUNTY- SUB FROM 1 BY 1 UNTI L COUNTY- SUB > 10. PERFORM 1000- PRI NT- TOTAL.
800- ADD- POP.
ADD POPULATI ON ( STATE- SUB, COUNTY- SUB) TO TOTAL1.
The following illustrates how this procedure could be coded using an in-line
PERFORM
:
PERFORM VARYI NG STATE- SUB FROM 1 BY 1 UNTI L STATE- SUB > 50 AFTER COUNTY- SUB FROM 1 BY 1 UNTI L COUNTY- SUB > 10 ADD POPULATI ON ( STATE- SUB, COUNTY- SUB)
TO TOTAL1 END- PERFORM
Using either routine, we vary the minor subscript first, holding the major subscript
constant. That is, when the major subscript is equal to 1, denoting
STATE
1, all counties
within that
STATE
are summed. Thus, we set
STATE- SUB
equal to 1 and vary
COUNTY-SUB
from 1 to 10.
STATE- SUB
is then set to 2, and we again vary
COUNTY- SUB
from 1 to
10, and so on.
The sequence of additions may also be performed as follows:
POPULATI ON ( 1, 1)
,
POPULATI ON ( 2, 1) , . . . POPULATI ON ( 50,
1)
;
POPULATI ON ( 1,
2)
,
POPULATI ON
( 2, 2) , . . . POPULATI ON ( 50, 2) , . . . POPULATI ON ( 50, 10)
. That is, we can add
COUNTY- SUB
to 2 and vary
STATE- SUB
from 1 to 50 again, and so on. The following
coding illustrates how this procedure can be performed:
Alternative Coding
PERFORM 700- USA- TOT. .
. .
700- USA- TOT.
PERFORM 800- MAJ OR- LOOP
VARYI NG COUNTY- SUB FROM 1 BY 1 UNTI L COUNTY- SUB > 10. PERFORM 1000- PRI NT- TOTAL.
800- MAJ OR- LOOP.
PERFORM 900- MI NOR- LOOP
VARYI NG STATE- SUB FROM 1 BY 1 UNTI L STATE- SUB > 50. 900- MI NOR- LOOP.
ADD POPULATI ON ( STATE- SUB, COUNTY- SUB) TO TOTAL1.
All the routines illustrated result in the same accumulated population total.
Example 4
Let us establish an array that will contain 12 monthly totals for each of 25 salespeople in Lacy’s
Department Store. Each total represents the accumulated monthly sales amount transacted by a
salesperson. Thus, the first element in the array will be January’s sales total for Salesperson 1,
the second will be February’s sales total for Salesperson 1, and so on.
There are 25 salespeople, each having 12 monthly sales totals, and the salespeople are
num-bered from 1 to 25 consecutively. The
WORKI NG- STORAGE SECTI ONentry for this array is as follows:
01 COMPANY- SALES- ARRAY.
05 SALESPERSON OCCURS 25 TI MES.
10 MONTH- AMT OCCURS 12 TI MES PI C 9( 4) .
The major-level
OCCURSclause indicates that there are 25 salespeople represented in the array.
Each
of the 25 salespeople has
12
monthly sales totals. Thus the array has 300 fields, each four
positions long. We need not store month number or salesperson number since both vary
consec-utively: the former from 1 to 12 and the latter from 1 to 25. This array, then, is a direct-referenced
array.
Assume that data has already been stored in the array. We wish to print 12 lines of monthly
totals. Each line will contain 25 totals, one for each salesperson. Line 1 will contain 25 sales figures
for January. These include array elements
( 1, 1) . . . ( 25, 1)or the January totals for
sales-persons 1 through 25. Line 2 will contain 25 sales totals for February, which would be
( 1, 2) . . . ( 25, 2) ,and so on.
The format of each line to be printed is described in
WORKI NG- STORAGEas follows:
The word
FI LLERis required
with COBOL 74
WORKI NG- STORAGE SECTI ON. 01 SALES- LI NE.
05 PI C X.
05 I TEMX OCCURS 25 TI MES.
10 MONTHLY- SALESPERSON- TOTAL PI C ZZZ9.
10 PI C X.
05 PI C X( 6) .
We use a
single-level
OCCURSclause
to describe the 25 sales totals within
SALES- LI NE. Since
each line will contain 25 salesperson figures, only one
OCCURSclause is necessary. The fact that
there will be 12 lines printed is
not
denoted by an
OCCURSclause, but by repeating the print
routine 12 times.
OCCURSclauses are used to denote repeated occurrences of
fields
, not
records
.
Note that
I TEMX, which
OCCURS 25 TI MES, consists of
two
fields,
MONTHLY- SALESPERSON- TOTALand a one-position blank or
FI LLERarea. This one-position area will separate each of the 25
amount fields to make the entire line more readable. If all the monthly salesperson totals
appeared next to one another, it would be difficult to read the line.
Using a nested
PERFORM, the routine is as follows:
PERFORM 800- WRI TE- RTN
VARYI NG SUB2 FROM 1 BY 1 UNTI L SUB2 > 12. .
. .
800- WRI TE- RTN.
MONTH
SALESPERSON 1 2 3 4 5 6 7 8 9 10 11 12
1
2
25
• • •
Sales for
salesperson 1 salesperson 25Sales for
• • •
• • •
• • •
COMPANY-SALES-ARRAY
SALES FOR MONTH 1
SALES FOR MONTH 12 PERFORM 900- MOVE- RTN
VARYI NG SUB1 FROM 1 BY 1 UNTI L SUB1 > 25. WRI TE PRI NT- REC FROM SALES- LI NE
AFTER ADVANCI NG 2 LI NES. 900- MOVE- RTN.
MOVE MONTH- AMT ( SUB1, SUB2) TO MONTHLY- SALESPERSON- TOTAL ( SUB1) .
What we have done is to take an array that consists of 25 rows and 12 columns and print it out
in an order different from the one in which it is stored:
We use the
same subscript
,
SUB1, to reference the number of the salesperson accessed in
(1)
COMPANY- SALES- ARRAYand in (2) the print line.
In the next section, we will consider how to
ADD
to fields in the array. We end that
section with the program that produces the output specified above.
SELF-TEST
Using the following
TEMPERATURE- ARRAY, code the solutions to Questions 1–5:
01 TEMPERATURE- ARRAY.
05 DAY- I N- WEEK OCCURS 7 TI MES. 10 HOUR OCCURS 24 TI MES.
15 TEMP PI C S9( 3) .
1.
Find the average temperature for Sunday (Day 1).
2.
Find the average weekly temperature for 2
A.
M. (the second column).
3.
Find the day of the week and the hour when the temperature was highest. Also indicate what
the highest temperature was.
4.
Find the number of days when the temperature fell below 32
7
at any hour. Could a
PERFORM. . . VARYI NG . . . AFTER
be used?
5.
Print the average hourly temperatures for each day of the week.
6.
Define a
COMPANY- SALES- ARRAYthat contains a name and 12 monthly amounts for each of
25 salespersons.
Solutions
1.
MOVE 0 TO TOTAL.PERFORM 500- SUNDAY- AVERAGE
VARYI NG X2 FROM 1 BY 1 UNTI L X2 > 24. COMPUTE AVERAGE = TOTAL / 24.
DI SPLAY ’ AVERAGE TEMPERATURE FOR SUNDAY WAS ’ , AVERAGE. .
. .
500- SUNDAY- AVERAGE.
With COBOL 85, we can use an in-line
PERFORMinstead:
MOVE 0 TO TOTAL.
PERFORM VARYI NG X2 FROM 1 BY 1 UNTI L X2 > 24
ADD TEMP ( 1, X2) TO TOTAL END- PERFORM.
COMPUTE AVERAGE = TOTAL / 24.
DI SPLAY ’ AVERAGE TEMPERATURE FOR SUNDAY WAS ’ , AVERAGE.
2.
MOVE 0 TO TOTAL. PERFORM 2- AM- AVERAGEVARYI NG X1 FROM 1 BY 1 UNTI L X1 > 7. COMPUTE AVERAGE = TOTAL / 7.
DI SPLAY ’ THE AVERAGE TEMPERATURE AT 2 AM WAS ’ , AVERAGE. .
. .
2- AM- AVERAGE.
ADD TEMP ( X1, 2) TO TOTAL.
With COBOL 85, we can use an in-line
PERFORMinstead:
MOVE 0 TO TOTAL.
PERFORM VARYI NG X1 FROM 1 BY 1 UNTI L X1 > 7
ADD TEMP ( X1, 2) TO TOTAL END- PERFORM.
COMPUTE AVERAGE = TOTAL / 7.
DI SPLAY ’ THE AVERAGE TEMPERATURE AT 2 AM WAS ’ , AVERAGE.
3.
MOVE 0 TO HOLD- I T, STORE1, STORE2. PERFORM 200- MAJ OR- LOOPVARYI NG X1 FROM 1 BY 1 UNTI L X1 > 7. DI SPLAY ’ HI GHEST TEMPERATURE WAS ’ , HOLD- I T.
DI SPLAY ’ DAY OF WEEK OF HI GHEST TEMPERATURE WAS ’ , STORE1. I F STORE2 < 12
DI SPLAY ’ HOUR OF HI GHEST TEMPERATURE WAS ’ , STORE2, ’ AM’ ELSE I F STORE2 > 12 AND < 24
SUBTRACT 12 FROM STORE2
DI SPLAY ’ HOUR OF HI GHEST TEMPERATURE WAS ’ , STORE2, ’ PM’ ELSE I F STORE2 = 12
DI SPLAY ’ HOUR OF HI GHEST TEMPERATURE WAS NOON’ ELSE
DI SPLAY ’ HOUR OF HI GHEST TEMPERATURE WAS MI DNI GHT’ .
. .
200- MAJ OR- LOOP.
PERFORM 300- MI NOR- LOOP
VARYI NG X2 FROM 1 BY 1 UNTI L X2 > 24. 300- MI NOR- LOOP.
I F TEMP ( X1, X2) > HOLD- I T MOVE TEMP ( X1, X2) TO HOLD- I T MOVE X1 TO STORE1
MOVE X2 TO STORE2
END- I F.
We could replace the first
PERFORMwith the following and eliminate
200- MAJ OR- LOOPentirely:
PERFORM 300- MI NOR- LOOP
VARYI NG X1 FROM 1 BY 1 UNTI L X1 > 7 AFTER X2 FROM 1 BY 1 UNTI L X2 > 24.
01 DAYS VALUE ’ SUNMONTUEWEDTHUFRI SAT’ .
05 DAY- OF- THE- WEEK OCCURS 7 TI MES PI C X( 3) .
The second
DI SPLAYwould then change as follows:
DI SPLAY ’ DAY OF WEEK OF HI GHEST TEMPERATURE WAS ’ , DAY- OF- THE- WEEK ( STORE1) .
For COBOL 74, the
WORKI NG- STORAGEentry would require a
REDEFI NES:
01 DAYS.
05 DAY- VALUE PI C X( 21)
VALUE ’ SUNMONTUEWEDTHUFRI SAT’ . 05 DAY- OF- THE- WEEK REDEFI NES DAY- VALUE
OCCURS 7 TI MES PI C X( 3) .
4.
MOVE 0 TO COUNTER. PERFORM 200- MAJ OR- LOOPVARYI NG X1 FROM 1 BY 1 UNTI L X1 > 7.
DI SPLAY ’ NUMBER OF DAYS WHEN TEMPERATURE < 32 WAS ’ , COUNTER.
. . .
200- MAJ OR- LOOP.
MOVE ’ NO ’ TO FOUND. PERFORM 300- MI NOR- LOOP
VARYI NG X2 FROM 1 BY 1 UNTI L X2 > 24 OR FOUND = ’ YES’ .
300- MI NOR- LOOP.
I F TEMP ( X1, X2) < 32 ADD 1 TO COUNTER MOVE ’ YES’ TO FOUND
END- I F.
We use a field called
FOUNDto terminate processing of
300- MI NOR- LOOPwhen we find an
hour in any day when the temperature falls below 32
7
. Because
FOUNDhas one value
( ’ NO ’ )
when no match has been found, and another value
( ’ YES’ )when a match occurs,
we call this field a switch or flag. Once we find a temperature lower than 32, we need not
check the rest of the hours during that day.
A
PERFORM . . . VARYI NG . . . AFTERcould
not
be used because
200- MAJ OR- LOOPhas an
operation to be performed
in addition to
varying the minor subscript. That is,
PERFORM . . . VARYI NG . . . AFTERis used when you want to process all array elements together; when you
need to stop, print, or
MOVE ’ N0 ’ TO FOUNDbefore or after a row in an array is processed,
then this option cannot be used.
5.
Note:
Use
01 DAYSestablished for Question 3 if an abbreviation for the day
( SUN . . . SAT)is to print rather than the day number.
PERFORM 500- PRI NT- RTN
VARYI NG X1 FROM 1 BY 1 UNTI L X1 > 7. .
. .
500- PRI NT- RTN. MOVE 0 TO TOTAL. PERFORM 600- MI NOR- LOOP
VARYI NG X2 FROM 1 BY 1 UNTI L X2 > 24. MOVE DAY- OF- THE- WEEK ( X1) TO DAY- OUT. COMPUTE AVERAGE- OUT = TOTAL / 24. WRI TE PRI NT- REC FROM OUT- REC
AFTER ADVANCI NG 2 LI NES. 600- MI NOR- LOOP.
ADD TEMP ( X1, X2) TO TOTAL.
6.
01 COMPANY- SALES- ARRAY.05 SALESPERSON OCCURS 25 TI MES.
10 NAME PI C X( 20) .
Us ing a Do uble - Le ve l o r Tw o - Dime ns io nal Array fo r Accumulating To tals
Suppose a company has 10 departments and five salespeople (numbered 1–5) within
each department. We wish to accumulate the total amount of sales for each salesperson
within each department:
01 DEPT- TOTALS.
05 DEPT OCCURS 10 TI MES.
10 SALESPERSON OCCURS 5 TI MES.
15 TOTAL- SALES PI C 9( 5) V99.
Before adding any data to a total area, we must ensure that the total area is initialized
at zero. To initialize an entire array at zero, we could code the following with COBOL
85:
MOVE ZEROS TO DEPT- TOTALS
. Alternatively, with COBOL 85 we can code:
01 DEPT- TOTALS VALUE ZEROS.
If your compiler permits you to reference
DEPT- TOTALS
in the
PROCEDURE DI VI SI ON
,
moving
ZEROS
to
DEPT- TOTALS
replaces all fields with 0; note, however, that
MOVE 0
TO DEPT- TOTALS
only moves a 0 to the leftmost position in the array. This is because
DEPT- TOTALS
, as a group item, is treated as an alphanumeric field; if you move a single
0 to an alphanumeric field, the 0 is placed in the leftmost position; all other positions
are replaced with blanks.
With COBOL 74, however, you may not reference the
01
array entry itself. In such
a case, you must code a full initializing routine prior to adding to
TOTAL- SALES
. We
will use either nested
PERFORM
s or a
PERFORM
with the
AFTER
option in our illustrations:
PERFORM 700- I NI TI ALI ZE- RTN
VARYI NG X1 FROM 1 BY 1 UNTI L X1 > 10 AFTER X2 FROM 1 BY 1 UNTI L X2 > 5. .
. .
700- I NI TI ALI ZE- RTN.
MOVE 0 TO TOTAL- SALES ( X1, X2) .
This routine, which initializes each
TOTAL- SALES
field separately, will run on all
computers; COBOL 85 compilers, however, will allow you to code
MOVE ZEROS TO
DEPT- TOTALS
.
Assume an input record has been created each time a salesperson makes a sale. Each
input record contains a department number called
DEPT- I N
, a salesperson number
called
SALESPERSON- NO- I N
, and an amount of sales called
AMT- I N
. There may be
nu-merous input records for a salesperson if he or she made more than one sale. The coding
to accumulate the totals after the array has been initialized at zero is as follows:
READ SALES- FI LE
AT END MOVE ’ NO ’ TO ARE- THERE- MORE- RECORDS
END- READ.
PERFORM 200- ADD- RTN
UNTI L ARE- THERE- MORE- RECORDS = ’ NO ’ . .
. .
200- ADD- RTN.
ADD AMT- I N TO TOTAL- SALES ( DEPT- I N, SALESPERSON- NO- I N) . READ SALES- FI LE
AT END MOVE ’ NO ’ TO ARE- THERE- MORE- RECORDS
END- READ.
As indicated previously, input fields may be used as subscripts. For correct
process-ing, a validation procedure should be used to ensure that (1)
DEPT- I N
is an integer
between 1 and 10 and (2)
SALESPERSON- NO- I N
is an integer between 1 and 5. We should
also check that
AMT- I N
is numeric:
200- ADD- RTN.
I F AMT- I N I S NUMERI C
AND ( DEPT- I N >= 1 AND <= 10)
SALESPERSON NO
1
DATE
6
5 11
MO DA YR 3
2
SALES AMOUNT
ADD AMT- I N TO TOTAL- SALES ( DEPT- I N, SALESPERSON- NO- I N) ELSE
DI SPLAY ’ ERROR’
END- I F.
READ SALES- FI LE
AT END MOVE ’ NO ’ TO ARE- THERE- MORE- RECORDS
END- READ.
At the end of the job, we wish to print 10 pages of output. Each page will contain
five lines, one for each salesperson in a given department. The full
PROCEDURE DI VI SI ON
is as follows:
PROCEDURE DI VI SI ON. 100- MAI N- MODULE.
OPEN I NPUT SALES- FI LE OUTPUT PRI NT- FI LE. MOVE ZEROS TO DEPT- TOTALS. READ SALES- FI LE
AT END MOVE ’ NO ’ TO ARE- THERE- MORE- RECORDS
END- READ.
PERFORM 200- ADD- RTN UNTI L NO- MORE- RECORDS. PERFORM 300- PRI NT- RTN
VARYI NG X1 FROM 1 BY 1 UNTI L X1 > 10. CLOSE SALES- FI LE
PRI NT- FI LE. STOP RUN.
200- ADD- RTN.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * NOTE: AMT- I N, DEPT- I N, SALESPERSON- NO- I N ARE I NPUT FI ELDS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
I F AMT- I N I S NUMERI C
AND ( DEPT- I N >= 1 AND <= 10)
AND ( SALESPERSON- NO- I N >= 1 AND <= 5)
ADD AMT- I N TO TOTAL- SALES ( DEPT- I N, SALESPERSON- NO- I N) ELSE
DI SPLAY ’ ERROR’
END- I F.
READ SALES- FI LE
AT END MOVE ’ NO ’ TO ARE- THERE- MORE- RECORDS
END- READ.
300- PRI NT- RTN.
MOVE X1 TO DEPT- NO- ON- HDG- LI NE. WRI TE PRI NT- REC FROM HDG- LI NE
AFTER ADVANCI NG PAGE. PERFORM 400- LI NE- PRI NT
VARYI NG X2 FROM 1 BY 1 UNTI L X2 > 5. 400- LI NE- PRI NT.
MOVE X2 TO SALESPERSON- NO- OUT.
MOVE TOTAL- SALES ( X1, X2) TO TOTAL- OUT. WRI TE PRI NT- REC FROM SALES- LI NE- REC
AFTER ADVANCI NG 2 LI NES.
In this illustration, we assume that the values for
DEPT- I N
vary from 1–10 and the
values for
SALESPERSON- NO- I N
vary from 1–5. If either or both of these fields have
values other than 1–10 or 1–5 consecutively, then the numbers themselves must be
stored along with the
TOTAL- SALES
.
The full program for printing monthly sales totals that uses procedures discussed in
this section appears in Figure 13.1.
I DENTI FI CATI ON DI VI SI ON. PROGRAM- I D. FI G131. ENVI RONMENT DI VI SI ON. I NPUT- OUTPUT SECTI ON. FI LE- CONTROL.
SELECT SALES- FI LE ASSI GN TO ’ S1. DAT’ .
SELECT REPORT- FI LE ASSI GN TO PRI NTER ’ P1. OUT’ . DATA DI VI SI ON.
FI LE SECTI ON. FD SALES- FI LE
LABEL RECORDS ARE STANDARD. 01 SALES- REC.
05 SALESPERSON- NO- I N PI C 99. 05 SALES- AMT- I N PI C 999. 05 DATE- OF- TRANS.
10 MONTH- I N PI C 99.
10 DAY- I N PI C 99.
10 YEAR- I N PI C 99. FD REPORT- FI LE
LABEL RECORDS ARE OMI TTED.
01 PRI NT- REC PI C X( 132) .
WORKI NG- STORAGE SECTI ON.
01 MORE- RECS PI C X( 3) VALUE ’ YES’ . 01 COMPANY- SALES- ARRAY.
05 SALESPERSON OCCURS 25 TI MES.
10 MONTH- AMT OCCURS 12 TI MES PI C 9( 4) . 01 HEADI NG- REC.
05 PI C X( 30)
VALUE SPACES.
05 PI C X( 102)
VALUE ’ ANNUAL SALES REPORT’ . 01 COLUMN- HEADI NG.
05 PI C X( 43)
VALUE ’ S1 S2 S3 S4 S5 S6 S7 S8 ’ .
05 PI C X( 39)
VALUE ’ S9 S10 S11 S12 S13 S14 S15 S16 ’ .
05 PI C X( 50)
VALUE ’ S17 S18 S19 S20 S21 S22 S23 S24 S25’ . 01 SALES- LI NE.
05 PI C X.
05 I TEMX OCCURS 25 TI MES.
10 SALES- I TEM PI C ZZZ9.
10 PI C X.
05 PI C X( 6) .
01 SUB1 PI C 99.
01 SUB2 PI C 99.
PROCEDURE DI VI SI ON. 100- MAI N.
OPEN I NPUT SALES- FI LE OUTPUT REPORT- FI LE.
WRI TE PRI NT- REC FROM HEADI NG- REC AFTER ADVANCI NG PAGE.
WRI TE PRI NT- REC FROM COLUMN- HEADI NG AFTER ADVANCI NG 3 LI NES.
MOVE ZEROS TO COMPANY- SALES- ARRAY. READ SALES- FI LE
AT END MOVE ’ NO ’ TO MORE- RECS
END- READ.
PERFORM 200- CALC- RTN
UNTI L MORE- RECS = ’ NO ’ . PERFORM 800- WRI TE- RTN
VARYI NG SUB2 FROM 1 BY 1 UNTI L SUB2 > 12. CLOSE SALES- FI LE
[image:14.612.179.493.93.750.2]REPORT- FI LE.
Figure 13.1
STOP RUN. 200- CALC- RTN.
I F MONTH- I N >= 1 AND <= 12
AND SALESPERSON- NO- I N >= 1 AND <= 25 ADD SALES- AMT- I N TO
MONTH- AMT ( SALESPERSON- NO- I N, MONTH- I N) ELSE
DI SPLAY ’ ERROR ’ , SALES- REC
END- I F.
READ SALES- FI LE
AT END MOVE ’ NO ’ TO MORE- RECS
END- READ.
800- WRI TE- RTN.
MOVE SPACES TO SALES- LI NE. PERFORM 900- MOVE- RTN
VARYI NG SUB1 FROM 1 BY 1 UNTI L SUB1 > 25. WRI TE PRI NT- REC FROM SALES- LI NE
AFTER ADVANCI NG 2 LI NES. 900- MOVE- RTN.
MOVE MONTH- AMT ( SUB1, SUB2) TO SALES- I TEM ( SUB1) .
Lo ading Input Data into a Do uble - Le ve l o r Tw o - Dime ns io nal Array
To load data such as temperatures or populations into an array, we may use a
READ
statement and then move the data to the array. In place of
READ
and
MOVE
statements,
we could use a
READ . . . I NTO
.
Consider again our
TEMPERATURE- ARRAY
from the beginning of this chapter:
01 TEMPERATURE- ARRAY.
05 DAY- I N- WEEK OCCURS 7 TI MES. 10 HOUR OCCURS 24 TI MES.
15 TEMP PI C S9( 3) .
Suppose we have seven input records, each with 24 three-position hourly
tempera-tures. The first input record to be loaded into the array is for Day 1 or Sunday, the
second is for Day 2 or Monday, and so on:
FD TEMP- FI LE
LABEL RECORDS ARE OMI TTED. 01 I N- REC.
05 HOURLY- TEMP OCCURS 24 TI MES PI C S9( 3) .
The
ARRAY- LOAD
routine could be executed as follows. We use subscript names here
that are more meaningful than
X1
and
X2
:
READ TEMP- FI LE
AT END PERFORM 600- ERR- RTN
END- READ.
PERFORM 200- ARRAY- LOAD
VARYI NG DAY- SUB FROM 1 BY 1 UNTI L DAY- SUB > 7 OR NO- MORE- RECORDS.
I F ARE- THERE- MORE- RECORDS = ’ YES’ OR DAY- SUB NOT > 7 PERFORM 600- ERR- RTN
END- I F.
. . .
200- ARRAY- LOAD.
PERFORM 300- MI NOR- LOAD
VARYI NG HOUR- SUB FROM 1 BY 1 UNTI L HOUR- SUB > 24. READ TEMP- FI LE
AT END MOVE ’ NO ’ TO ARE- THERE- MORE- RECORDS
END- READ.
300- MI NOR- LOAD.
STATE
NO COUNTYNO POPULATION-IN
1 2 3 4 5 14
COUNTY 1 POP
1 20 91 100
COUNTY 2 POP
COUNTY 10 POP • • •
11 10
10 491 500
STATE 1 POP
STATE 50 POP • • •
1
If there are not exactly seven records in
TEMP- FI LE
,
600- ERR- RTN
will be executed,
which terminates the job. The
END- READ
and
END- I F
scope terminators are valid with
COBOL 85; with older compilers omit the scope terminators and end the previous line
with a period.
SELF-TEST
Consider our population array:
01 POPULATI ON- ARRAY.
05 STATE OCCURS 50 TI MES. 10 COUNTY OCCURS 10 TI MES.
15 POPULATI ON PI C 9( 10) .
1.
Assume there are 500 input records with the following format:
Write a routine to load each record into the
POPULATI ON- ARRAY.
2.
Assume the input records have the following format:
There are 50 such records, where the first record is for
STATE1, the second is for
STATE2,
and so on. Write a routine to load each record into the
POPULATI ON- ARRAY.
3.
Assume the input records have the following format:
There are 10 such records, where the first record is for
COUNTY1, the second is for
COUNTY2,
and so on. Write a routine to load each record into the
POPULATI ON- ARRAY.
4.
Suppose records were read with the format specified in Question 2 and we want to print a
report as follows:
STATE STATE- POP
1 . . . 50
Z, ZZZ, ZZZ, ZZZ. . . Z, ZZZ, ZZZ, ZZZ
What type of array would we need in
WORKI NG- STORAGEto print the 50 state population
totals?
5.
Suppose records were read with the format specified in Question 3 and we want to print a
COUNTY POPULATI ON
1 . . . 10
Z, ZZZ, ZZZ, ZZZ. . . Z, ZZZ, ZZZ, ZZZ
What type of array would we need in
WORKI NG- STORAGEto process the data?
Solutions
1.
PERFORM 500 TI MESREAD I N- FI LE
AT END DI SPLAY ’ NOT ENOUGH RECORDS’ STOP RUN
END- READ
I F STATE- NO >= 1 AND <= 50 AND COUNTY >= 1 AND <= 10 PERFORM 200- LOAD
ELSE
DI SPLAY ’ ERROR I N STATE OR COUNTY NO’
END- I F END- PERFORM.
200- LOAD.
MOVE POPULATI ON- I N TO POPULATI ON ( STATE- NO, COUNTY- NO) .
With COBOL 85, we can use a different in-line
PERFORMinstead:
PERFORM 500 TI MES READ I N- FI LE
AT END DI SPLAY ’ NOT ENOUGH RECORDS’ STOP RUN
END- READ
I F STATE- NO >= 1 AND STATE- NO <= 50 AND COUNTY >= 1 AND COUNTY <= 10
MOVE POPULATI ON- I N TO POPULATI ON ( STATE- NO, COUNTY- NO) ELSE
DI SPLAY ’ ERROR I N STATE OR COUNTY NO’
END- I F END- PERFORM.
2.
The input file is defined as follows:
FD I N- FI LE LABEL RECORDS ARE STANDARD. 01 I N- REC.
05 COUNTY- I N- POP OCCURS 10 TI MES PI C 9( 10) .
The procedure to input records with in-line
PERFORMs is as follows:
PERFORM VARYI NG STATE- NO
FROM 1 BY 1 UNTI L STATE- NO > 50 READ I N- FI LE
AT END DI SPLAY ’ NOT ENOUGH I NPUT’ STOP RUN
END- READ
PERFORM VARYI NG COUNTY- NO
FROM 1 BY 1 UNTI L COUNTY- NO > 10 MOVE COUNTY- I N- POP ( COUNTY- NO)
TO POPULATI ON ( STATE- NO, COUNTY- NO)
END- PERFORM END- PERFORM.
3.
The input file is defined as follows:
FD I N- FI LE LABEL RECORDS ARE STANDARD. 01 I N- REC.
05 STATE- POP OCCURS 50 TI MES PI C 9( 10) .
The procedure to input records with in-line
PERFORMs is as follows:
PERFORM VARYI NG COUNTY- NO
AT END DI SPLAY ’ NOT ENOUGH I NPUT’ STOP RUN
END- READ
PERFORM VARYI NG STATE- NO
FROM 1 BY 1 UNTI L STATE- NO > 50 MOVE STATE- POP ( STATE- NO)
TO POPULATI ON ( STATE- NO, COUNTY- NO)
END- PERFORM END- PERFORM.
4.
There would be no need to accumulate totals in an array at all. The 10 county population
figures for the first record would be added and printed as the
STATE- POPfor
STATE1. The
next record would be read and the procedure repeated for
STATE2.
5.
Records are entered in such a way that all input would need to be stored
before
any state
totals could print. The
POPULATI ON- ARRAYspecified at the start of the Self-Test would be
used.
Pe rfo rming a Lo o k- Up Us ing a Do uble - Le ve l OCCURS
Performing a Full Table Look-Up
We will use a double-level
OCCURS
entry to define a table and then use a
SEARCH
to
perform a table look-up.
Example
Assume that the following table has been loaded into storage:
01 I NVENTORY- TABLE.05 WAREHOUSE OCCURS 50 TI MES. 10 I TEM- X OCCURS 100 TI MES.
15 PART- NO PI C 9( 4) . 15 UNI T- PRI CE PI C 999V99.
There are 50 warehouses, and each stores 100 items. Each warehouse stocks its own inventory,
which is different from the inventory at other warehouses. This means that a specific
PART- NOwill appear
only once
in the table. There are 5000 table records, each with a warehouse number,
part number, and unit price. The first table record refers to warehouse 1, part number 1; the next
to warehouse 1, part number 2; the 101st to warehouse 2, part number 1, and so on.
Suppose that input transaction records have the following format:
1- 4 PART- NO- I N 5- 6 QTY- ORDERED
For each
PART- NO- I Nin a transaction record, we need to look up the corresponding
PART- NOin
the table and find its
UNI T- PRI CE. We store the unit price for each part in the table and
not
in the
transaction record for the following reasons:
1. If each input transaction record contained a unit price, we would be keying unit price each
time a part was ordered. This would increase both keying costs and the risk of input errors.
2. Changes to unit prices can be more easily made to a relatively small number of table entries
than to a large number of input transaction records.
We store prices in an external table, which is in a file and is loaded in, rather than in an internal
table, which is established with
VALUEclauses. External tables are used for this type of application
because the table elements themselves are likely to change with some frequency. That is, because
we anticipate that unit prices may change, we establish the
I NVENTORY- TABLEas an external table
that can be changed, when needed, by a separate program. If we defined it as an internal table
with
VALUEclauses, we would need to modify and recompile our look-up program each time a
change to unit price occurred.
The output from this program will be a printed transaction report. Each time a
PART- NOis
ordered, we will print the
PART- NOand the
TOTAL- AMTof the transaction, where
TOTAL- AMT = QTY- ORDERED(from the transaction record)
2
UNI T- PRI CE(from the table). Since we will use a
SEARCH
, the table we have described must include the appropriate
I NDEXED BYclauses with each
01 I NVENTORY- TABLE.
05 WAREHOUSE OCCURS 50 TI MES I NDEXED BY X1. 10 I TEM- X OCCURS 100 TI MES I NDEXED BY X2.
15 PART- NO PI C 9( 4) . 15 UNI T- PRI CE PI C 999V99.
The Identifier Used with the SEARCH Refers to the Lowest-Level OCCURS Entry
To
SEARCH
the table, we code
SEARCH I TEM- X . . .
because
I TEM- X
is the
lowest-level
OCCURS
entry
.
Note that
SEARCH I TEM- X
increments the lowest-level index only
. Hence if
X1
is set to 1 initially, the
SEARCH
will perform a look-up on items in warehouse 1 only,
that is (1, 1) through (1, 100). To search
all
warehouses, the
SEARCH
itself must be
exe-cuted from a
PERFORM . . . VARYI NG
that increments the major index,
X1
.
The routine would then appear as follows:
MOVE ’ NO ’ TO MATCH- FOUND. PERFORM 500- SEARCH- I T
VARYI NG X1 FROM 1 BY 1
UNTI L X1 > 50 OR MATCH- FOUND = ’ YES’ . I F MATCH- FOUND = ’ YES’
WRI TE OUT- REC FROM TRANS- REC- OUT AFTER ADVANCI NG 2 LI NES ELSE
PERFORM 600- NO- MATCH- ERR
END- I F.
. . .
500- SEARCH- I T. SET X2 TO 1.
SEARCH I TEM- XkˆˆˆˆˆˆUse lowest-level OCCURS level here
WHEN PART- NO- I N = PART- NO ( X1, X2)
MULTI PLY UNI T- PRI CE ( X1, X2) BY QTY- ORDERED GI VI NG TOTAL- AMT
MOVE ’ YES’ TO MATCH- FOUNDkˆˆEnables 500-SEARCH-IT to be
terminated properly when a match is found
END- SEARCH.
MATCH- FOUND
is a field that is initialized at
’ NO ’
and changed to
’ YES’
only when
the corresponding
PART- NO
in the table is found. We terminate
500- SEARCH- I T
when
a match is found
( MATCH- FOUND = ’ YES’ )
or the entire table has been searched
( X1 >
50) . 600- NO- MATCH- ERR
would be executed only if no match existed between the
PART-NO- I N
and a table entry.
The full program for this example appears in Figure 13.2.
I DENTI FI CATI ON DI VI SI ON. PROGRAM- I D. FI G13- 2. *
ENVI RONMENT DI VI SI ON. I NPUT- OUTPUT SECTI ON. FI LE- CONTROL.
SELECT I NVENTORY- TABLE- I N ASSI GN TO DI SK1. SELECT TRANSACTI ON- FI LE ASSI GN TO DI SK2. SELECT REPORT- OUT ASSI GN TO SYS$OUTPUT. *
DATA DI VI SI ON. FI LE SECTI ON.
FD I NVENTORY- TABLE- I N
LABEL RECORDS ARE STANDARD. 01 I NVENTORY- TABLE- REC.
05 T- WAREHOUSE- NO PI C 99.
05 T- PART- NO PI C 9999.
05 T- UNI T- PRI CE PI C 999V99. FD TRANSACTI ON- FI LE
LABEL RECORDS ARE STANDARD. 01 TRANSACTI ON- REC.
05 PART- NO- I N PI C 9999.
[image:19.612.187.512.218.430.2]05 QTY- ORDERED PI C 99.
Figure 13.2
Figure 13.2
(continued)
05 PI C X( 14) .
FD REPORT- OUT
LABEL RECORDS ARE OMI TTED.
01 OUT- REC PI C X( 132) .
WORKI NG- STORAGE SECTI ON. 01 WS- AREAS.
05 ARE- THERE- MORE- RECORDS PI C X( 3) VALUE ’ YES’ . 88 NO- MORE- RECORDS VALUE ’ NO ’ . 05 MATCH- FOUND PI C X( 3) VALUE ’ NO ’ . 01 I NVENTORY- TABLE.
05 WAREHOUSE OCCURS 50 TI MES I NDEXED BY X1. 10 I TEM- X OCCURS 100 TI MES I NDEXED BY X2.
15 PART- NO PI C 9( 4) . 15 UNI T- PRI CE PI C 999V99. 01 TRANS- REC- OUT.
05 PI C X( 9) VALUE SPACES.
05 PART- NO- OUT PI C 9( 4) .
05 PI C X( 5) VALUE SPACES.
05 QTY- OUT PI C 999.
05 PI C X( 5) VALUE SPACES.
05 TOTAL- AMT PI C $ZZZ, ZZZ. 99.
05 PI C X( 95) VALUE SPACES.
01 ERR- REC.
05 PI C X( 9) VALUE SPACES.
05 ERR- PART PI C 9( 4) .
05 PI C X( 5) VALUE SPACES.
05 PI C X( 114)
VALUE ’ PART NUMBER I S NOT I N TABLE’ . 01 HEADI NG- 1.
05 PI C X( 12) VALUE SPACES.
05 PI C X( 120)
VALUE ’ I NVENTORY REPORT’ . 01 HEADI NG- 2.
05 PI C X( 18)
VALUE ’ PART NO’ .
05 PI C X( 9) VALUE ’ QTY’ .
05 PI C X( 105)
VALUE ’ TOTAL AMT’ . *
PROCEDURE DI VI SI ON. 100- MAI N- MODULE.
PERFORM 700- I NI TI ALI ZATI ON- RTN. READ I NVENTORY- TABLE- I N
AT END MOVE ’ NO ’ TO ARE- THERE- MORE- RECORDS
END- READ.
PERFORM 200- TABLE- LOAD
VARYI NG X1 FROM 1 BY 1 UNTI L X1 > 50. MOVE ’ YES’ TO ARE- THERE- MORE- RECORDS. READ TRANSACTI ON- FI LE
AT END MOVE ’ NO ’ TO ARE- THERE- MORE- RECORDS
END- READ.
PERFORM 400- CALC- RTN UNTI L NO- MORE- RECORDS. PERFORM 800- END- OF- J OB- RTN. STOP RUN.
200- TABLE- LOAD.
PERFORM 300- LOAD- I T
VARYI NG X2 FROM 1 BY 1 UNTI L X2 > 100. 300- LOAD- I T.
I F T- WAREHOUSE- NO NOT EQUAL TO X1 DI SPLAY ’ TABLE I S NOT I N SEQUENCE’ CLOSE I NVENTORY- TABLE- I N
Figure 13.2
(continued)
END- I F.
MOVE T- PART- NO TO PART- NO ( X1, X2) . MOVE T- UNI T- PRI CE TO UNI T- PRI CE ( X1, X2) . READ I NVENTORY- TABLE- I N
AT END MOVE ’ NO ’ TO ARE- THERE- MORE- RECORDS
END- READ.
400- CALC- RTN.
MOVE PART- NO- I N TO PART- NO- OUT. MOVE QTY- ORDERED TO QTY- OUT. MOVE ’ NO ’ TO MATCH- FOUND. PERFORM 500- SEARCH- I T
VARYI NG X1 FROM 1 BY 1 UNTI L X1 > 50
OR MATCH- FOUND = ’ YES’ . I F MATCH- FOUND = ’ YES’
WRI TE OUT- REC FROM TRANS- REC- OUT AFTER ADVANCI NG 2 LI NES ELSE
PERFORM 600- NO- MATCH- ERR
END- I F.
READ TRANSACTI ON- FI LE
AT END MOVE ’ NO ’ TO ARE- THERE- MORE- RECORDS
END- READ.
500- SEARCH- I T. SET X2 TO 1. SEARCH I TEM- X
WHEN PART- NO- I N = PART- NO ( X1, X2)
MULTI PLY UNI T- PRI CE ( X1, X2) BY QTY- ORDERED GI VI NG TOTAL- AMT
MOVE ’ YES’ TO MATCH- FOUND
END- SEARCH.
600- NO- MATCH- ERR.
MOVE PART- NO- I N TO ERR- PART. WRI TE OUT- REC FROM ERR- REC
AFTER ADVANCI NG 2 LI NES. 700- I NI TI ALI ZATI ON- RTN.
OPEN I NPUT I NVENTORY- TABLE- I N TRANSACTI ON- FI LE OUTPUT REPORT- OUT.
WRI TE OUT- REC FROM HEADI NG- 1 AFTER ADVANCI NG PAGE. WRI TE OUT- REC FROM HEADI NG- 2 AFTER ADVANCI NG 2 LI NES. 800- END- OF- J OB- RTN.
CLOSE I NVENTORY- TABLE- I N TRANSACTI ON- FI LE REPORT- OUT.
Note:Use scope t ermi nat ors (whi ch are i n col or) wi t h COBOL 8 5 onl y. Ot herwi se omi t t hem and end precedi ng l i nes wi t h a peri od.
Alternatively, we could use a
PERFORM . . .
VARYI NG . . .
AFTER
for searching the
table:
400- CALC- RTN.
MOVE PART- NO- I N TO PART- NO- OUT. MOVE QTY- ORDERED TO QTY- OUT. MOVE ’ NO ’ TO MATCH- FOUND. PERFORM
VARYI NG X1 FROM 1 BY 1
UNTI L X1 > 50 OR MATCH- FOUND = ’ YES’ AFTER X2 FROM 1 BY 1
UNTI L X2 > 100 OR MATCH- FOUND = ’ YES’ I F PART- NO- I N = PART- NO ( X1, X2)
MULTI PLY UNI T- PRI CE ( X1, X2) BY QTY- ORDERED
END- I F END- PERFORM.
I F MATCH- FOUND = ’ YES’
WRI TE OUT- REC FROM TRANS- REC- OUT AFTER ADVANCI NG 2 LI NES ELSE
PERFORM 600- NO- MATCH- ERR
END- I F.
READ TRANSACTI ON- FI LE
AT END MOVE ’ NO ’ TO ARE- THERE- MORE- RECORDS
END- READ.
Using the
PERFORM . . . VARYI NG . . . AFTER
, there is no need for the
SEARCH
in
500-SEARCH- I T
.
Searching Only Part of a Table
Suppose we wish to find the
UNI T- PRI CE
for an input
PART- NO- I N
stored at
WAREHOUSE
5
. There is no need to search the entire table, just those entries within
WAREHOUSE 5
.
Using the preceding
I NVENTORY- TABLE
, we could code the
SEARCH
as follows:
SET X2 TO 1.
SEARCH I TEM- Xkˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆ
AT END PERFORM 700- ERR- RTN WHEN PART- NO- I N = PART- NO ( 5, X2)
DI SPLAY UNI T- PRI CE ( 5, X2)
END- SEARCH.
We use I TEM-X here.
The maj or i ndex X1 i n t he WHEN cl ause i s repl aced wi t h 5 because
we do not want i t t o vary.
We
SEARCH I TEM- X
, not
WAREHOUSE
, because we are looking for an item within a
specific warehouse, warehouse 5 in this instance.
DEBUGGING TIP
If we code:
01
I NVENTORY- TABLE.
05
WAREHOUSE OCCURS 50 TI MES I NDEXED BY X1.
10
I TEM- X OCCURS 100 TI MES I NDEXED BY X2.
15
PART- NO
PI C 9( 4) .
15
UNI T- PRI CE
PI C 999V99.
.
.
.
300- SEARCH.
SET X1, X2 TO 1.
SEARCH I TEM- X
.
.
.
the
PART- NO
s that will be searched are (1, 1) (1, 2) ... (1, 100). The major-level
index,
X1
, will
not
be varied. If we want to
SEARCH
the entire table (all warehouses
and all items), we need to code:
PERFORM 300- SEARCH
VARYI NG X1 FROM 1 BY 1
UNTI L X1 > 50.
.
.
.
300- SEARCH.
SET X2 TO 1.
SEARCH I TEM- X
.
If we code:
SET X1, X2 TO 1.
SEARCH WAREHOUSE
.
.
.
the
PART- NO
s searched will be (1, 1) (2, 1) ... (50, 1). That is, only the major-level
index,
X1
, will be varied, not the minor index,
X2
.
Searching Elements in an Array
A
SEARCH
can also be used with a multiple-level array for finding specific values in the
array. Consider the following double-level array:
01 ARRAY1.
05 STATE OCCURS 50 TI MES I NDEXED BY X1.
10 DI STRI CT OCCURS 10 TI MES I NDEXED BY X2. 15 POPULATI ON PI C 9( 10) .
To search an entire array such as the preceding, we use a
PERFORM . . . VARYI NG
,
which varies the major index and where the module being performed includes a
SEARCH
:
PERFORM VARYI NG X1
FROM 1 BY 1 UNTI L X1 > 50 SET X2 TO 1
SEARCH DI STRI CT .
. . END- PERFORM
Searching an Array until a Match is Found
In this example, we assume that there are precisely 10 districts per state. Each state,
then, has 10 districtwide population figures. Suppose there is
only one district
within the
United States with a population of 123,000 and we want to print its state and district
number. To do this, we must search the entire array until a match is found. When we
find a match, we want to print the values of the indexes since
X1
contains the state
number and
X2
the district number.
A
PERFORM . . . VARYI NG
is coded to increment the major index. The paragraph that
is performed will have a
SEARCH
that varies the minor index. That is, the statement
SEARCH DI STRI CT . . .
varies
X2
, the minor index, from 1 by 1 until a match is found
or
X2
exceeds 10.
X1
,
the major index, remains constant
in the
SEARCH
, at whatever value
it was initially set to. The
PERFORM . . . VARYI NG
will increment this major subscript.
Thus, to
SEARCH
the array until a ‘‘hit’’ or match is found, we would have:
SET is used in place of MOVE to transmit X1 and X2 to an output area
MOVE ’ NO ’ TO MATCH- FOUND. PERFORM 500- SEARCH- RTN
VARYI NG X1 FROM 1 BY 1
UNTI L X1 > 50 OR MATCH- FOUND = ’ YES’ . I F MATCH- FOUND NOT = ’ YES’
DI SPLAY ’ NO MATCH’
END- I F.
500- SEARCH- RTN. SET X2 TO 1. SEARCH DI STRI CT
WHEN POPULATI ON ( X1, X2) = 123000 SET X1- OUT TO X1
DI SPLAY X1- OUT, X2- OUT MOVE ’ YES’ TO MATCH- FOUND
END- SEARCH.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Each SEARCH will test POPULATION (X1, 1) - POPULATION * * (X1, 10). The X1 index remains constant and is not * * incremented by the SEARCH. It is incremented by the * * PERFORM ... VARYING. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Each time through
500- SEARCH- RTN
,
X1
is set by the
PERFORM
, first to 1, then to 2,
and so on. Then, in
500- SEARCH- RTN
itself,
X2
is set to 1 before the array is actually
searched. Thus, the first execution of
500- SEARCH- RTN
will search the entries
( 1, 1) ,
( 1, 2) , . . . ( 1, 10)
. If no match is found, the entries
( 2, 1) , ( 2, 2) , . . . ( 2, 10)
will be searched the second time through
500- SEARCH- RTN
. This continues until a match
occurs (i.e., a district population
4
123000), or the array has been completely searched.
If a match is found, we want to print the values of the indexes, since
X1
will contain
the state number and
X2
, the district number.
X1
and
X2
, as indexes, cannot be used in
a
DI SPLAY
statement, so we must copy their contents to other fields using a
SET
instruc-tion. To move the contents of an index to other fields such as
X1- OUT
and
X2- OUT
, we
use the
SET
statement,
not
the
MOVE
statement.
Alternatively, we could use a
PERFORM . . . VARYI NG . . . AFTER
:
MOVE ’ NO ’ TO MATCH- FOUND. PERFORM 500- SEARCH- RTN
VARYI NG X1 FROM 1 BY 1 UNTI L X1 > 50
OR MATCH- FOUND = ’ YES’ AFTER X2 FROM 1 BY 1
UNTI L X2 > 10
OR MATCH- FOUND = ’ YES’ . 500- SEARCH- RTN.
I F POPULATI ON ( X1, X2) = 123000 SET X1- OUT TO X1
SET X2- OUT TO X2 DI SPLAY X1- OUT, X2- OUT
END- I F.
Searching an Entire Array for Multiple Matches
We can search the entire array for specific conditions
even after a match is found
. Suppose
we wish to find the total number of districts within the United States that have
popu-lations in excess of 100,000. In this instance, we want to continue our
SEARCH
even after
we find a ‘‘hit’’, that is, a district with a population greater than 100,000. To continue
searching a table after a ‘‘hit’’ or match, it is best to use a
PERFORM . . . VARYI NG . . .
AFTER
with an
I F
test, instead of a
SEARCH
:
MOVE ZERO TO CTR. PERFORM 200- COUNT- THEM
VARYI NG X1 FROM 1 BY 1 UNTI L X1 > 50 AFTER X2 FROM 1 BY 1 UNTI L X2 > 10. DI SPLAY CTR.
200- COUNT- THEM.
I F POPULATI ON ( X1, X2) > 100000 ADD 1 TO CTR
END- I F.
Suppose we wish to find the total number of districts in
STATE 3
with populations
less than 50,000. In this case, we want to keep the
STATE
index,
X1
, fixed at 3. To do
this, we could code the following:
MOVE ZERO TO CTR2. SET X1 TO 3.
VARYI NG X2 FROM 1 BY 1 UNTI L X2 > 10. DI SPLAY CTR2.
300- SEARCH- RTN.
I F POPULATI ON ( X1, X2) < 50000 ADD 1 TO CTR2
END- I F.
DEBUGGING TIP
When an array or a table is to be searched for one specific entry or match, use
the
SEARCH
verb. This is because the
SEARCH
instruction stops as soon as the
con-dition tested in the
WHEN
clause is met. You could, however, use a
PERFORM
with
an
I F
instead of a
SEARCH
. When a table or an array is being searched where there
may be more than one ‘‘hit’’ or match to be tabulated or counted, it is better to
use
PERFORM
s and an
I F
instead of the
SEARCH
. With multiple-level arrays or tables,
use a
PERFORM . . .
VARYI NG . . .
AFTER
with an
I F
test to check for multiple
matches.
T
RIPLE
- L
EVEL
OCCURS C
LAUSE AND
M
ORE
We have seen that
OCCURS
clauses may be written on one or two levels. We may also
use triple-level
OCCURS
clauses. A
maximum
of seven levels of
OCCURS
clauses may be
used with COBOL 85, but COBOL 74 permits only up to three levels.
Suppose we have a table consisting of 50 state populations. Each state is further
subdivided into 10 counties. Each county has precisely five district figures. The
follow-ing array may be coded in the
WORKI NG- STORAGE SECTI ON
:
01 POPULATI ON- TABLE.
05 STATE OCCURS 50 TI MES. 10 COUNTY OCCURS 10 TI MES.
15 DI STRI CT- POP OCCURS 5 TI MES PI C 9( 10) .
In this way, we have defined 2500 fields (50
2
10
2
5) in storage, each 10 positions
long. To access any field defined by several
OCCURS
clauses, we use the
lowest
-level
data-name. In this illustration, the data-name
DI STRI CT- POP
must be used to access any of
the 2500 fields of data.
Since
DI STRI CT- POP
is defined by a triple-level
OCCURS
clause,
three
subscripts are
used to access the specific field desired. The
first
subscript refers to the
major
-level item,
STATE
. The
second
subscript refers to the
intermediate
-level item,
COUNTY
. The
third
sub-script refers to the
minor
-level item,
DI STRI CT- POP
. Subscripts are always enclosed
within parentheses. Each subscript is separated from the next by a comma and a space.
If we code
DI STRI CT- POP ( 5, 4, 3)
, the
DI STRI CT- POP
specified refers to the
popu-lation figure for
STATE 5
,
COUNTY 4
,
DI STRI CT 3
. An item defined by a triple-level
OCCURS
clause is accessed with three subscripts.
Example 1
Write a routine to find the smallest figure in the
POPULATI ON- TABLEarray. (We assume that data
has already been placed in the array.) Store this smallest figure in
HELD.
Using nested
PERFORM . . . VARYI NGstatements to achieve this looping, we have:
MOVE DI STRI CT- POP ( 1, 1, 1) TO HELD. PERFORM 200- RTN- 1
VARYI NG SUB1 FROM 1 BY 1 UNTI L SUB1 > 50. PERFORM 500- NEXT- RTN.
PERFORM 600- EOJ - RTN. 200- RTN- 1.
PERFORM 300- RTN- 2
To display the temperature at 3
A.
M. on January 2, 1993, we have:
DI SPLAY HOURLY- TEMP ( 1, 2, 3). The number 1 refers to the first year specified, 1993; 2 refers to the second day of that year
and 3 refers to the third hour, or 3
A.
M.
To load the array, we could read 1095 (3 years
2
365 days) records each with 24 hourly
temperatures:
PERFORM 400- LOAD- I T VARYI NG SUB1 FROM 1 BY 1 UNTI L SUB1 > 3 AFTER SUB2 FROM 1 BY 1 UNTI L SUB2 > 365.
PERFORM 400- RTN- 3
VARYI NG SUB3 FROM 1 BY 1 UNTI L SUB3 > 5. 400- RTN- 3.
I F DI STRI CT- POP ( SUB1, SUB2, SUB3) < HELD MOVE DI STRI CT- POP ( SUB1, SUB2, SUB3) TO HELD
END- I F.
Using a
PERFORM . . . VARYI NG . . . AFTERin the first
PERFORM, we can eliminate
200- RTN- 1and
300- RTN- 2:PERFORM 400- RTN- 3
VARYI NG SUB1 FROM 1 BY 1 UNTI L SUB1 > 50 AFTER SUB2 FROM 1 BY 1 UNTI L SUB2 > 10 AFTER SUB3 FROM 1 BY 1 UNTI L SUB3 > 5.
Note that more than one
AFTER
clause can be used in a
PERFORM . . . VARYI NG
, with
the last one being performed first. That is, the minor subscript is varied first.
With COBOL 85, we can use nested in-line
PERFORM
s:
MOVE DI STRI CT- POP ( 1, 1, 1) TO HELD. PERFORM VARYI NG SUB1 FROM 1 BY 1
UNTI L SUB1 > 50 PERFORM VARYI NG SUB2 FROM 1 BY 1
UNTI L SUB2 > 10 PERFORM VARYI NG SUB3 FROM 1 BY 1
UNTI L SUB3 > 5
I F DI STRI CT- POP ( SUB1, SUB2, SUB3) < HELD MOVE DI STRI CT- POP ( SUB1, SUB2, SUB3)
TO HELD
END- I F END- PERFORM END- PERFORM END- PERFORM.
PERFORM 500- NEXT- RTN. PERFORM 600- EOJ - RTN.
or
MOVE DI STRI CT- POP ( 1, 1, 1) TO HELD. PERFORM VARYI NG SUB1 FROM 1 BY 1
UNTI L SUB1 > 50
AFTER SUB2 FROM 1 BY 1 UNTI L SUB2 > 10 AFTER SUB3 FROM 1 BY 1 UNTI L SUB3 > 5
I F DI STRI CT- POP ( SUB1, SUB2, SUB3) < HELD MOVE DI STRI CT- POP ( SUB1, SUB2, SUB3)
TO HELD
END- I F END- PERFORM.
PERFORM 500- NEXT- RTN. PERFORM 600- EOJ - RTN.
Example 2
Suppose we want to store the hourly temperatures for Los Angeles or any other city for the years
1993 –1995. We could establish a triple-level or
three-dimensional
array as follows:
01 TEMPERATURE- ARRAY.
05 YEAR- X OCCURS 3 TI MES. 10 DAY- X OCCURS 365 TI MES.
15 HOURLY- TEMP OCCURS 24 TI MES PI C S9( 3) .
. . . 400- LOAD- I T.
READ DAY- TEMP- FI LE
AT END MOVE ’ NO ’ TO MORE- RECS
END- READ.
PERFORM 500- STORE- 24- VALUES
VARYI NG SUB3 FROM 1 BY 1 UNTI L SUB3 > 24. 500- STORE- 24- VALUES.
MOVE I N- TEMP ( SUB3) TO HOURLY- TEMP ( SUB1, SUB2, SUB3) .
To determine the average temperature for 1994 we could code in-line
PERFORMs with COBOL
85 as follows:
MOVE 0 TO TOTAL. MOVE 2 TO SUB1.
PERFORM VARYI NG SUB2 FROM 1 BY 1 UNTI L SUB2 > 365 PERFORM VARYI NG SUB3 FROM 1 BY 1 UNTI L SUB3 > 24
ADD HOURLY- TEMP ( SUB1, SUB2, SUB3) TO TOTAL END- PERFORM
END- PERFORM.
COMPUTE AVERAGE = TOTAL / 8760.
DI SPLAY ’ THE AVERAGE TEMPERATURE FOR 1994 I S ’ , AVERAGE.
Note that there are
no
periods between the first
PERFORMand the last
END- PERFORM. We divide
TOTAL
by 8760, which is 365 days
2
24 hours.
To find the average temperature for January 3 for the three years 1993 –1995 we could code:
MOVE 0 TO TOTAL. MOVE 3 TO SUB2.
PERFORM 200- MAJ OR- RTN VARYI NG SUB1 FROM 1 BY 1 UNTI L SUB1 > 3.
COMPUTE AVERAGE = TOTAL / 72
DI SPLAY ’ THE AVERAGE TEMPERATURE FOR J AN 3 FOR 1993 – 1995 I S ’ , AVERAGE.
200- MAJ OR- RTN.
PERFORM 300- MI NOR- RTN VARYI NG SUB3 FROM 1 BY 1 UNTI L SUB3 > 24.
300- MI NOR- RTN.
ADD HOURLY- TEMP ( SUB1, SUB2, SUB3) TO TOTAL.
A
PERFORM . . . VARYI NG . . . AFTERcould be used instead. With COBOL 85, we could code
an in-line
PERFORM . . . VARYI NG . . . AFTERas follows:
MOVE 0 TO TOTAL. MOVE 3 TO SUB2.
PERFORM VARYI NG SUB1 FROM 1 BY 1 UNTI L SUB1 > 3 AFTER SUB3 FROM 1 BY 1
UNTI L SUB3 > 24
ADD HOURLY- TEMP ( SUB1, SUB2, SUB3) TO TOTAL END- PERFORM.
COMPUTE AVERAGE = TOTAL / 72.
DI SPLAY ’ THE AVERAGE TEMPERATURE FOR J AN 3 FOR 1993 – 1995 I S ’ , AVERAGE.
Because seven levels of
OCCURS
are permitted with COBOL 85, a maximum of
six
AFTER
clauses are therefore allowed with COBOL 85. The limit for the number of
AFTER
clauses with COBOL 74 is two.
CHAPTER SUMMARY
A. Multiple-level
OCCURS1. May be used for an array or a table.
2. The lowest-level
OCCURSdata-name or an item subordinate to it is used to access an entry
in the array or the table.
3. If we use a
SEARCHfor accessing a multiple-level table,
I NDEXED BYmust be used on all
4. The identifier used with the
SEARCHstatement should typically be the one on the lowest
OCCURS
level. Only the index on the same level as the
OCCURSlevel will be incremented
by the
SEARCH. That is,
SEARCH XXX, for example, will only vary the index specified with
XXX
. Consider the following:
05 XXX OCCURS 10 TI MES I NDEXED BY X2.
X2
is the only index incremented in the search regardless of whether
XXXis subordinate
to an
OCCURSor contains another level of
OCCURS.
B. COBOL 85 permits seven levels of
OCCURS; COBOL 74 permits three levels.
CHAPTER SELF-TEST
1. With
MOVE I TEMX ( SUB1, SUB2) TO HELD, SUB1refers to the
-level
OCCURSclause
and
SUB2refers to the
-level
OCCURSclause.
2. Consider the following
DATA DI VI SI ONentry:
01 ARRAY1.
05 FI ELDX OCCURS 20 TI MES. 10 FI ELDXX OCCURS 50 TI MES.
15 I TEMX PI CTURE S99.
The number of storage positions reserved for this area is
. The data-name that
may be used to access a field in the
PROCEDURE DI VI SI ONis
. If
I TEMX ( CTRA,CTRB)
is used in the
PROCEDURE DI VI SI ON, then
CTRAmay vary from
to
and
CTRBmay vary from
to
.
3. If three subscripts are used to access an item, the firs