CHAPTER
9:
The
Evaluate Statement:
- When more than two values are possible coding IF can become highly complex.
We
can use Evaluate
to simplify the coding
and to help keep your code clear and concise. Evaluate
is ideal for circumstances in which you want to execute different
statements based on the value of a single data item.
- Simple Example of Evaluate :
The
Evaluate statement makes this situation much easier to write and
understand:
000067
Evaluate Commission-Plan
000068
When "A"
000069
Move 10 To Commission-Percent
000070
When "B"
000071
Move 20 To Commission-Percent
000072
When "C"
000073
Move 25 To Commission-Percent
000074
When Other
000075
Move Zero To Commission-Percent
000076
End-Evaluate
- The text that follows the word Evaluate is defined as the selection subject.The text that follows the word When is defined as the selection object. As the Evaluate statement is executed, each select ion object is evaluated against each select ion subject. When the result of this evaluation is true, the statements after the When are executed.
- The evaluations occur in the order of the coded When items . After a subject and object are evaluated to be true, the statements after the When are executed and the processing of the Evaluate statement ends . Thus it does not fall through. Statements after the selection object are executed until the next selection object ( When), End-Evaluate, or period, is encountered .
- Note that after a When selection object is evaluated with the selection subject and the evaluation is determined to be true, no further selection objects are evaluated.
- Evaluate can be coded in several ways. For example: Both the below statements are the same
000061
Evaluate Data-Item-A = Data-Item-B
000062
When True
000063
Display “Items are Equal”
000064
When False
000065
Display “Items are not equal”
000066
End-Evaluate
000067
Evaluate True
000068
When Data-Item-A = Data-Item-B
000069
Display “Items are Equal”
000070
When Data-Item-A not = Data-Item-B
000071
Display “Items are not equal”
000072
End-Evaluate
It
is advised that we use END-EVALUATE with EVALUATE statement.
The
first of above statements uses the condition Data-Item-A =
Data-Item-B as its subject. When such a condition is used as a
selection subject, the only selection objects that make sense are
True and False. This statement is equivalent to coding an If
statement with an Else clause.
The
second Evaluate uses True as its selection subject. The condition to
be tested is then coded as a selection object. The second select ion
object is the opposite condition .
- WHEN OTHER:
The
selection object Other allow statements that follow are always
executed when no other select ion objects are evaluated to be true
with the select ion subject.
Example:
000067
Evaluate True
000068
When Data-Item-A = Data-Item-B
000069
Display “Items are Equal”
000070
When Other
000071
Display “Items are not equal”
000072
End-Evaluate
Example
with Range:
000160
Evaluate Sale-Price
000161
When 1000 Thru 10000
000162
Move 50 To Commission-Percent
000163
When 500 Thru 1000
000164
Move 25 To Commission-Percent
000165
When 250 Thru 500
000166
Move 10 To Commission-Percent
000167
When Other
000168
Move 5 To Commission-Percent
000169
End-Evaluate
If
the sale price is $1,000, it seems as if the second selection
object should be executed. It is not . The reason is that the first
select ion object is true for a sale price of $1,000, so the
commission is moved, and no further selection objects are evaluated.
Another
method of coding this Evaluate statement follows:
This
method makes use of the True selection subject.
000160
Evaluate True
000161
When Sale-Price >= 1000
000162
Move 50 To Commission-Percent
000163
When Sale-Price >= 500
000164
Move 25 To Commission-Percent
000165
When Sale-Price >= 250
000166
Move 10 To Commission-Percent
000167
When Other
000168
Move 5 To Commission-Percent
000169
End-Evaluate
Remember
that the select ion objects are evaluated aga inst the selection sub
ject one at a time, from the top of the Evaluate down.
More
than one statement may be executed as part of the When.
- We may stack selection objects . If no statements follow the select ion object, it is treated as part of the next selection object. Therefore, if any selection object evaluates with the selection subject to be true, the statements after the final stacked selection object are executed
Example:
000192
Evaluate Last-Name (1:1)
000193
When "A"
000194
When "E"
000195
When "I"
000196
When "O"
000197
When "U"
000198
Move 1 To Group-Id
000199
When "B" Thru "J"
000200
Move 2 To Group-Id
000201
When Other
000202
Move 3 To Group-ID
000203
End-Evaluate
In
this example, any last name that starts with A, E, I, O, or U will
be assigned a group of 1.
- Like If statements, you may nest Evaluate statements. Subsequent Evaluate statements may be coded in the statements that appear after the selection objects
If
multiple selection subjects are used, the same number of items must
be specified on the selection object ( When) lines of the Evaluate
statement .
Multiple
selection subjects and objects are separated with the word Also.
Another
possible value that can be checked as a selection object is Any
.
Any
means that the evaluation evaluates to be true no matter what the
value of the selection object.
Example:
000233
Evaluate Last-Name (1:1) Also
First-Name (1:1)
000234
When “A” Thru “F” Also “A” Thru “F”
000235
Move 1 To Group-Id
000236
When “A” Thru “F”
Also “G” Thru “N”
000237
Move 2 To Group-Id
000238
When “A” Thru “F” Also Any
000239
Move 3 To Group-Id
000240
When “G” Thru “N” Also “A” Thru “F”
000241
Move 4 To Group-Id
000242
When “G” Thru “N” Also “G” Thru “N”
000243
Move 5 To Group-Id
000244
When “G” Thru “N” Also
Any
000245
Move 6 To Group-Id
000246
When Any Also “A” Thru “F”
000247
Move 7 To Group-Id
000248
When Any Also “G” Thru “N”
000249
Move 8 To Group-Id
000250
When Other
000251
Move 9 To Group-Id
000252
End-Evaluate
Note
that when creating complex Evaluate statements using multiple
selection sub-
jects,
remember that Other is a catchall .
We cannot code Other with any
other
selection object. Instead of using Other for an individual
item when
Also
is used, the word Any is provided.
IN
above example For each selection object, both subjects must be
evaluated with the selection objects . If all the different
conditions evaluate to true, then the statements after the selection
object line are executed.
CHAPTER10
Processing
Loops
The
Basic Perform Statement:
- The Perform statement executes the code you specify after the Perform and then returns in your program to the point immediately after the Perform statement .
- The simplest format of the Perform statement allows you to Perform a Section or Paragraph with in the Procedure Division
- We can divide the Procedure Division into Sections, using Section headings.
A
Section can have many Paragraphs. When you Perform a Section, all
the
Paragraphs
in the Section are performed from the top down. At the start of the
next Section, the program returns to the next line after the
Perform of that Section. This
practice is not often used and is not recommended. It is not obvious
when you read the Perform statement
that multiple Paragraphs
are going to be executed.
- We can also perform a single paragraph from a section. If a Paragraph in a Section is performed, then the program returns to the statement immediately after the Perform when the next Paragraph or Section is encountered
Example:
000014
Perform First-Section
000015
Perform Para-2
000016
Stop Run
000017
.
000018
First-Section Section.
000019
Para-1.
000020
Display “Para 1”
000021
.
000022
Para-2.
000023
Display “Para 2”
000024
.
000025
Para-3.
000026
Display “Para 3”
This
will produce the output as
Para
1
Para
2
Para
3
Para
2
The
first Perform causes each statement in the entire Section to be
executed . The second Perform executes only the statement under
Para-2 .
- Aside from performing a Section or a Paragraph, you may Perform a range of
Paragraphs.
To do so, state the starting Paragraph, the word Thru (or Through),
and the last Paragraph to be executed . Each Paragraph between the
two
Paragraph
titles spec ified is executed, and all statements under the last
Paragraph are executed.
Example:
Perform
Para-1 Thru Para-2
- When using Perform with the Thru clause, many programmers code a dummy
Paragraph
after the end of the Paragraph. The dummy Paragraph contains only
the word Exit.
Exit does nothing and is coded only because each
Paragraph has to contain at least one statement .
Example:
000060
Perform Para-1 Thru Para-1-Exit
000061
Stop Run
000062
.
000063
Para-1.
000064
Display “Para 1”
000065
.
000066
Para-1-Exit.
000067
Exit.
Creating
Processing Loops Using Perform:
- With Perform, We can Perform a Paragraph multiple times.
Example:
Perform
Count-By-1 10 Times
This
Procedure Division code Performs the Count-By-1 Paragraph 10 times.
The
number of times a Perform is to be executed can be specified by a
numeric data item or a numeric literal.
Perform-until:
Perform using conditional test.
We
can base the perform on the Conditional test. We do this by using
Until.
With
Until we tell the program to Perform the Paragraph, testing for the
condition before every execution of the Paragraph, Until the
condition is true.
Note
that by default the test will be performed before the statements are
executed. So there is a chance that it does not even execute once.
The
test for your condition occurs before the Paragraph is next executed.
We
must remember that the condition that is specified in the Perform
statement is
tested
before the Perform is executed. If the condition is true upon the
first pass, our
Perform
is never executed.
Example:
000087
Perform Para-1 Until Test-Item = "A"
Use
of Go To:
- The Go To causes the program to jump to the Paragraph title or Section header specified in the Go To statement. Thus note that we can go to Section or a paragraph.
- Go To causes what is referred to as an unconditional branch . The logic of your program jumps to the point of the Go To and does not return, in contrast to the logic of a Perform
CHAPTER
11
Advanced
Perform Statements:
Inline
Perform:
Perform
with Varying:
- When Varying is used with the Perform statement, a numeric data item is specified . This item will be incremented by the value specified in a second data item or literal each time the Perform is executed. (we can make it decrement by using the negative value in 2nd data item)
- The starting value of the field before the increment is also specified . If we want the count down, we can vary the data item by a negative number.
When
Varying is used, the test for terminating the Perform is usually,
but not always, based on the data item that is being varied .
- Very imp :When using Varying, the field being varied is incremented after the Perform is executed.
The
test for the condition that terminates the Perform, specified by the
Until phrase, is made before the Perform is executed.
Example:
000013
Perform Count-Routine Varying Counter
000014
From 1 by 1 Until Counter > 10
- When using Varying, you specify first the field you are going to adjust. The next item, after the word From, is the starting value of the variable . The number or data item that follows the word By is the amount by which you want to adjust the data value for each execution of the Perform.Any condition may appear after the word Until. When that condition is true, the Perform stops looping.
Imp: First,
the initial execution of the Perform is
made with the item you decide to vary set at the initial value as
specified with the word From.
At the end of the Perform,
the counter is adjusted by the amount specified after the By.The
condition is tested before thePerform is
executed.
- Decrementing: If we wanted to count down instead of up, you could vary from 10 by–1. Th is adds a negative 1 to the counter each time, which is the same as subtracting 1, thus counting down.
000015
Perform Count-Routine With Test After Varying Counter
000016
From 10 by -1 Until Counter = 1
- Test After:
Instead
of the default behavior of testing for the condition before the
Perform is executed, you can code With Test After. This
option causes the Perform to test the condition immediately after
the Perform has been executed and before any adjustment is made by
the use of Varying. Note that the change to the variable will be
made only after the condition is tested
This
approach ensures that we can use more understandable looping
parameters . It also guarantees that the Perform will be executed at
least once because the condition is not tested until after the
Perform has executed.
Thus
normal Perform acts like while and “with test after” causes
it to perform like do-while
Example:
000013
Perform Count-Routine With Test After Varying Counter
000014
From 1 by 1 Until Counter = 10
We
can also code With test before, But that defualt also.
The
Use of the Inline Perform:
- The inline Perform has all of the characteristics of a regular Perform with two
exceptions.
First,
it is always terminated with the explicit scope
terminator, End-Perform .
Second,
it has no Paragraph or Section name to be performed.
The
statements that are to be performed are coded between the Perform
statement and the End-Perform explicit scope terminator
Example:
000013
Perform With Test After Varying Counter
000014
From 1 by 1 Until Counter = 10
000017
Display Counter
000015
End-Perform
Suggestions
on when to use inline perform:
• If
only one or two statements are being executed, use an inline Perform.
• If
you are using this code in only one place in the program, use an
inl ine Perform.
• If
the code can be reused and is performed from more than one place in
the program, Perform a Paragraph instead . If you end up cod ing
exactly the same statements inside two inline Performs , you should
use a common Paragraph instead .
• If
the Perform is heavily nested or takes up several pages of source
code, you
might
want to break it down into individual paragraphs. Page after page
of inline
Perform
code can be as hard or harder to follow than separated paragraphs .
Example:
000027
Perform Varying Name-Length from 20 By -1
000028
Until First-Name (Name-Length:1) > Space
000029
or Name-Length = Zeros
000030
Continue
000031
End-Perform
Make
a special note of the Continue statement used in the inline Perform.
A statement must occur with in the Perform. Because the Perform is
actually accomplishing all the necessary testing and data
manipulation, nothing actually happens inside the Perform.
The
Continue statement does nothing and is coded just to satisfy the
compiler requirement that the inline Perform contain at least one
statement.
Additionally,
we may also nest inline Performs.
000050
Perform 10 Times
000051
Perform 20 Times
000052
Add 1 to Data-A
000053
End-Perform
000054
End-Perform
000055
.
In
this example, 1 is added to Data-A 200 times.
The
exterior Perform in line 50, per-forms the Perform in line 51 ten
times, and this interior Perform adds 1 to Data-A 20
CHAPTER
12:
TABLES:
- Tables are the COBOL version of an array . They can be used for subtotaling and data validation.
- 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.
- A table is defined by using the Occurs clause in the Data Division .
- Imp: The Occurs clause may not be used on a level 01 or level 77 data item .
Example:
000010
01 Month-Table.
000011
03 Month-Name Pic X(9) Occurs 12 Times.
NOte
that we did not define the occurs clause on a 01 level item.
- The Occurs clause may also be used at the Group Level to create an array containing several elementary items.
Example:
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).
In
the above example the pairing of State-Abbrev and State-Name repeats
51 times.
Consider
a table 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.
If
we looked at the table in memory with in the computer, we you
would
see the 50 state abbreviates listed together, followed by
the
50 state descriptions.
Basic
table handling:
- To reference an element with in a table, you need to specify the subscript .
The
first element of the table has a subscript value of 1.
Example:
000060
Display State-Name (24)
This
line of code displays the 24th occurrence of State-Name.
We
may use a table entry in the same way you use any other COBOL data
item .
Populating
a Table in Working-Storage:
- If a table is defined as below ,one way to get the individual month names into the table is to move them individually.
000010
01 Month-Table.
000011
03 Month-Name Pic X(9) Occurs 12 Times.
000061
Move "January" To Month-Name (1)
000062
Move "February" To Month-Name (2)
This
code is repeated for each month .
The
move method makes sense when the table is to populated
programatically in procedure division and when table may not be the
same for every execution.
However
when the table is going to be the same for every execution,
then
its better to populate the table in the working -storage section.
This
could be done using REDEFINES
clause.
- The Redefines allows you to specify a different Picture clause for a previously defined data item .
Example
of REDEFINES:
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.
- When using Redefines, we must make sure that the item you are redefining is
the
same size as the item in your Redefines clause . The
compiler
warns
us 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 .
Example
of Prepopulating the table using REDEFINES:
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 .
000039
03 Month-Table Redefines
Month-Descriptions.
000040
05 Month-Name Pic X(9) Occurs 12 Times.
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.
Look
up:
- Another use of tables would be to perform a look up.
Example:
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
Above
shows a way to search through the table
using normal inline perform.
The
search is an inline Perform that continues until it reaches the end
of the table or until it gets a match.
- The Search Statement:
- To use Search to scan a table the table must have an associated index .
An
index is a system-assigned data
field that references the different elements of a table. We
do not define this field in our program.
- Although an index behaves like a numeric data item, we 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.
Example:
000058
03 Month-Table Redefines Month-Descriptions.
000059
05 Month-Name Pic X(9) Occurs 12 Times Indexed
by
000060
Table-Index.
- Adjusting index value : To adjust the index value we use SET statement.
We
can set the index to a particular value or adjust it up or down by
specific value.
Example:
000061
Set Table-Index To 1
000062
Set Table-Index Up by 2
000063
Set Table-Index Down by 1
The
normal search performs search top to bottom. In the Search syntax we
define the condition that causes the search to stop. Optionally we
can also speciify some
statements
to perform if search does not find any data items in the table to
satisfy the test condition.
NOte
that the data item specified in the search is the one for which the
occurs clause is being coded.
- The condition to end the Search is specified using WHEN, similar to that in evaluate statement.
The
statements that are executed when the Search fails are coded after
the clause At
End .
- NOte that search always begins searching from the current position of the index.
We
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 .
Example:
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
Note
that instead of the numeric subscript we have specified the index
name in brackets.
- Its very important to note that the At End condition, if present, must occur before any When clauses. At End is optional .
- With Normal Search we can specify multiple When clauses.
If
any one of them is true, the statements after the assoc iated 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 .
However
we can specify multiple conditions using AND
- 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 we want to do something in our program based on the actual element number of the found item,
COBOL
provides a method to increment another data item during the Search .
The
item being incremented can be the index for another table or a
numeric variab e . The Varying
clause specifies the other data item . We 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
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
Example:
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
- SEARCH ALL
- The normal search is not efficient on large tables.
COBOL
provides another format of the Search statement that allows much
faster searching . This
format is Search All.
- To use Search All, the table must be indexed and keyed. Recollect that normal Search only required data table to be indexed. With SEARCH ALL the requirement increases to key as well
- 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 .
Example:
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).
The
Search All can be coded as below:
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
- 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 be ing 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 .
Example:
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).
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
First,
notice that the table is keyed by two key fields .
Second,
notice the When and the And clauses in the Search All statement .
Each clause refers to a key as def ined on the Occurs line .
Finally,
realize that the Search does not stop until both conditions, the When
and the And , are satisfied .
Multidimensional
Tables:
- COBOL tables can have up to seven dimensions.
- A two-dimensional table is a table with in a table.
Example:
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.
Example:
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 .
Example:
000101
Set Drawer-Index To 3
000102
Set File-Index To 5
000103
Display File-Number (Drawer-Index, File-Index)
- Multidimensional tables can be searched using the Search verb.
Imp:The
higher-level index values must be Set before the basic, or
lowest-level index can be searched.
Example:
000104
Set Drawer-Index To 2 /*SETTING
THE HIGHER LEVEL*/
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
Even
if the table is 4 dimensional and we are performing a search then we
need to write 3 inline perform to loop thru the 3 dimensions and
search on the final dimension.
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 .
4
dimensional exmaple:
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).
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
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.
Variable-Length
Tables:
- Tables do not have to be of fixed length.
- We can define a table that contains from one to any number of entries .
- Allow maximum table size would be wasting time ins Search operations.
We
create a variable-length table by specifying
Depending On in the Occurs clause on the item definition
.
- We 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, we
must specify the minimum and maximum number of occurrences in the
table.
Example:
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.
- 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.
- We 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 .
CHAPTER
13:
Sequential
files.
- A file is made up of individual records .
- A record is a collection of individual fields or data items .
- The format or formats of the records in the file are defined in your COBOL program .
- A record is a Group Level item, made up of elementary data items or groups of elementary data items . The definition for a record is called a record layout.
- The layouts of the records used by the various files in COBOL program
are
specified in the Data Division .
- A sequential file is one that is accessed sequentially, that is, the records are retrieved from the file in order, from the first record in the file to the last .
Records
cannot be retrieved out of order.
We
may not jump ahead in the file, nor may you go backward.
- Many compilers distinguish between Line Sequential and Record Sequential files.
Line
Sequential files contain records of varying length.
Records
are terminated with a platform-dependent delimiter. Under most
PC-based operating systems, this delimiter is a Carriage Return and
Line Feed, in ACSII a X”0D0A”.
On
UNIX systems, Line Sequential files are terminated with a Line Feed
only; in ASCII, a X”0A”.
The
other type of file is a Record Sequential file, normally referred to
simply
as
a Sequential file. The records in a Record Sequential file are not
delimited.
Each
record in the file is adjacent to its immediate neighbors .
A
Line Sequential file is one kind of Sequential file and is similar
to a regular
text
file . Each record in a Line Sequential file is a line in a file
and is delimited
by
a carriage return and line feed (or just a line feed in the UNIX
world) . The lines may be of various lengths . Each Read against a
Line Sequential file returns a single line as a record . With a
regular Sequential file, otherwise known as a Record
Sequential
file, records are read based on their length. If your records are 80
characters long, every Read returns exactly 80 characters . There are
no “lines” and no delimiters separating the records .
Connecting
Program to File:
1st
we must establish connection between the program and the file.
This
process requires two steps.
The
first establishes the hardware, file type, organization, and filename
of the file you are accessing.
The
second defines the layout of the records in the file.
Select
Statement:
- Select Statement connects program to file.
- The Select statement is coded in the Environment Division , under the Input-Output
- Section, in a paragraph titled File-Control.
- An internal filename is specified in the Select statement . This name is used to refer in the cobol program.
- The filename can be upto 30 characters.
- The Assign clause can refer to a symbolic name or, in some cases, as on the PC, an actual physical filename .
The
symbolic name can later be associated with a specific file, using
runtime
options
like DDNAME is JCL.
- The Organization clause specifies the type of file you are working with . For Sequential files, the type can be Sequential or Line Sequential.
- The File Status clause associates the system returned File Status with a field in the Data Division. This field is two characters long and contains a status value that can be tested after every operation against the file.
Example:
000056
Input-Output Section.
000059
File-Control.
000060
Select Name-File Assign To “NAME.TXT”
000061
Organization Is Line Sequential
000062
File Status Is Name-File-Status.
The
input section contains the paragraphs pertaining to external file
I-O.
Select
Statements must be used FILE-CONTROL section.
The
File Description:
- The File Description (FD) describes the attributes of the file and its associated data
record
or records.
- The FD is coded in the Data Division of the File Section.
- The Record Description, or descriptions, immediately follow the FD.
- The FD contains the same filename as specified in the Select statement . Every file specified with a Select statement requires a File Description entry.
- The record description must start with an 01 Group Level item .
- A file may have more than one record description, and each must follow the associated FD.
Example:
000065
Data Division.
000066
File Section.
000067
FD Name-File.
000068
01 Name-Record.
000069
03 Full-Name Pic X(30).
- The rules of coding the record description is identical to those dealing with working-storage.
- Data records can have 88 level items and redefines clause.
- Value clause is considered as comments and do not set actual values .
- In addition 77 clause cannot be used in record description.
- Occurs clause may also be used for variable clause.
- We can specify more than one Record Description for a file, these Record Description s are implicit Redefines. They overlap each other. Hence if we move data into a field in one Record Description , that data shows in all Record Descriptions for the file.
Opening
the File:
- To work with a file 1st we need to open a file.
The
Sequential file is opened in 4 modes: Input,Output,I-O,Extend.
- Input: allows you to read data from the file.
- Output: Allows you to write data to file.
- I-O: allows you to update records in the file.
- Extend: allows you to add records to the end of the file.
Example:
Open Input Name-File
- On successful opening the status value is 00.
This
value is stored in the data item assigned by the File Status clause
on the Select statement .
- Standard File Status values contain two characters .
The
status returned under “normal”
circumstances begins with a zero .
If
your file does not exist and you Open it Input, the File
Status returned is 35.
- Optional Clause: When we don’t want your program to report a serious file error when the file does not exist, we can code the Optional clause on the Select statement .
When
Optional is coded,the File Status reported for the Open of a file
that does not exist is 05 and the Open is successful.
The
first Read of the file, however, reports that end of file has been
reached .
Example:
000059
File-Control.
000060
Select Optional
Name-File Assign To “NAME.TXT”
000061
Organization Is Line Sequential
000062
File Status Is Name-File-Status.
Closing
the File:
- When we are done processing the file , we should release the file to operating system so that program can use it using close statement.
Example:
000100
Close Name-File
- Following are the File Status that we might get after closing file:
- 00 : Successful operation.
- 30: Physical operation error. NO more information is available
- 42: Close Issued for unopened files.
- 9x: Vendor specific compiler error.
Writing
to the File:
- To create the file, it is opened for Output .
When
a file that does not exist is opened for Output , it is created .
If
it does exist, it is replaced by an empty file .
- The statement required to Open the name file for Output is
000091
Open Output Name-File
- Data records are created in the file by using the Write statement .
The
operand required with write statement is
the record identifier.
The
record identifier is one of the 01 Group level items coded under the
FD.
- When writing to a file, never specify the filename, but rather the
record
identifier . The reason is that multiple record descriptions may
exist
for
a particular file . Specifying the record description causes the
program to
Write
the record in the format desired.
- Possible file status from write statements:
- 00: Successful completion.
- 30: Error , No other information available.
- 48: Attempted to write to a file that is either not open or is not open in an
- appropriate mode for write
- 34: Boundary error.
- 9x: Complier specific error codes.
File
Status 30 is a kind of catchall. Errors that may occur during the
Write that are
not
captured any other way may report a File Status 30.
Status
34 is reported if you exceed the maximum allowable size for the file
on your platform or if the media you are writing to fills up.
- Following is how we should specify the File Status variable:
000029
01 Name-File-Status Pic XX Value Spaces.
000030
88 Name-File-Success Value “00”.
000068
Write Name-Record
000069
If Name-File-Success
000070
Move “Record Written” To Error-Message
000071
Else …..................
000076
End-if
File
Status checks after the Open and the Write. If an error of any kind
occurs, the error flag is set .
- After a Write, the contents of the file buffer cannot be counted on.
The
file buffer is the area described by the record description under
the FD. Therefore, if we need to reference the contents of the data
record after a Write, we need to store the record in
Working-Storage.
When
we Write the record, you can do one of two things.
- We can either move the Working-Storage version of the record to the record description and then issue the Write.
- We can use the Write statement with the From clause . Using From causes the program to do an implied move. The data in Working-Storage is moved to the file buffer as the Write is processed .
In
the 2ns method Instead of the FD coded previously, you may use the
following:
000018
FD Name-File.
000019
01 Name-Record Pic X(30).
Add
the following line to Working-Storage.
000021
Working-Storage Section.
000022
01 Full-Name Pic X(30) Value Spaces.
The
only other change necessary is to the Write statement:
000068
Write Name-Record From Full-Name
Now
we can reference Full-Name with the Display statement, after the
Write is complete, without worrying about the integrity of the data
in the file buffer .
- When the file is opened Extend , new data records written to the file are added at the end of the file, after the existing records.
Reading
from the File:
- Reading from a sequential data file requires that you Open the file for Input , or for I-O. The statement required to Open the file for Input is
000110
Open Input Name-File..
- File Status reported when file is opened are:
- 00 Successful completion .
- 05 Successful Open of an optional file that does not exist .
- 30 Physical error, no other information available .
- 35 Open failed on a non optional file . The file does not exist .
- 39 The file being opened is defined differently than the definition specifiedin this program.
- 41 The file being opened is already open .
- 9x Compiler-vendor defined.
If
a file with Optional coded on the Select statement is opened for
Input and that file does not exist, the Open is successful and a
return code of 05
is returned .
Note
that the file is not created. This feature is useful when you
have a program that expects input data, but where you may not always
have any input data to provide . By
making the file Optional , the Open never fails.
File
Status 35 means that the
file is not defined as Optional and does not exist .
File
Status 39 means that the
definition of the file being opened differs from that in the program
.
File
Status 41 means that you are
attempting to Open a file that is already open .
- Read statement is used to read the file. Sequential files are read from the first record to the last. You may not skip forward in the file . Every record is read in order . Each Read returns the next record in the file .
- When you code the Read statement, the filename is specified . You do not read using a record description . The simplest form of the Read statement is
000111
Read Name-File
- This Read statement returns the next record in the file and places the contents in the record description defined for the file under the FD.
- Status Values for Read:
- 00 Successful completion .
- 04 Successful; however, the record read is not the same length as the record defined in the FD.
- 10 The end of the file has been reached .
- 30 Physical error, no other information available .
- 46 The Read failed because the previous Read failed.
- 47 A Read was attempted on a file that is not Open for Input or I-O.
- 9x Compiler-vendor defined.
File
Status 04 is considered a
successful Read. However, the record read has a different size than
your program’s definition .
File
Status 10 means that you
have reached the end of your input file and no record is returned.
File
Status 46 occurs when you attempt to Read a record and the previous
Read has failed.
File
Status 47 means that you have attempted to Read from a file that is
either not Open or is Open Output or Extend , instead of Input or
I-O .
- The end-of-file condition can be detected in two ways .
- One method is to check the File Status after the Read. If it is 10, then you have reached the end of the file .
- Another way is to code the At End clause on the Read statement .When At End is coded, the statements after the clause are executed when an end-of-file condition is detected .
When
we use AT END clause its
suggested to use END-READ delimiter.
In
addition to coding At End , we may also code Not
At End.
Example:
000120
Read Name-File
000121
At End Set All-Done
To True
000122
Not At End Perform
Process-Data
000123
End-read
Similar
to the Write statement with From where the record is written from
another
data
item . For the Read statement, we specify Into and the name of the
data item in
which
we wish to store the record read .
Example:
000124
Read Name-File Into
Full-Name
Updating
the File:
- To update the file, you must Open it for I-O . The File Status values returned by the Open are the same as those reported for opening the file for Input.
000125
Open I-O Name-File
- After the file is Open, it is processed by Read statements as if it were Open for Input .
However,
we may now update a record by coding the Rewrite
statement . Rewrite
replaces the last record read with the new data that you have placed
in the record description .
- Rewrite also supports the use of From to update the record from a data item in Working-Storage. The File Status values returned from a Rewrite on a Sequential file are the same as those that are returned as the result of a Write .
- The Rewrite statement also requires the record description and not the filename—exactly the same as the Write statement .
- We may not issue a Write statement against a Sequential file that is opened I-O. If you need to Write more records to a Sequential file, you must open it Extend .
Variable-Length
Records:
- Sequential data files can contain variable-length records . These data records contain a table that is defined with an Occurs and Depending On.
- The numeric field that determines the number of occurrences may or may not appear in the data record . If it does appear in the record, it must appear before the table that it helps to define . If it does not, then the Read of the record will not be successful .
- If the field that determines the number of occurrences is not part of the data record, it must be initialized to the proper number of occurrences before the Read statement is executed.
Example:
000020
FD Name-File.
000021
01 Name-Record.
000022
03 Name-Ctr Pic 9(2).
000023
03 Name-Table Occurs 1 to 20 Times Depending On Name-Ctr.
000024
05 Name-Item Pic X(20).
CHAPTER
14.
Indexed
Files:
- An Indexed file is a file that allows access to data records by way of a Key field.
- A record in an Indexed file contains at least one Key field. This field is the index to the file.
- There must be at least one Key field that contains a value that is unique.
- This Key field is the Primary Key. Each record in the file is uniquely identified by this Key.
- Indexed files need not be limited to a single Key field.Indexed files may have Alternate Key fields .
- Unlike the Primary Key field, Alternate Key fields may or may not be unique. When we define the Key structure of the file in the COBOL program, we must specify whether any Alternate Key fields may contain duplicates .
- The Key field is either a single elementary item in your record description or a single group field. Generally this is put at the beginning of the file.
Select
Statement for indexed files:
- The Select statement is where you define the Key data for the Indexed file.
- Organization Indexed—Specifies that this f ile is an Indexedfile .
- Access Dynamic, Random , or Sequential—Specifies how the records in the file are to be retrieved and/or updated.
- Record Key—Specifies the field that is to be the Primary Key for the file . Only one Primary Key is allowed .
- Alternate Record Key—Specifies a field that is to act as an Alternate Key field for the file . A single file may have multiple Alternate Key statements.
- With Duplicates—If coded, the associated Alternate Record Key may containduplicates; it does not have to uniquely identify the record as does the Primary Key field.
- For an Indexed file, Organization Indexed must be included in the Select statement .
- One of the three access methods must be chosen.
- Sequential access causes the Indexed file to behave as a Sequential file.
- Random access means that every record is retrieved by specifying a Key field. The records may be retrieved in any order .
- Dynamic access allows you to have the best of both Sequential and Random access . Data records may be accessed randomly via a Key , or you may position the data file at a particular record and then access the file sequentially. The Starting position may be chosen based on the alternate key or the primary key.
Example:
000058
Select Dealer-File Assign to “Dealer.Dat”
000059
Organization Indexed
000060
Access Sequential
000061
Record Key Dealer-Number of Dealer-Record
000062
Alternate Record Key Dealer-Name of Dealer-Record
000063
File Status Dealer-Status.
Creating
an Indexed File from a Sequential File
- Creating an Indexed file by opening it output and accessing it sequentially is
normally
the most efficient file creation method .
In
this case, the records being added must already be in Primary Key
sequence
- We have to remember, however, that the data records for the file must be written in Primary Key sequence. If a record is written out of sequence, an error 21is
reported.
- Status messages that we might get with indexed files:
- 00 Successful completion .
- 30 Physical error, no other information available .
- 21 Primary Record Key value not in ascending Key sequence . This condition can occur when a duplicate record is encountered, or when the Primary Key is out of order.
- 34 Fatal error caused by the inability of the program to Write the record.Usually occurs because of an inaccurate Key field. Can also be caused bya hardware problem, such as running out of disk space, or secondary f ileallocations of space on some systems.
- 48 Attempt to Write to a file that is not opened for Output , Extend , or I-O .
- 9x Compiler-vendor defined.
- Indexed files may be opened Extend instead of Output.
Records
added to the file must still be in Primary Key sequence, and their
Primary Key values must be greater than the last record in the file.
- Taking care of the primary key sequence is needed when we have sequential access. And if we go out of sequence then we get error code 21 . To avoid error code 21 we can open the file in random mode. When Random access is used, records are added based on their Key value. They do not have to be added in sequence. COBOL and the Indexed file system work together to ensure that the records are properly added to the f ile . File Status 21 errors should no longer occur .
- A new File Status value—22—is possible when an Indexed file is Open for Outputwith Random access . This File Status is returned when a record with a duplicate Key is added to the file. The Key causing the error can be either the Primary Key or the Alternate Key. This error is caused by duplicate Alternate Key values only when duplicates are not allowed on Alternate Keys. If duplicates are allowed on Alternate Keys and a duplicate record is written, the returned File Status is 02.
- Using Random access the order in which the records are added does notmatter. Random access allows you to Write records in any position in the file .
Error
Handling Methods:
Till
now we only used the records are added does not matter. Random
access allows you to Write records in any position in the file .
Apart
from this there are two more options that can be used:
- Invalid Key clause .Any statements coded after this clause are executed when an Invalid Key cond ition occurs . These File Status values begin with a 2. When an Invalid Key cond ition is encountered, the associated operation is not successful.
Example:
000175
Write Dealer-Record
000176
Invalid Key
000177
Move Dealer-Status To Write-Error-Status
000178
Move Write-Error To Error-Message
000179
Perform Display-And-Accept-Error
000180
Not Invalid Key
000181
Initialize Work-Record
000182
Move 1 To Cursor-Row
000183
Cursor-Column
000184
End-Write
When
Invalid key is used its suggested to use the END-WRITE delimiter.
Note
that Invalid Key condition is triggered only when a File Status value
begins with a 2.
- Declaratives:
- The use of Declarativesis specified in your program immediately after the Procedure Division by coding the word Declaratives.
- After the word Declaratives, a Section is coded for each file that is to have declarative logic executed when an error condition occurs . These must be Sections , not Paragraphs.
- Immediately after the Section header is a Use statement . It tells the program to execute the Declaratives in this section when a file error is detected for the specified file.
- We can separate the Sections with in the Declaratives into Paragraphs.
- We may not Perform any code outs ide the Declaratives and End-Declaratives labels .
However
we may Perform code from different Sections with in the
Declaratives.
Example:
We
might have a common error-display paragraph that is coded in the
Declaratives Section for one file and then performed in the
Declaratives Sections for the other files.
- The Declaratives are not executed for Invalid Key conditions (that is, File Status values starting w ith 2) if the Invalid Key clause is coded for the file operation . Additionally, File Status 10 (end of file) does not trigger the Declaratives if the At End clause is coded on the Read statement
Example:
000155
Procedure Division.
000156
Declaratives.
000157
Input-File-Error Section.
000158
Use After Standard Error Procedure On Dealer-File.
000159
Dealer-File-Error.
000160
String “Error On Dealer-File “ Dealer-Status
000161
Delimited By Size Into Error-Message
000162
End-String
000163
Display Data-Entry-Screen
000164
Accept Data-Entry-Screen
000165
.
000166
End Declaratives.
We
cannot Perform anything outside the Declaratives from with in the
Declaratives.
Important
note:
●When
an Indexed file is opened for Output and the access mode specified
is
Sequential,
any records written to the file must be written in Primary key
sequence
order.
● When
an Indexed file is opened for Output and the access mode specified
is
Random
, the records may be written in any order .
Though
Using Random access for writing into indexed file works fine , there
are scenarios under which we would want to have sequential access for
writing data to file.
When
processing large amounts of data, we will find that adding records in
random order is much slower than adding them in Sequential order.
For each Add in
random
order, the program must check whether the record already exists, add
the
record
in the proper portion of the data file, and then adjust the index
records
accordingly
. With Sequential access, the program need only verify that the Key
value
currently being written is greater than the last Key value written
. All the
records
are in sequence and can be added efficiently . Key maintenance is
simplified
for
the program as well
CHAPTER
15
Reading
Indexed File Records:
- Sequential access, for example, allows the file to be processed from front to back, from lowest Primary Key to highest, using the same programming statements as a normal Sequential file . Sequential access can be put to good use when the entire file is to be processed .
- Random access provides instant access to a specific record and can be a very fast way to retrieve information from an Indexed file .
- Dynamic access allows both Sequential and Random access . Dynamic access offers the best of both worlds but has the disadvantage of being slightly more cumbersome than either Random or Sequential access .
Sequential
Access:
Sequential
access is specified in the Select statement for the file:
000058
Select Dealer-File Assign To “Dealer.Dat”
000059
Organization Indexed
000060
Access Sequential
000061
Record Key Dealer-Number Of Dealer-Record
000062
Alternate Record Key Dealer-Name Of Dealer-Record
000063
File Status Dealer-Status.
In
order to Read data from an Indexed file, it must be opened for
Input. The Open statement is very simple:
000101
Open Input Dealer-File
The
Read statement operates exactly the same way with an Indexed file
Open with Sequential access as it does with a regular Sequential
file .
Each
subsequent Read statement returns the next
record in the file, in Primary Key sequence . The At End
condition is true if a Read is attempted after the last record of a
file is read. The File Status returned is 10 if the end of file
is reached.
The
Start Statement:
- We can begin reading anywhere in the file by using the Startstatement .
The
Start statement allows you to specify the position in the file where
the next Read will occur.
- With the Start statement, we specify two things , one is the the file we want to position—and second is the location— in reference to the Key field. Before issuing the Start, we place a value in the Key field to control the positioning . We can Start the file on a record equal to the Key field, greater than the Key field, greater than or equal to the Key field, or not less than the Key field. You may not specify less than in the Start statement .
- Start Statement can be used only with indexed file and not sequential file.
Example:
If
we want to begin processing on the account numbers beginning with the
letter C, we can code the following statements after the Open and
before any Read statements:
000412
Move “C” to Dealer-Number
000413
Start Dealer-File Key Not < Dealer-Number
- Start can come with Invalid key clause.
- Status value 23 can be returned when you use the Start state-ment to position an Indexed file for a Sequential Read. Status 23 means record not found. This status is returned after a Start statement if a record cannot be found that matches the requested position in the file .
Example:
000101
Move “C” To Dealer-Number
000102
Start
Dealer-File Key Not < Dealer-Number
000103
Invalid Key Set End-Process To True
000104
End-Start
- An interesting aspect of the Start statement is that it allows you to begin sequentially reading the Indexed file based on the Alternate Key field.Instead of specifying the Primary Key on the Start statement, you may specify an Alternate Key field.
Example:
000101
Move “H” To Dealer-Name
000102
Start Dealer-File Key Not < Dealer-Name
000103
Invalid Key Set End-Process To True
000104
End-Start
When
we run the program with this code inserted, the first name that is
displayed begins with an H.
- Each subsequent Read returns the records in name sequence, not in account number sequence as we saw before . Thus the Start statement specifies where to Start in the file and in which Key sequence to Read the file .
- Starting at the beginning of the file. When we want to Start at the beginning of the file, using the Alternate Key , use the Start statement but place Low-Values in the Key field. When starting, use the not <phrase, not the > phrase . Using not <ensures that the next record read is the one with Low-Values or something greater in it
Example:
000099
Move Low-Values To Dealer-Name
000100
Start Dealer-File Key Not < Dealer-Name
000101
Invalid Key Set End-Process To true
- If we know the specific record Key you want to Start on, we may use Start with Key = the Key field after it has been filled with the appropriate starting Key , for example:
000099
Move “Jennings” To Last-Name
000100
Move “Shelly” To First-Name
000101
Move “Martin” To Middle-Name
000102
Start Dealer-File Key = Dealer-Name
000103
Invalid Key Set End-Process To True
If
the name does not exist, you get a File Status 23 and the Invalid Key
condition is true . If the name does exist, the very next Read
contains the record with this Key value
- Note that The Start statement does not return the record; it only positions the file for the next Read. A Read statement must be executed to retrieve a data record, even after a successful Start.
Random
Access:
The
Select statement necessary for Random access is
000058
Select Dealer-File Assign To “Dealer.Dat”
000059
Organization Indexed
000060
Access Random
000061
Record Key Dealer-Number Of Dealer-Record
000062
Alternate Record Key Dealer-Name Of Dealer-Record
000063
File Status Dealer-Status.
- When reading from the file using Random access, we must place a value in the Key field of the file being read
The
next Read statement for the file returns the record identified by
dealer number L3460 .
000102
Read Dealer-File
If
the file contains no record matching the Key specified, a File
Status of 23is
returned,
which is an Invalid Key condition . we may code the Invalid Key
clause
after
the Read to handle these conditions if we des ire .
Once
the value is set in the key , any number of times we execute the read
statement the same record is read.
Example:
000102
Read Dealer-File
000103
Invalid Key Display “No Dealer Record Found”
000104
Not Invalid Key Perform Process-Record
000105
End-Read
If
a Read is not successful, the content of your data record area is not
protected . If data was in the area from a previous Read or a value
was in the Key field, it may not be there after an unsuccessful Read
attempt.
Its
suggested to use the END-READ scope terminator in case we INVALID-KEY
clause.
- Unless otherwise specified, the Read statement assumes that we are reading via the Primary Key field. It is entirely permissible to Read records from an Indexed file opened in Random mode by the Alternate Key field.
When
we Read via the Alternate Key , the
specific Key field desired must be coded in the Read statement .
000100
Move “Alan” To First-Name
000101
Move “Aaron” To Middle-Name
000102
Move “Holmes” To Last-Name
000103
Read Dealer-File Key
Dealer-Name
000104
Invalid Key Display “Record Not Found”
000105
Not Invalid Key Perform Process-Record
000106
End-Read
- If a matching record is not found, a File Status of 23 is returned in the File Status
field
if one is defined. Declaratives may be specified for the file and w
ill be executed in case of a Read that is not successful. The Key
clause specifies the Key field to be used for the Random Read .
- If a Random Read is attempted against an Alternate Key that allows duplicates and a record is identified that has an identical Alternate Key to another record in the file, a File Status of 02 is returned . The record returned is the oldest in the f ile, the first record added with this Alternate Key value.
- Its very important to state that The At End clause is not valid for use on a Read statement when the file is Open for Random access . We will never reach the end of the file, the record being read will exist, or it will not .
Dynamic
Access:
- Dynamic access is the slowest and most versatile of the access methods used to
retrieve
records from an Indexed file .
- This type of access is the slowest because of the overhead required for the program to keep track of its position in the file . Dynamic access allows you to retrieve records both randomly and sequentially.
- The Select statement used to specify Dynamic access is coded as follows:
000058
Select Dealer-File Assign to “Dealer.Dat”
000059
Organization Indexed
000060
Access Dynamic
000061
Record Key Dealer-Number of Dealer-Record
000062
Alternate Record Key Dealer-Name of Dealer-Record
000063
File Status Dealer-Status.
- When Dynamic access is specified, we can perform Random reads using exactly the same method as if the file were Open with Random access .
- To Read records from the file sequentially from an Indexed file Open with Dynamic
access,
we must first position the file at a valid record. Correct
positioning can be
accomplished
in three ways.
1st
method: One method is to issue a Random Read using the desired
Key field. That is move a value in the key or alternate key and then
issue a read command. If the Read is successful, then we may
continue to Read subsequent records from the file sequentially in
the order of the Key that was used for the Random Read .
We
need some way to differentiate between a Random Read and a Sequential
Read designed to retrieve the next record in the file .
To
indicate that the next record in sequence should be returned, we
issue a Read statement with the Next clause . Thus with dynamic
access we can 1st
position the record using a normal read and the issue Read-next to
read the records sequentially from that point.
000101
Read Dealer-File Next Record
The
word Record is optional and is specified only to make the code more
readable.
The
At Endclause may be coded to detect the end of file .
The
Invalid Key clause is not val id on a Read statement w ith the
Next clause .
FILE
STATUSVALUES RETURNED FROM A READ WITHNEXT
46
The prior Read or Start statement was unsuccessful, and the
next record
cannot
be determined.
47
The file is not Open for Input
2nd
Method: The second method that can be used to position the file
for a Sequential Read is to issue a Start statement . The
Start statement works as previously discussed and sets the position
in the file for the next Read Next statement .
3rd
method: The third method to position the file at a valid record
is simply to Open the f ile . When you Open an Indexed file with
Dynamic access, the next record pointer is set to the begin-ing of
the file . Subsequent Read statements with the Next clause return
records in Primary Key sequence.
Note
that when we read indexed file sequentially , it is always read in
the sequence of the primary key. (unless specified)
The
Read with Next need not specify the Key being used; it is assumed
from the last success-ful Read or Start operation
Important
Points:
• Indexed
files can be read randomly or sequentially. Random reads are made
directly
with
a known Key , and Sequential reads are made serially, one after the
other,
based
on the Key sequence of the file .
• You
can specify the starting position for Sequentialreads by us ing the
Start
statement
.
• The
Start statement is valid for both Sequential access and Dynamic
access .
• When
a Random Read is issued and a matching record is not found, a File
Status
23
is returned . Another way to detect this condition is to use the
Invalid Key
clause
of the Read statement because any File Status that begins with 2
indicates
an
Invalid Key condition .
• Dynamic
access allows you to access an Indexed file randomly or
sequentially. The
statement
to Read a record sequentially is the Read statement with the Next
clause .
•A
Start statement does not return the data record contents; it only
pos itions the
file
for the next Read.
CHAPTER
16
Updating
Indexed File Records:
- Updating records in an Indexed file requires that we be able to Read a record so that we can present its contents to the user for modification . We also need to be able to Write the new record, or update the existing record if a change has been made .
- COBOL provides an Open mode that allows you to Read records from an Indexed file, Write new records, and update existing records. This Open mode is I-O , meaning Input-Output . The File Status values returned when opening a file I-O are the same as those returned when opening the file for Input.
- All the statements used when reading from an Indexed file that is Open Input apply when the file is Open I-O. We may specify Sequential, Random , or Dynamic access . We may Read records from the file as if it were Open Input . We may Write new records to the file using Write as if the file were Open Output. Finally, you may update existing records.
Writing
Records:
- We may not Open the file I-O with Sequential access mode and Write records. If you attempt to do so, a File Status of 48 is returned. This status is returned because we cannot Write to an Indexed file with Sequential access that is opened for I-O. If we need to add a record to an Indexed file with Sequential access, we should Open the file for Extend instead of I-O. When writing to the file, you must ensure that the primary Key of the record being written is greater than the last record in the file. If not, you receive a File Status 21, record out of sequence, error. The primary Key controls the sequence of records for Sequential Write operations. Keep in mind that although Sequential access is pretty fast and has its place, you probably don’t want to try to add records to an Indexed file Open in Sequential mode.
- When we use Random access and have the file Open I-O, we may Write new records to the file. The order of the writes does not matter. If a duplicate primary Key is encountered, a File Status of 22 is returned. Our new record does not replace the existing record. If you have Alternate Record Keys and duplicates are not allowed—but one is encountered during the Write—a File Status 22 is also returned. In this case, it is not possible to determine which Key is being duplicated by the Write: the primary or one of the Alternate Key fields. If duplicates are allowed on the Alternate Key and one is encountered as the result of a Write statement, a File Status of 02 is returned
- The
COBOL standard requires that we either code the Invalid
Key
clause or have Declaratives
defined for the file when performing a Write
against an Indexed
file.
- For the Write statement, Dynamic and Random access work the same way. Writes to an Indexed file that is Open I-O with Dynamic access are identical to writes to a file that is Open with Random access.
- The
Write
statement is coded the same as with Sequential
files. You specify the record description to be written, not the
file name. The only additional check that may be coded with Indexed
files is the Invalid
Key
clause.
000101 Write Dealer-Record From Dealer-Work 000102 Invalid Key Perform Invalid-Dealer-Write 000103 End-Write
Rewriting Records:
- The Rewrite statement is available only when the file is Open I-O.
- With Sequential access a Rewrite can be performed only if the last statement executed against the file was a Read statement, and the Read was successful. If we attempt to Rewrite a record when access is Sequential, without first reading a record, the Rewrite fails. The File Status reported for this failure is 43, which simply means that the last statement executed for the file was not a successful Read. This failure occurs even after a successful Rewrite statement if you attempt to execute another Rewrite without first performing a Read.
Any
attempt to do so results in a
File
Status 21
for record out of sequence.
- When Random or Dynamic access is selected for the Indexed file, the Rewrite statement becomes less restrictive. The Rewrite does not have to be preceded by a successful Read statement. The primary Key determines the placement of the record in the file.
- Its suggested that that you always Read the record that you are going to Rewrite. Because the Rewrite statement allows you to replace a record without regard to its contents, erasing information in your data record with a Rewrite is relatively easy. Imagine that you want to change a dealer’s phone number. If you fill in a record with dealer number and phone number and then Rewrite the record, all of the other information in the record is lost. It is replaced by the values that you may have had initialized or have left over from a previous, but unrelated, Read statement. The best practice is to Read the record, move in the fields being updated, and then Rewrite the record.
- The act of rewriting a record does not change the current record positioning in the file. Therefore, you can change the contents of a record, even changing the Alternate Key value by which you are reading. The next record you Read is then based on what that Key used to be and not the new value. For example, if you are reading the dealer file by Alternate Key value and you change a last name from "Smith" to "Jones", your next Read returns the record after "Smith", not the record after "Jones".
Example:
000207 Move "(909) 555-1212" To Home-Phone Of Dealer-Record
000208 Rewrite Dealer-Record
000209 Invalid Key Move Spaces To Error-Message
000210 String "Error Rewriting Dealer File " Dealer-Status
000211 Delimited By Size Into Error-Message
000212 Set File-Error To True
000213 End-Rewrite
Deleting Records:
- Unlike the Write and Rewrite statements, when a Delete statement is coded, the filename is specified, for example:000215 Delete Dealer-File
- When Organization is Sequential, the record deleted is the last record read. The Delete statement is valid only when the last operation against the file is a successful Read statement. If not, the Delete returns a File Status value of 43. Because a Delete cannot return File Status values beginning with a 2 when the file is Open with Sequential access, coding Invalid Key on such a Delete is not allowed.
- When Dynamic or Random access is selected for the file, the Delete statement, like the Rewrite, becomes a little less restrictive. The record being deleted need not have been previously read. Simply fill in the primary Key information in the record description for the file and issue the Delete statement. If the record does not exist, a File Status of 23 is returned and an Invalid Key condition exists. You may code the Invalid Key clause on a Delete statement if the access mode of the file against which the Delete is being processed is Random or Dynamic.
Relative Files:
- There are no Alternate keys.
Select Rel-File Assign To "Relative.Dat" Organization Relative Access Dynamic Relative Key Is Rel-Work-Num File Status Rel-Status.
- The field that defines the Key is specified with the Relative Key clause, not the Record Key clause as was the case for an Indexed file. The Relative Key can be any unsigned integer data item.
- We must take care to make your Relative Key field large enough to handle the greatest number of records you expect to have in the file. If the field is too small and you attempt to Write a record whose Key value exceeds the maximum for the file, an Invalid Key condition occurs and the File Status is set to 24.
- As with an Indexed file, the Start statement positions the file for the next Read. Start, Read, Write, Rewrite, and Delete
000145 Start Relative-File Key = Relative-Key
000146 Invalid Key
000147 String "Start Error Number "
000148 Relative-Status
000149 Delimited By Size
000150 Into Error-Message
000151 Not Invalid Key
000152 String "Start Successful "
000153 Relative-Status
000154 Delimited By Size
000155 Into Error-Message
000156 End-Start
000159 Read Relative-File Next
000160 At End
000161 Move "End of File " To Error-Message
000162 End-Read
- Delete removes the Relative record whose Relative record number is set in the Relative-Key field. Be aware that if the fifth record of the file is deleted in this method, the sixth record does not become the fifth, and so on. The result is a missing record in the Relative file. If you try to do a random Read, Delete, or Rewrite on this record now, you receive a File Status 23. If you Write the record again, it is created in its previous physical location in the file
Imp
points:
CHAPTER 17. Sorting
- With a simple statement, COBOL allows us to sort a data file. We may even sort the data file in place. That is, we can take a file, sort it, and not create a separate output file.
File
organization and access modes are not specified for the file.
However
the file needs to have a unique name.
- We may assign actual physical files for sort or just use symbolic names.
000010 Select Sort-Work Assign to Symbolic-Sort-Name.
- In addition to the Select statement, a special File Section entry is required under the Data Division. This entry is the Sort Description, or SD. The SD is coded in exactly the same manner as an FD, but identifies the file as a Sort Work File to the system. A typical SD is coded as follows:
000020 SD Sort-Work.
000021 01 Sort-Record.
000022 03 Sort-Field-1 Pic X(20).
000023 03 Sort-Field-2 Pic X(20).
000024 03 Filler Pic X(20).
The
SD
simply refers to the Sort
Work File.
- The simplest sort reads an input file, sorts the records, and creates an output file. The records in the three files have the same record layout.
- When sorting, any number of fields may be specified as Key fields—the fields that are used to control the Sort sequence. The order of the Sort is also specified. The Sort may be in Ascending or Descending sequence on the various Key data fields involved.
- For convenience the SD layout is generally kept same as that of the FD layout.
- The files specified with Using and Giving can be the same.
000070 Sort Sort-Work Ascending Key Last-Name Of Sort-Record
000071 First-Name Of Sort-Record
000072 Middle-Name Of Sort-Record
000073 Using Dealer-Text
000074 Giving Dealer-Text
Note that we are sorting the sort dataset using the input dataset and writing the results to output dataset.
The filename specified after Sort is always the Sort Work File and must be described with an SD entry in the File Section.
Notice
that the program had no Open,
Close,
Read
or Write
statements. The Sort
performs all of these operations automatically.
- Following are how sort dataset is specified using SELECT statement.
000014 Select Sort-Work Assign To Dealer-Sort-Work.
The name chosen, Sort-Work, is not significant. Any valid filename will work as well. Sort-Work is descriptive, and it is a good programming practice
000070 Sort Sort-Work Descending Key State-Or-Country Of Sort-Record 000071 Ascending Key Last-Name Of Sort-Record 000072 First-Name Of Sort-Record 000073 Middle-Name Of Sort-Record
- The input and output files from a sort need not be the same file type.
We
can create an indexed file from the sequential file by sorting. All
we would need to do is to specify the Indexed file as the output in
the Giving clause of the Sort statement.
When
an Indexed file is specified in the Giving clause of a Sort
statement, the Sort Key must be the same as the Primary Key of the
Indexed file. In addition, the SD must match the FD for record size
and the location and length of the Primary Key field.
The
Select statements are provided for all three files: the Line
Sequential input file, the Indexed output file, and the Sort Work
File.
000011 Select Dealer-Text Assign To "Dealer.TXT"
000012 Organization Line Sequential
000013 Access Sequential.
000014 Select Dealer-File Assign To "Dealer.Dat"
000015 Organization Is Indexed
000016 Record Key Dealer-Number Of Dealer-Record
000017 Alternate Key Dealer-Name Of Dealer-Record
000018 Access Is Sequential.
000019 Select Sort-Work Assign To Dealer-Sort-Work.
000043 Sort Sort-Work Ascending Key Dealer-Number Of Sort-Record
000044 Using Dealer-Text
000045 Giving Dealer-File
000046 Display "Sort Complete"
000047 Stop Run
000048 .
Manipulating Data During the Sort
- This diversity is handled by coding Input and Output procedures on the Sort.
If
any kind of looping is required then we must handle it on our own.
- The statement that writes records to the Sort Work File is the Release statement, and its coding is similar to the Write statement. We may Release a Sort record by using the From clause to build the Sort record in Working-Storage if desired. As with the Write statement, the data in the record description area of the Sort record cannot be relied on after a Release statement is executed.
- By using the Input Procedure, you can create a Sort Work File and output file such that the record layouts differ, unlike Using and Giving in which the record layouts had to be the same.
000075
Sort Sort-Work Ascending Key Last-Name Of Sort-Record
000076
First-Name Of Sort-Record
000077
Middle-Name Of Sort-Record
000078
Input Procedure Sort-In
000079
Giving Address-File
000080
Display "Sort Complete"
000081
Stop Run
The
Input Procedure, Sort-In, handles the Open, Read, and Close
statements of the input file. Notice that if the state is not "CA",
the Sort record is not released, which limits the Sort to records
where the state is "CA".
Example:
000083
Sort-In.
000084
Open Input Dealer-File
000085
Perform Until All-Done
000086
Read Dealer-File
000087
At End Set All-Done To True
000088
Not At End
000089
If State-Or-Country Of Dealer-Record = "CA"
000090
Move Corresponding Dealer-Record To Sort-Record
000091
Release Sort-Record /*RECORD AND NOT FILE*/
000092
End-If
000093
End-Read
000094
End-Perform
000095
Close Dealer-File
000096
.
We
explicitly move the data to the sort record. The Sort record layout
may not be same as that of input file.
We
may pass only specific fields to the output for SORTING pupose
By
using the same field names in the Dealer-Record and Sort-Record, we
are able to utilize Move with Corresponding. Notice that more fields
are defined in the Dealer-Record than in Sort-Record, yet Move with
Corresponding correctly moves only those fields where the field
names match.
Note
the Close of the input file after processing is complete. No Open or
Close statements are coded for the Sort Work File.
The
only operation relating to the Sort Work File releases the record to
the Sort.
Note
that its not necessary to use the OUTPUT procedure if we are using
Input procedure. With input procedure the output could be a file.
- Thus with input procedure we can do any processing needed before sorting and with output procedure we process data after sorting.
Only
when we are using USING or GIVING the sort takes care of file
handling.
- The Output Procedure does not necessarily have to create a sorted output file.
- In the Output Procedure, We may Read records from the Sort Work File. We do not code normal Open, Read, or Close statements for the sort datasets. The Sort positions the file properly and handles any necessary internal Open and Close operations.
- The Return statement retrieves records from the sorted Sort Work File. Return behaves the same as a Sequential Read.
- We must code an At End clause to detect the end of file. We may Return the record into another data area, just as we can with Read, by using Return with an Into clause.
000073
Sort Sort-Work Ascending Key Dealer-Number Of Sort-Record
000074
Using Dealer-Text
000075
Output Procedure Sort-Out
000076
Display "Sort Complete with " Record-Count "
Records."
000077
Stop Run
Here
we have not used input procedure. However there could be cases where
in we have input pocedure as well.
- The Return statement, like Read, uses the name defined in the FD, not the record description, to describe the data being returned.The At End clause handles the end-of-file processing. Regular record processing occurs after the Not At End clause. Notice the use of the End-Return explicit scope terminator.
000079
Sort-Out.
000080
Open Output Dealer-File
000081
Perform Until All-Done
000082
Return Sort-Work Into Dealer-Record
000083
At End Set All-Done To True
000084
Not At End
000085
Add 1 To Record-Count
000086
Move Zeros To Last-Sold-Amount
000087
Last-Sold-Date
000088
Sold-To-Date
000089
Commission-To-Date
000090
Write Dealer-Record
000091
End-Return
000092
End-Perform
000093
Close Dealer-File
- In these Sort examples, the various record sizes and layouts of the input file, output file, and Sort Work File have been the same. However, when using Sort, you may use records of varying sizes. The only restriction is that no input record may be longer than the Sort work record, and if variable-length records are used, none may be shorter than the shortest allowed record in the Sort Work File.
- When sorting a file, we may encounter duplicate Sort Keys. Duplicates are allowed and will cause no problems. The order of the records with the duplicate Key fields in the Sort file is undetermined. We can control the order, forcing the duplicates to appear in the same order as the input file, by adding the word Duplicates, which is short for Duplicates In Order, to the Sort statement.
000073
Sort Sort-Work Ascending Key Dealer-Number Of Sort-Record
000074
With Duplicates
000075
Using Dealer-Text
000076
Output Procedure Sort-Out
CHAPTER
21
Date
Manipulation.
- Before 1989 the only way to determine the system date was to use the Accept verb with the From Date and Day clauses. This technique returned only a two-digit date. In 1989 the 1985 COBOL standard was revised to include a new set of features called Intrinsic Functions.
The
three different standard Accept
statements related to date processing are
000100
Accept The-Date From Date
000101
Accept The-Day From Day
000102
Accept The-Weekday From Day-Of-Week
- The first returns the date in a format known as Year-Month-Day. The field The-Date is defined as a six-digit numeric field. The first two numbers represent the last two digits of the current year. The next two represent the month, and the last two the day of the month.
- The second format returns the Julian date. The Julian date is a five-digit numeric field. It contains the two-digit year and a three-digit number corresponding to the day of the year.
- The third format returns the current day of the week. The value is a single-digit numeric field. For example, 1 is returned for Monday, 2 for Tuesday, and 3 for Wednesday.
- Intrinsic Functions are used like literals.
- They are invoked by coding the word Function followed by the name of the Intrinsic Function to be used.
- The Function for returning the current system date and time is Current-Date.
- Function Current-Date is one of the few Intrinsic Functions that return an alphanumeric value. This Function returns a field that is 21 characters long.
- The final five characters return the offset from Greenwich mean time (GMT) for time-zone conversion.
000010
01 Current-Date-Group.
000011
03 Todays-Date.
000012
05 Today-YYYY Pic 9(4).
000013
05 Today-MM Pic 9(2).
000014
05 Today-DD Pic 9(2).
000015
03 Time-Now.
000016
05 Time-Hour Pic 99.
000017
05 Time-Minutes Pic 99.
000018
05 Time-Seconds Pic 99.
000019
05 Time-Hundredths Pic 99.
000020
03 GMT-Offset.
000021
05 GMT-Direction Pic X.
000022
05 GMT-Hours Pic 99.
000023
05 GMT-Minutes Pic 99.
000026
Move Function Current-Date To Current-Date-Group
000027
Display "Today = " Todays-Date
000028
Display "Time = " Time-Now
000029
Display "GMT offset = " GMT-Offset
The
GMT-Direction
is either a plus sign or a minus sign (+
or -),
indicating the conversion that was applied to GMT to achieve local
time.
- If we want to use the Current-Date Intrinsic Function but require only the date, not the time values, we can use reference modification. For example, we can code:
000101
Move Function Current-Date (1:8) to Date-Only
- This can be made easy by the use of two functions: Integer-OF-DATE and DATE-OF-INTEGER.
Integer-Of-Date
accepts a single argument: the
date in Year-Month-Day
format, using a four-digit year.
- We can use the opposite procedure to convert a date from an integer date to a regular Gregorian date in the format YYYYMMDD.
000019
Compute Date-To-Convert =
000020
Function Date-Of-Integer (Integer-Version-Of-Date)
- Determining the days between particular dates becomes easy.Simply convert each date to an integer date and compute the difference. Likewise, if you want to compute a date that is a certain number of days in the future, convert the date to an integer, add the number of days, and reconvert the result to a date.
Integer-value-of-date
= function INTERGER-OF-DATE(CURRENT-DATE(1:8))
COMPUTE
Integer-value-of-date= Integer-value-of-date +30
New-date
= function DATE-OF-INTEGER( Integer-value-of-date)
The
Integer-Of-Date
Function
can also be used in a calculation to determine the day of the week
for a particular day. Because day 1 in the COBOL calendar, January 1,
1601, is a Monday.ie day-of-week=1. This is the reason why the date
jan 1 1601 was chosen., Thus figuring the day of the week for any
other, later date is fairly easy.
All
we have to do is divide the integer value of the date by 7—the
number of days in the week—and examine the remainder.
If
the remainder is 1,
the day of the week is Monday; 2
is Tuesday, 3
is Wednesday, and so on. If the day is Sunday, the remainder is
zeros.
The
quotient will give the number of weeks since 1601 jan 1.
- To properly validate days in February, you must determine whether the year being checked is a leap year. The rules for determining a leap year are simple. Any year evenly divisible by 4, except those years evenly divisible by 100 and not evenly divisible by 400, is a leap year. The year 2000 is a leap year because it is evenly divisible by 400. The year 1900, although evenly divisible by 4, was not a leap year because it was evenly divisible by 100 and not by 400.
- The Functions related to the Julian date are Day-Of-Integer and Integer-Of-Day.
- These Functions make conversion to and from the Gregorian date simple. If we want to convert from Gregorian date, use the Function Integer-Of-Date to find the integer date of the day in question. Then, using that integer, execute the Function Day-Of-Integer. The Julian date is returned in YYYYDDD format, where YYYY is the full four-digit year and DDD is the day of the year.
- To convert from Julian date to Gregorian date, use the Function Integer-Of-Day to determine the integer date; then use the Function Date-Of-Integer to find the Gregorian date.
Summary:
We
know 5 functions related to date operation:
- CURRENT-DATE : Gives current date with time and gmt offset
- INTEGER-OF-DATE : number of days since Jan 1 1601
- DATE-OF-INTEGER : converts a integer to date.
- INTEGER-OF-DAY: input is julian date and it gives number of date since jan 1 1601
- DAY-OF-INTEGER: converts integer to julian date.
CHAPTER
22.
Other
Intrinsic Functions
Mathematical
functions:
Each
trigonometric Function accepts a single argument, which is specified
within parentheses following the Function name. These Functions are
|
Function Cos |
|
Function Sin |
|
Function Tan |
|
Function Asin |
|
Function Acos |
|
Function Atan |
- The Cosine Function returns a numeric value in the range of plus or minus1
The
argument used with the Cos Function must
be numeric and is specified in radians.
Because
the argument is in radians, we might need to convert an angle to
radians. We could use the below for this purpose:
000101
Compute Radians = Angle * (3.14159265358979324 / 180)
- The Sin Function returns a numeric value in the range of plus or minus 1 that approximates the value of the Sin of the argument. As with Cosine, the argument value is specified in radians.
- The Tan Function returns a numeric value that approximates the value of the Tangent of the argument. The argument value is specified in radians.
- The Atan Function returns an approximation of the ArcTangent of the specified argument. The value is returned in radians.
- Two different logarithm Functions are provided. These numeric Functions accept a single numeric argument.The Log Function returns an approximation of the natural logarithm of the specified argument.The Log10 Function returns an approximation of logarithm to base 10 of the argument. The argument must be a positive number.
- Imp: Factorial Function to find the factorial of an argument. The argument specified must be either zero or a positive integer. When the argument specified is zero, a value of 1 is returned from the Function; otherwise, the factorial is returned. Make sure that the numeric field you are computing the result into is large enough to contain the value. To compute the factorial of7, code the following:
000105
Compute The-Factorial = Function Factorial (7)
- The Sqrt Function approximates the square root of the argument.
000106
Compute Square-Root = Function Sqrt (Numeric-Field)
- COBOL has two Functions that can find the integer portion of a numeric field. The two Functions differ in how they handle negative numbers. The first Function,Integer-Part, returns the integer portion of the argument.
000107
Compute The-Integer-Part = Function Integer-Part (-1.9)
returns
negative1 in The-Integer-Part. Any decimal positions are removed.
If
the argument were 1.9, the value returned would be 1.
The
sister Function,Integer,
returns
the greatest integer value that is less than or equal to the
argument. WithInteger, the example
000108
Compute The-Integer-Part = Function Integer (-1.9)
returns
a value of negative2. Negative 2 is the greatest integer value that
is less than or equal to negative1.9.
For
positive numbers, the two Functions,Integer- Part and Integer, return
the same result.
- Rem Function. This Function returns the remainder of the first argument divided by the second.
Following
is the calculation done:
000109
Compute Remainder = First-Argument – 000110 (Second-Argument *
000111 Function Integer-Part (First-Argument/Second-Argument))
A
Function that is very similar to Rem is MOD. Mod accepts two
arguments, and returns an integer that is the value of the first
argument using the second argument as the modulus. For positive
numbers, the value returned is the same as that of Rem. However,
when negative numbers are involved, the values returned by Mod and
Rem differ because of the slight variation in the calculation used to
arrive at the Mod result. The calculation for Mod uses Integer
rather than Integer- Part.
- There are Functions for Max, Min, Mean, Median, Midrange, Range, Sum, Variance, and Standard-Deviation. Two related Functions are Ord-Max and Ord-Min.
- The Function Max returns the maximum value from a list of arguments.
000116
Compute Max-Value = Function Max (Field-1 Field-2 Field-3)
Similarly,
the Min
Function
returns the minimum value of the arguments specified for the
Function.
- Ord-Max and Ord-Min are related to Max and Min. Instead of returning the highest or lowest value, Ord-Max and Ord-Min return the relative position of the argument in the list that contains the highest or lowest value.
- The Functions Mean and Midrange are closely related. Both Functions return numeric values.The Mean Function returns the average value of all of the arguments specified for the Function.The Midrange Function returns the average value of the highest and lowest argument values. Arguments are specified just as for the Max Function.
000117
Compute The-Median = Function Median (Field-1 Field-2 Field-3)
- The Range Function returns the range of numbers involved in the argument list. The Function returns a number that is the difference between the highest and lowest value in the argument list. If you have arguments where the lowest value is10and the highest value is20, the range is10.
- The Sum Function adds all the arguments specified together and reports that result. The following two lines of code produce identical results:
000118
Compute The-Result = Function Sum (Field-1 Field-2 Field-3)
000119
Add Field-1, Field-2, Field-3 Giving The-Result
- The Variance Function returns a numeric value that approximates the variance between the list of arguments specified. It is simply the square of the standard deviation of the list of arguments.
The
Elementary Level of the table must be specified.
If
the entire table is to be processed, the subscript specified is the
word All. By
using a variable-length table defined with the Depending On clause,
we can process a variable number of items with these Functions. For
example, you might have the following table defined:
000011
01 Work-Table.
000012
03 Work-Entry Pic 9(3) Occurs 1 To 20 Times
000013
Depending On Num-Entries.
000014
01 Num-Entries Pic 9(3) Value 3.
Assume
that the first element of the table is equal to 5, the second is
equal to 20, and the third 10. The following line finds the minimum
value in the table:
Compute
Result = Function Min (Work-Entry (All))
- When a Function Ord-Min or Ord-Max is used with a table, the element that is the Minor the Max is returned. Function Ord-Min provides a simple method to find the element of the table that contains the lowest value.
- TheFunctionsrelated to working with strings are Length, Min, Max, Ord-Min, Ord-Max, Char, Ord, Upper-Case, Lower-Case, Reverse, Numval, andNumval-C.
- The Length Function returns a numeric value that corresponds to the length of the argument.
Even
if the field contains spaces, the Length Function returns the full
field defined length.
Another
use for the Length Function is to return the actual length of a
variable- length table. When you use the Function with a table, the
actual used length is returned. For example, if your table is
defined as
000011
01 Variable-Table.
000012
03 Table-Items Occurs 1 To 500 Times
000013
Depending On Table-Occurrences.
000014
05 Table-Element Pic 9(3).
We
can determine the actual utilized length of the table using theLength
Functionas follows:
000019
Compute Item-Length = Function Length (Variable-Table)
- The Min, Max, Ord-Min, and Ord-Max Functions work with alphanumeric data items in the same way that they work with numeric items. We can use the Min and Max Functions to find the minimum and maximum values in a series of strings stored in a table. Or you can use Ord-Max and Ord-Min to determine which elements of a table have the greatest and least value.
- The Char Function accepts a numeric argument and returns the character that corresponds with that numeric value in the collating sequence in use by the program. For example, if the following statement is executed, the letter"X"is returned.
000016
Move Function Char (89) to Character-Returned
000017
Compute Position-Returned = Function Ord ("Q")
However,
with the Ord
Function only a single character field is valid.
- The Upper-Case Function converts an alphanumeric data item to uppercase. The argument can be any Elementary or Group Level alphanumeric data item. Each character within the field is converted to all capital letters.
000018
Move Function Upper-Case (Input-Field) To Output-Field
000019
Move Function Lower-Case (Input-Field) To Output-Field
- The Reverse Function reverses the order of the characters in the argument. For example, your program might contain the following Working-Storage entries:
000010
01 Input-Field Pic X(15) Value "COBOL".
000011
01 Output-Field Pic X(15) Value Spaces.
000025
Move Function Reverse (Input-Field) To Output-Field
- COBOL provides a much simpler method of converting these edited fields back into numbers.
When
passed a valid edited numeric field,Numval returns a numeric value
that is equal to the numeric value of the input field. Numval cannot
handle input with currency symbols, commas, CR, or DB. Numvalis
simply coded as shown here:
000025
Compute Converted-Value = Function Numval (Field-To-Convert)
Numval-C
accepts
a second argument, which is the currency symbol to expect in the
input field. If this argument is omitted, the currency symbol for the
current character set is used. In
addition to handling the currency, Numval-C handles embedded commas
and the CR and DB characters that might appear at the end of a
numeric edited field.
000026
Compute Converted-Value =
000027
Function Numval-C (Field-To-Convert "$")
Numval-C
is slower.
When-Compiled
and Random.
- The When-Compiled Function returns the date and time the program was compiled. The format of the value returned is the same as that of the Current-Date Function.
The
following code displays the compilation date of a program:
000100
Display Function When-Compiled (1:8)
- The Random Function returns a pseudo-random value that is less than one but greater than or equal to zero.
To
create a valid, random, whole number from the decimal value returned
by the Random Function, we
must multiply the value by your maximum value and then add 1.
For
example, to generate a random number, (Random-Number Pic 9(3))
between 1 and 500, we may code the following:
000100
Compute Random-Generate = Function Random (Seed-Number)
000101
Compute Random-Number = (Random-Generate * 500) + 1
The
Function accepts a single integer argument that is the “seed”
value for the random number Function. If you need to reproduce a
series of random numbers, simply code the Random Function with the
same starting seed value. After
the initial execution of the Function, the argument should be
omitted. Many programmers use the time as the initial seed value
when a random number is desired.
CHAPTER
23
- COBOL programs may execute other COBOL programs or even programs written in a different source language.
The
calling program is simply the program that issues the Call
statement,
causing another program to be executed.
- These called programs are often referred to as subprograms because they are called from a Main program.
- Normally the programs are coded with STOP-RUN to end the execution. But with subprograms we use Exit Program causes control to return immediately to the calling program. Any files that are open in the subprogram are automatically closed as if a Close statement were executed. The only difference is that no Declaratives are processed, even if they are coded.
- In addition to simply calling a subprogram, we can pass data to and from the subprogram.
When
passing data to a subprogram, the Call statement is altered slightly
with the addition
of the Using clause. The
various Call parameters are specified after the Using clause.
By
default the COBOL passes
the memory address of these data items to the subprogram, which then
has access to those data items. The
Call parameters may be any literals or data items. Thus any change
made by the called program to the data items being passed will
reflect in the calling program
Example:
Call "Chapt23e" Using Passed-Date Valid-Status
- The Linkage Section appears immediately before the Procedure Division of the called program.
000023
Linkage Section.
000024
01 Passed-Date.
000025
03 Date-To-Validate Pic 9(8).
000026
03 Date-To-Validate-X Redefines Date-To-Validate.
000027
05 Date-MM Pic 99.
000028
05 Date-DD Pic 99.
000029
05 Date-YYYY Pic 9(4).
000030
01 Valid-Status Pic X(40).
- The Procedure Division is coded with a Using clause, which references the Call parameters as named in the Linkage Section. This combination of Linkage Section and Procedure Division setup allows the called program to reference the passed data in its exact memory location. The called program may modify this data, and when control is passed back to the calling program, the modified data will be available.
In
called program:
000023
Linkage Section.
000024
01 Passed-Date.
000025
03 Date-To-Validate Pic 9(8).
000026
03 Date-To-Validate-X Redefines Date-To-Validate.
000027
05 Date-MM Pic 99.
000028
05 Date-DD Pic 99.
000029
05 Date-YYYY Pic 9(4).
000030
01 Valid-Status Pic X(40).
000031
Procedure Division Using
Passed-Date Valid-Status.
- Another option is to call the subprogram specifying By Content before the data item being passed.We may mix By Reference and By Content items in the same Call statement.
- Calling By Content causes the program to copy the data being passed to a temporary area, passing the address of that temporary area to the called program instead of the address of the actual data item. This method allows the called program to modify this data, but upon return to the calling program, the original data is left intact, thus protecting it.
000028
Call "Chapt23e" Using By Content Passed-Date
Valid-Status
- If you need a value returned, you must always issue the call using By Reference or by not specifying By Content or By Reference and thus defaulting to By Reference.
000028
Call "Chapt23e" Using
By Content
Passed-Date
000029
By
Reference Valid-Status
By
content and By Reference is written before the data item.
- The programs called so far in these examples have been static calls. These programs are actually linked into and become part of the program that issues the Call. If the subprogram is changed, then the calling program must be recompiled or at least relinked so that the new called program can be linked with the calling program
- Dynamically called programs are loaded into memory when the Call is issued. Therefore, these programs can be changed and recompiled independently of the calling program. The use of dynamic calls is specified mainly by the method in which the programs are linked. This is specified during the compilation and linking.
- When using dynamic calls, we can very easily change the name of the program being called. Instead of coding the Call statement using a literal for the program to be called, refer to a data item defined in Working-Storage. For example, we can define an item in Working-Storage as 01 Program-To-Call Pic X(8) Value "CHAPT23E". Coding Call Program-To-Call, issues a dynamic call for CHAPT23E. To call a different program, simply move its name into the Program-To-Call field and issue the Call.
- Dynamically called programs can be removed from memory and reinitialized upon the next Call by coding a Cancel statement. The Cancel statement is followed by the name of the program being canceled or the data field containing the name of the program to be canceled. For example:
000103
Cancel Program-To-Call
One
reason for using CANCEL statement is good housekeeping. At the end of
your program, we should Cancel any dynamically called programs.
Another reason to Cancel a program is to initialize its
Working-Storage to a fresh state upon the next Call of the program.
Remember that the Cancel statement closes any open files that the
called program was using.
When
a Cancel statement is encountered, all files opened by the program
are closed as if a Close statement were issued for each one. No
Declaratives that might be coded for the file are performed with
this implied Close.
On
Exception clause:
- If for some reason the Call is not successful, either because of a memory problem or because the called program is not found, an exception occurs.
- We may capture this exception by coding the On Exception clause with the Call statement. Similarly, the Not On Exception clause is also supported.
000104
Call Program-To-Call
000105
On
Exception Display
"The Call Failed"
000106
Not
On Exception
Display "The Call was Successful"
000107
End-Call
Note
that the program-id of the subprogram is very important when calling
a sub program . It is used to determine which is the called program.
Is
INITIAL:
The
Is Initial clause of the Program Id reinitializes any Working-Storage
entries with a Value clause every time the subprogram is called.
000001 Identification Division.
000002 Program-Id. Chapt23e Is
Initial.
- This can be made sure by making use of copybooks. We would create a copy book to be used inside the calling function working -storage area and also in the linkage section of the called program. This way we can make sure the definition is same in both called and calling program.
- It uses the Copy statement.
The
Copy statement simply inserts another file containing source code
into your program. When compiled, the compiler assembles the full
program byexpanding the copy members into the source of the program.
These copy members are referred to as Copybooks.
- The use of the Copy statement is not limited to the Linkage Section. You can use the Copy statement anywhere in a program except within Copybooks.