Reading COBOL Layouts

This tutorial on how to read a COBOL layout was written specifically for our customers who have had a conversion performed at Disc Interchange and have received a COBOL layout with the data.  It is intended to give you enough information to read most simple layouts.  It does not cover all topics or everything you would find in a complex layout, and it is intended to explain COBOL layouts only so you can use your converted data, not so you can write COBOL programs. 

This article begins here: Reading COBOL Layouts where you will also find a topic index.

Part 5: Tables and Occurs

A powerful feature of COBOL is the use of tables, via the "OCCURS" and "OCCURS DEPENDING ON" clauses.  This section describes COBOL Tables and the OCCURS and OCCURS DEPENDING ON clauses, both of which cause fields or groups to repeat some number of times.

Contents of this section:
Problems with COBOL Occurs? Request a COBOL quote
We know how to handle them!

   Tables and the OCCURS clause
   Occurs Depending On

Tables and the OCCURS clause

Suppose you wanted to store your monthly sales figures for the year. You could define 12 fields, one for each month, like this:

   05  MONTHLY-SALES-1    PIC S9(5)V99.

   05  MONTHLY-SALES-2    PIC S9(5)V99.
   05  MONTHLY-SALES-3    PIC S9(5)V99.
   05  MONTHLY-SALES-11   PIC S9(5)V99.
   05  MONTHLY-SALES-12   PIC S9(5)V99.
But there's an easier way in COBOL.  You can specify the field once and declare that it repeats 12 times. You do this with the OCCURS clause, like this:
(By now you should also know this can be written on two lines like this):
                                   PIC S9(5)V99.
This specifies 12 fields, all of which have the same PIC, and is called a table (also called an array).  The individual fields are referenced in COBOL by using subscripts, such as "MONTHLY-SALES(1)".  This table occupies 84 bytes in the record (12 * (5+2)). (The sign is embedded, not separate, and the decimal is implied.)

The OCCURS can also be at the group level, and this is the most useful application of OCCURS.  For example, all 25 line items on an invoice (75 fields) could be held in this group:

       10  QUANTITY            PIC 9999.
       10  DESCRIPTION         PIC X(30).
       10  UNIT-PRICE          PIC S9(5)V99.
Notice the OCCURS is listed at the group level, so the entire group occurs 25 times. The order of the data in the file is as-if you had specified multiple groups, like this:

   05  LINE-ITEMS-1.
       10  QUANTITY            PIC 9999.
       10  DESCRIPTION         PIC X(30).
       10  UNIT-PRICE          PIC S9(5)V99.

   05  LINE-ITEMS-2.        10  QUANTITY            PIC 9999.        10  DESCRIPTION         PIC X(30).        10  UNIT-PRICE          PIC S9(5)V99.
   05  LINE-ITEMS-25.        10  QUANTITY            PIC 9999.        10  DESCRIPTION         PIC X(30).        10  UNIT-PRICE          PIC S9(5)V99.
There can be nested occurs -- an occurs within an occurs.  In the next example, suppose we stock ten products and we want to keep a record of the monthly sales of each product for the past 12 months. We could do just that with this table:
           10  MONTHLY-SALES OCCURS 12 TIMES  PIC 999.
In this case, "INVENTORY-ITEM" is a group composed only of "MONTHLY-SALES", which occurs 12 times for each occurrence of an inventory item.  This gives an array (table) of 10 * 12 fields.  The only information in this record are the 120 monthly sales figures -- 12 months for each of 10 items.

We could also have a description for each item. The description would go under the 05 level INVENTORY-ITEM group, at the 10 level, the same as the monthly sales.  Further, we could track, say, the sale price of each item for each month.  A record which will do these things is:

           10  ITEM-DESCRIPTION               PIC X(30).
               15  QUANTITY-SOLD              PIC 999.
               15  UNIT-PRICE                 PIC 9(5)V99.
Notice we have made MONTHLY-SALES a group, which now contains two fields, and the whole group repeats 12 times for each instance of INVENTORY-ITEM.  This short layout has 250 fields: two fields (QUANTITY-SOLD and UNIT-PRICE) that repeat 12 times for each inventory item, times 10 items, plus the ITEM-DESCRIPTION field for each of the 10 items.  Fields and groups can be nested several levels deep, and it's possible to have thousands of fields in a layout only a couple pages long.

Occurs Depending On

One really great feature of COBOL tables, and a really nasty one to convert to other languages, is the "OCCURS DEPENDING ON".  This is an OCCURS, like above, but the number of times it occurs in a particular record can vary (between some limits). The number of times it actually occurs in any particular record will be given by a value in another field of that record. This creates records that vary in size from record to record.

The OCCURS-DEPENDING-ON can include many subordinate fields and groups, all of which occur multiple times.  Further, most compilers allow one or more (fixed) OCCURS to be nested within an OCCURS-DEPENDING-ON, and some compilers allow multiple OCCURS-DEPENDING-ON to be nested, or to occur in succession.  This can get pretty involved, so we will only give one simple example, that of a patient's medical treatment-history record .

       05  PATIENT-NAME                PIC X(30).
       05  PATIENT-SS-NUMBER           PIC 9(9).
       05  NUMBER-OF-TREATMENTS        PIC 99 COMP-3.
           10  TREATMENT-DATE.
               15  TREATMENT-DAY        PIC 99.
               15  TREATMENT-MONTH      PIC 99.
               15  TREATMENT-YEAR       PIC 9(4).
           10  TREATING-PHYSICIAN       PIC X(30).
           10  TREATMENT-CODE           PIC 99.
Here are the significant points of this record:
  1. The name of the record is "PATIENT-TREATMENTS".
  2. The first three fields "PATIENT-NAME", "PATIENT-SS-NUMBER", and "NUMBER-OF-TREATMENTS" occur in the fixed portion of every record.  This fixed portion is the same for every record.
  3. The TREATMENT-HISTORY group is the variable portion of the record. It can occur from 0 to 50 times.
  4. ""NUMBER-OF-TREATMENTS" is a number from 0 to 50 that tells us how many times the group TREATMENT-HISTORY occurs in this record.
  5. The value in NUMBER-OF-TREATMENTS is stored in a comp-3 packed format. This is very common. Also very common is comp or binary format.  All of these are binary data formats.
  6. TREATMENT-HISTORY is a group that is comprised of all the lower level fields beneath it. (Down to the next 05 level, or the end of the record).
  7. All the fields and groups within TREATMENT-HISTORY occur between 0 and 50 times.
  8. Because 0 is a valid number of occurrences, it is possible the variable portion of the record is not present.
  9. The "INDEXED BY TREATMENT-POINTER" clause may or may not be present.  If present it tells the compiler the name of the variable (TREATMENT-POINTER) to use as the index into the array.  If you don't understand this, you can safely ignore the "indexed by..." clause, unless you are programming in COBOL.
  10. TREATMENT-DATE is a group that is comprised of the day, month, and year fields beneath it.
  11. These records vary in size from 41 to 2041 bytes, and would be stored in some type of variable length file.

Our article Occurs...Depending On discusses this further, and has suggestions for converting variable tables to PC files.

Next: Part 6 Redefined Records

Additional Information

For more articles on data conversion, see our TechTalk Index.

Our COBOL Conversion Services

Disc Interchange Service Company's primary business is converting mainframe COBOL files.  We have the tools to properly convert both fixed-length tables and variable-length tables, including nested tables, in either EBCDIC or ASCII.

With over 24 years of experience with thousands of files, we have the knowledge to do your job right the first time.

Mainframe & AS/400 Conversions
Mainframe & AS/400 Conversion to PC

With 24 years experience, we are the experts at transferring mainframe data to PCs.
Get more information on IBM Mainframe conversions
Request a COBOL quote

Disc Interchange Service Company, Inc.
Media Conversion Specialists
15 Stony Brook Road
Westford, MA 01886
(978) 692-0050

Copyright © 1997 - 2007 by Disc Interchange
All rights reserved. See our copyright page.