Monday 13 February 2012




CHAPTER 9:
The Evaluate Statement:

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

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

  1. 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.
  2. 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 .

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


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


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

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

  1. Like If statements, you may nest Evaluate statements. Subsequent Evaluate statements may be coded in the statements that appear after the selection objects

  1. The Evaluate statement can create complex decision-making structures by using more than one selection subject.
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:
  1. 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 .

  1. The simplest format of the Perform statement allows you to Perform a Section or Paragraph with in the Procedure Division

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

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

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

  1. 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:

  1. 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:

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

  1. 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:
  1. In Inline perform the lines of code that are to be performed are located immediately after the Perform verb and not elsewhere in the program. 

Perform with Varying:
  1. 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)

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

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

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


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


  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:
  1. 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:

  1. Tables are the COBOL version of an array . They can be used for subtotaling and data validation.
  2. 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.

  1. A table is defined by using the Occurs clause in the Data Division .
  2. 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 in line 11 specifies that this field is repeated 12 times; in other words, the table has 12 elements. The subscript associated with the first element is 1, and the subscript associated with the last is 12.

  1. 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:

  1. 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:

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

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

  1. 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:

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

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

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

  1. A file is made up of individual records .
  2. A record is a collection of individual fields or data items .
  3. The format or formats of the records in the file are defined in your COBOL program .
  4. 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.

  1. The layouts of the records used by the various files in COBOL program
are specified in the Data Division .

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

  1. 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:
  1. Select Statement connects program to file.
  2. The Select statement is coded in the Environment Division , under the Input-Output
  3. Section, in a paragraph titled File-Control.
  4. An internal filename is specified in the Select statement . This name is used to refer in the cobol program.
  5. The filename can be upto 30 characters.
  6. 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.

  1. The Organization clause specifies the type of file you are working with . For Sequential files, the type can be Sequential or Line Sequential.
  2. 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:

  1. The File Description (FD) describes the attributes of the file and its associated data
record or records.

  1. The FD is coded in the Data Division of the File Section.
  2. The Record Description, or descriptions, immediately follow the FD.
  3. The FD contains the same filename as specified in the Select statement . Every file specified with a Select statement requires a File Description entry.
  4. The record description must start with an 01 Group Level item .
  5. 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).

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

  1. 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:

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

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

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

  1. 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:
  1. 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

  1. 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:

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

  1. The statement required to Open the name file for Output is
000091 Open Output Name-File

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

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

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

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

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

  1. 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:

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

  1. 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 specified
      in 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 .


  1. 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 .
  2. 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

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

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


  1. 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:

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

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

  1. 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 .
  2. The Rewrite statement also requires the record description and not the filename—exactly the same as the Write statement .

  1. 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:

  1. Sequential data files can contain variable-length records . These data records contain a table that is defined with an Occurs and Depending On.
  2. 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 .
  3. 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:

  1. An Indexed file is a file that allows access to data records by way of a Key field.
  2. A record in an Indexed file contains at least one Key field. This field is the index to the file.
  3. There must be at least one Key field that contains a value that is unique.
  4. This Key field is the Primary Key. Each record in the file is uniquely identified by this Key.

  1. Indexed files need not be limited to a single Key field.
    Indexed files may have Alternate Key fields .
  2. 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 .
  3. 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:

  1. 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 contain
    duplicates; it does not have to uniquely identify the record as does the Primary Key field.
  1. For an Indexed file, Organization Indexed must be included in the Select statement .

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

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

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

  1. 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 by
    a hardware problem, such as running out of disk space, or secondary f ile
    allocations 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.

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

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

  1. A new File Status value—22—is possible when an Indexed file is Open for Output
    with 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.

  1. Using Random access the order in which the records are added does not
    matter. 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:

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


  1. 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:
  1. 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.

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

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

  1. Start can come with Invalid key clause.

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


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

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

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

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

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

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

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


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

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

  1. 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:

  1. Dynamic access is the slowest and most versatile of the access methods used to
retrieve records from an Indexed file .

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

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

  1. When Dynamic access is specified, we can perform Random reads using exactly the same method as if the file were Open with Random access .

  1. 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:


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

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

  1. 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:

  1. The way the Write statement works depends on the access method used and Open mode of the file.

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

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


  1. Remember that any File Status that begins with 2, such as 22, is also an Invalid Key condition and that you may code the Invalid Key clause with the Write.



  1. 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.
  2. 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.

  1. 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:

  1. The Rewrite statement replaces an existing record with a new record.
  2. The behavior of the Rewrite statement depends on the type of access you have selected for the file.
  3. The Rewrite statement is available only when the file is Open I-O.
  4. When the file is defined with Sequential access, the Rewrite statement overlays the last record read with the new data record.
  5. 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.
  6. When rewriting a record you may not change the primary Key.
Any attempt to do so results in a File Status 21 for record out of sequence.


    Note that When using Indexed files, regardless of the access mode specified, you cannot change the primary Key.



  1. 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.
    When you execute the Rewrite statement, if the primary Key does not exist for the record you are rewriting, then the File Status is set to 23—record not found—and an Invalid Key condition occurs.
    If you Rewrite a record and cause a duplicate Alternate Key condition, a File Status of 22 is returned and an Invalid Key condition occurs
  2. 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.


  1. 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:

  1. Delete statement is valid only when the file is Open I-O.
  2. The primary Key of the file is the determining factor in deleting a record.
  3. Unlike the Write and Rewrite statements, when a Delete statement is coded, the filename is specified, for example:
    000215 Delete Dealer-File
  4. 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.
  5. 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.
  6. The Delete statement applies only to the record identified by the primary Key of the data file and not alternate key from which it is to be deleted.



Relative Files:

  1. Relative files behave like Indexed files except the Primary Key for the file is not part of the data record .
  2. There are no Alternate keys.
  3. Relative files are keyed by a Relative record number. The first record in a Relative file is record 1.
  4. The Select statement for the Relative file defines its Organization and tells the program the name of the data field in Working-Storage that contains the record number that is the Key for the file.
  Select Rel-File Assign To "Relative.Dat"
                Organization Relative
                Access Dynamic
                Relative Key Is Rel-Work-Num
                File Status Rel-Status.

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

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


  1. When reading a Relative file with Sequential access, the Relative Key of the record just read is stored in the Relative Key field. If the Key for the last record read exceeds the maximum value that your field can hold, an At End condition occurs and the File Status value is set to 14


  1. As with an Indexed file, the Start statement positions the file for the next Read. Start, Read, Write, Rewrite, and Delete

  1. Zeros cant be moved to the relative key for a read. The program will try to position the file on this Key value but it will fail. An Invalid Key condition will exist with a File Status value of 23.


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


  1. The Read statement with Next returns the next record in the file.

000159     Read Relative-File Next
000160          At End
000161             Move "End of File " To Error-Message
000162     End-Read

  1. 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:

  1. You may update an Indexed file by opening the file I-O or Extend. Opening Extend limits you to adding new records. To update existing records, you must Open the file I-O.
  2. When using Sequential access, you can Rewrite or Delete a record only when the last operation for the file is a successful Read statement.
  3. When using Dynamic or Random access, you can Delete or Rewrite a record without first reading it. You must use caution when performing a Rewrite in this manner so as not to erase information in the record that you want to keep.
  4. Write statements return a File Status 22 if a record already exists in the file with the same primary Key or Alternate Key that does not allow duplicates.
  5. If a Rewrite or Delete is executed for a record that does not exist, a File Status of 23 is returned.
  6. Unlike Write and Rewrite, the Delete statement is coded with the filename, not the record description name, as the identifier for the operation.
  7. Relative files are similar to Indexed files. The difference is that the Key is always a Relative record number, and the field that contains this number is not a part of the data record. The Key field is identified in the Select statement as a Relative Key instead of a Record Key.
  8. Deleting Relative records does not cause the remaining records to be renumbered. Instead, the location where that record was located is cleared, and another record with the same Relative record number may be written in that place.


CHAPTER 17. Sorting







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

  1. Sort work file: Each sort in your program uses a Sort Work File, which contains the records as they are sorted by the system.
We must declare these files in your program with a Select statement, like any other file.
File organization and access modes are not specified for the file.
However the file needs to have a unique name.

  1. We may assign actual physical files for sort or just use symbolic names.
    In some COBOL compilers, Sort Work Files are not assigned to a physical file. The physical file name in the Sort Work File Assign statement is for internal purposes only.

 000010     Select Sort-Work Assign to Symbolic-Sort-Name.

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

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

  1. The Sort statement specifies the name of the Sort Work File, which is the file that is actually being sorted, and the data fields that are to be used as the Key fields for sorting.
  2. 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.
  3. Using clause specifies the data file to be used as input into the Sort. This is the input file to be used for sorting.
  4. Giving clause specifies the data file that is to be the output of the Sort.
  5. When utilizing the USING AND GIVING with the Sort statement, the input and output files cannot be Open by the program. The Sort will take care of all I-O against these files, including the Open, Close, Read, Write, and Close statements.
  6. For convenience the SD layout is generally kept same as that of the FD layout.

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

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



  1. The Sort statement can sort using complex combinations of Ascending and Descending Key fields. For example, you can sort the dealer file Descending by state and the names Ascending under state.
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

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


The Sort statement is coded so that the Sort Key fields and sequence match the Sort Key of the output file. If they do not, the compiler issues a warning and the program does not compile.
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

  1. IN addition to simple sort, the COBOL allows you to manipulate the data going into and coming out of the Sort. This feature allows a single program to read a data file, manipulate the data to a great degree, sort it, and produce output based on this data.

  1. This diversity is handled by coding Input and Output procedures on the Sort.
  2. These procedures permit us to create a Sort file from various input sources—not just from a single input file.
  3. When utilizing the Input and Output procedure, the Sort file does not need to have the same record layout as the input file. The output file does not need to have the same layout as the Sort file.

The Input Procedure:

  1. The Input Procedure allows you to restrict the records that are used in the Sort.
  2. When an Input Procedure is specified, we are responsible for the file handling necessary to build the Sort records. However, we do not code any Open, Close, or Write statements for the Sort Work File.
  3. The Input Procedure specified is performed to create the Sort records, which are released to the Sort. The Input Procedure is performed only once for each Sort statement coded.
If any kind of looping is required then we must handle it on our own.

  1. When the Input Procedure is complete, the Sort Work File is sorted in the sequence specified.
  2. 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.
  1. 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.


  1. The Input Procedure name is not significant. we may call it anything that we desire.

  1. One common mistake is to assume that the Input Procedure will be executed repeatedly until the input file has been read. In fact, the Input Procedure is performed only once.
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.

The Output Procedure:

  1. The Input Procedure processed data before the Sort. If we want to process data after the Sort, we may code an Output Procedure with your Sort statement.

  1. Thus with input procedure we can do any processing needed before sorting and with output procedure we process data after sorting.

  1. The Output Procedure is responsible for all necessary file access. That is if we are writing sorted data several files then we have to take care of opening , writing etc of the file.
Only when we are using USING or GIVING the sort takes care of file handling.

  1. The Output Procedure does not necessarily have to create a sorted output file.

  1. Like the Input Procedure, the Output Procedure is performed only once and not repeatedly for each record. It is executed immediately after the Sort Work File is sorted into the desired sequence. We are responsible for coding the processing loop necessary for the Output Procedure to work properly.

  1. 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.
  2. The Return statement retrieves records from the sorted Sort Work File. Return behaves the same as a Sequential Read.
  3. 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.






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


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

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

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

  1. COBOL uses three different, but related, clauses with the Accept verb to obtain the date.

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.

  1. The new method for retrieving the current system date and time uses a new feature called an Intrinsic Function.
  2. Intrinsic Functions are used like literals.
  3. They are invoked by coding the word Function followed by the name of the Intrinsic Function to be used.


The Current-Date Intrinsic Function:

  1. The Function for returning the current system date and time is Current-Date.
  2. 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 first eight positions are the current date in Year-Month-Dayformat, using four digits to represent the year.
  • The next eight positions represent the current system time in Hour-Minute-Second-Hundredths format.
  • 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.

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

Finding Days Between Dates:

  1. 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.
The Function returns the number of days since December 31, 1600. Day 1 is January 1, 1601.

  1. The numeric-returning Intrinsic Functions, such as Integer-Of-Date and Date-Of-Integer, must be used in a mathematical statement—that is, within a mathematical expression such as Compute. Unlike the alphanumeric-returning Current-Date Function, you cannot use these Functions in a Move statement.

  1. 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)

  1. 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)



Determining the Day of the Week for a Particular 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.

Validating Dates:

  1. When validating a date, we must first ensure that it has been entered in the proper format by checking the values in the individual fields that make up the date. First, check the month value to determine whether it is between 1 and 12. Any value outside that range is obviously invalid.
  2. Then we must check the value of the day to determine whether it falls within the prescribed value for the particular month with which it is associated. Each month, with the exception of February, has a set number of days. A table of maximum day values is the simplest method of validating the day.
  3. 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.

Other Kinds of Dates:

  1. The Functions related to the Julian date are Day-Of-Integer and Integer-Of-Day.
  2. 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.

  1. 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:

  1. CURRENT-DATE : Gives current date with time and gmt offset
  2. INTEGER-OF-DATE : number of days since Jan 1 1601
  3. DATE-OF-INTEGER : converts a integer to date.
  4. INTEGER-OF-DAY: input is julian date and it gives number of date since jan 1 1601
  5. 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

  • Cosine
Function Cos
  • Sin
Function Sin
  • Tangent
Function Tan
  • Arcsin
Function Asin
  • Arccosine
Function Acos
  • Arctangent
Function Atan

  1. 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)
  1. 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.

  1. The Tan Function returns a numeric value that approximates the value of the Tangent of the argument. The argument value is specified in radians.

  1. The Asin and Acos Functions return an approximation of the ArcSin and ArcCosine of the argument. The argument must fall within the range of plus or minus 1. The value returned is in radians.

  1. The Atan Function returns an approximation of the ArcTangent of the specified argument. The value is returned in radians.

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


  1. 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)

  1. The Sqrt Function approximates the square root of the argument.
000106 Compute Square-Root = Function Sqrt (Numeric-Field)

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

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



Statistical Functions:

  1. There are Functions for Max, Min, Mean, Median, Midrange, Range, Sum, Variance, and Standard-Deviation. Two related Functions are Ord-Max and Ord-Min.

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

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

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

  1. The Median Function sorts the values of the arguments and returns the value of the argument that is in the middle of the sorted list. If Field-1has a value of 3,Field-2 has a value of 300 and Field-3 has a value of10, the following code returns a value of10:
000117 Compute The-Median = Function Median (Field-1 Field-2 Field-3)

If the three fields are arranged in sorted order, the middle value is10.

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


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

  1. The Standard-Deviation Function returns an approximation of the standard deviation of the arguments. If all the arguments have the same value,0is returned; otherwise, the algorithm is fairly involved.
  2. 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.

  1. IMP: The statistical Functions, Max, Min, Ord-Max, Ord-Min, Mean, Median, Midrange, Standard-Deviation, Sum, and Variance, accept a table as the argument.
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))

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


String Functions:

  1. TheFunctionsrelated to working with strings are Length, Min, Max, Ord-Min, Ord-Max, Char, Ord, Upper-Case, Lower-Case, Reverse, Numval, andNumval-C.

  1. 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)

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


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

  1. The converse Function is the Ord Function. When passed a character, the Ord Function returns the numeric position of the character in the computer’s collating sequence.
000017 Compute Position-Returned = Function Ord ("Q")

However, with the Ord Function only a single character field is valid.

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

  1. A related Function, Lower-Case, converts a data item to all lowercase characters.
000019 Move Function Lower-Case (Input-Field) To Output-Field

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

If you code the following:
000025 Move Function Reverse (Input-Field) To Output-Field

Output-Fieldwill contain" LOBOC".


  1. COBOL provides a much simpler method of converting these edited fields back into numbers.
Two related Functions handle this type of data conversion. These are Numval and Numval-C.
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.

Miscellaneous Functions:

When-Compiled and Random.

  1. 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)

  1. 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
The Call Interface

  1. COBOL programs may execute other COBOL programs or even programs written in a different source language.
  2. A Call is similar to a Perform. The called program is executed and then control returns to the calling program immediately after the Call statement.
The calling program is simply the program that issues the Call statement, causing another program to be executed.

  1. These called programs are often referred to as subprograms because they are called from a Main program.

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

  1. 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:

  1. The called program must have some way to find the data being passed by the calling program. Remember that the data itself is not passed, but the location or address in memory of that data is. The data is located in the called program by using what is known as the Linkage Section.
  2. The Linkage Section appears immediately before the Procedure Division of the called program.
  3. Under the Linkage Section, the data description of the same information that is passed is coded. Each item passed, however, must have a Group Level definition in the Linkage Section. Each item must match exactly what is passed in the Call statement of the calling 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 of the Called Program:

  1. In addition to the Linkage Section, the called program must identify the data items being passed to it on the Procedure Division line.
  2. 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.

  1. The COBOL standard provides no method for a COBOL program to Call itself or another program that calls a program that in turn issues a Call to the original program. This type of operation is defined as recursion. Thus Recursion not allowed


Call By Reference and By Content:

  1. By default the method of calling is calling By Reference.
When a parameter is passed By Reference, its address is passed to the called program.

  1. 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.
  2. 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

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

Dynamic Versus Static Calls:

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

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

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

  1. 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:

  1. 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.
  2. We may capture this exception by coding the On Exception clause with the Call statement. Similarly, the Not On Exception clause is also supported.
  3. If we choose to use On Exception or Not On Exception, I suggest that you use the End-Call explicit scope terminator.
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.

Using Copybooks in Linkage section:

  1. Another common problem relating to calling subprograms is failure to ensure that the parameters specified for the Call in the calling program match the parameters coded in the Linkage Section of the called program.
  2. 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.
  3. 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.

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