Level numbers in COBOL define the hierarchy of data: what is a record, what is a group, and what is a single field. They appear in the DATA DIVISION (FILE SECTION, WORKING-STORAGE SECTION, LINKAGE SECTION) at the start of each data description entry. This page explains level numbers 01 through 49, and the special levels 66, 77, 88, and 78, and how they shape your data structure.
Imagine an outline: the main title is 01. Under it you have sections (05). Under each section you have subsections (10). Under those you have the actual lines you fill in (e.g. 15 with a PICTURE). In COBOL, 01 is the "main box," and smaller numbers are "bigger boxes." So 01 is the whole record, 05 might be "name" or "address," and 10 might be "first name" and "last name." The smallest boxes that hold one value have a PICTURE. Level 77 is a single box that is not inside any other box. Level 88 is a label for a value (like "yes" or "no") so you can use the label in your logic instead of the raw value.
Levels 01 through 49 form a tree. Level 01 is the root: it starts a record or a top-level group. Each following entry with a higher level number belongs to the nearest preceding entry that has a lower level number. So 05 belongs to 01; 10 belongs to 05; 15 belongs to 10. Items with the same level number that follow each other are siblings (e.g. several 05s under one 01). When you hit another 01 (or 77), the previous 01 group ends.
| Level | Purpose | Notes |
|---|---|---|
| 01 | Start of a record or top-level group | All following items with higher numbers belong to this until the next 01 or 77. |
| 02–49 | Subordinate items in the hierarchy | Lower number = higher in the tree. Same number = siblings under the same parent. |
| 66 | RENAMES – alternate grouping of existing items | Does not add storage; renames a range of items. |
| 77 | Standalone elementary item (no group) | No parent, no children. Obsolete in some standards. |
| 88 | Condition name for values of the previous item | No PICTURE; used in IF or SET ... TO TRUE. |
| 78 | Constant name (compile-time constant) | Some compilers; defines a named constant. |
Only the order matters for hierarchy: 10 must be less than 15 so that 15 is subordinate to 10. Many shops use 01, 05, 10, 15, 20, etc. so that levels can be inserted later (e.g. 03 between 01 and 05) without renumbering. You can use 02, 03, 04 under 01 if you prefer; the rule is simply that a higher number is deeper in the tree.
12345678901 CUSTOMER-RECORD. *> Top level (record or group) 05 CUSTOMER-NAME. *> Group under 01 10 FIRST-NAME PIC X(15). *> Elementary under 05 10 LAST-NAME PIC X(20). *> Elementary under 05 05 CUSTOMER-ID PIC 9(6). *> Elementary under 01 05 BALANCE PIC S9(9)V99. *> Elementary under 01 *> FIRST-NAME and LAST-NAME are under CUSTOMER-NAME (05) *> CUSTOMER-ID and BALANCE are siblings of CUSTOMER-NAME under 01
A group item has a level number 01–49 and contains subordinate items; it has no PICTURE. Its length is the sum of its subordinates. You can MOVE the whole group or refer to any subordinate. An elementary item is a leaf: it has a PICTURE (and possibly USAGE, VALUE) and cannot be subdivided. In the example above, CUSTOMER-RECORD and CUSTOMER-NAME are group items; FIRST-NAME, LAST-NAME, CUSTOMER-ID, and BALANCE are elementary.
Level 77 defines an independent elementary item that is not part of any 01 group. It has no parent and no children. It must have a PICTURE (or equivalent). In older COBOL, 77 was common for working-storage variables that were not part of a record. In ANSI 85 and later, 77 was classified obsolete; you can still use it on many compilers, but defining a single 01 with one elementary item (e.g. 01 WS-COUNTER PIC 9(5).) is often used instead.
1234577 WS-FLAG PIC X VALUE 'N'. *> Standalone; not in a group 77 WS-TOTAL PIC 9(7)V99. *> Standalone numeric 01 WS-RECORD. *> Alternative: one 01 with one field 05 WS-COUNTER PIC 9(5) VALUE 0. *> Same idea as 77, different level
Level 88 does not define new storage. It attaches a condition name to one or more values of the immediately preceding data item. The 88 entry has no PICTURE; it has VALUE (or VALUES) and optionally THRU for a range. In the PROCEDURE DIVISION you use the condition name in IF (e.g. IF VALID-STATUS) or SET ... TO TRUE (which moves the first value of that condition to the parent field).
1234567891001 WS-STATUS PIC X. 88 VALID-STATUS VALUE 'Y'. 88 INVALID-STATUS VALUE 'N'. 88 PENDING-STATUS VALUE 'P'. *> In PROCEDURE DIVISION: IF VALID-STATUS DISPLAY 'Record is valid' END-IF SET INVALID-STATUS TO TRUE *> Moves 'N' to WS-STATUS
For numeric fields, 88 can use numeric values or ranges: VALUE 1 THRU 5, VALUE 0, VALUE -1. Condition names make the code easier to read and change (e.g. if the value for "valid" changes from "Y" to "V", you change only the 88 entry).
Level 66 is used with RENAMES to define an alternate grouping of existing elementary items. The 66 entry does not add new storage; it gives a new name to a contiguous range of items (item-1 THRU item-2) that already exist in the same record. Useful when you want to refer to a slice of the record as one group (e.g. for a MOVE or comparison) without changing the original layout.
Write a 01 record with a group (05) containing two elementary fields (10), and two more 05 elementary fields. Identify which items are groups and which are elementary.
Add an 88 condition name for a PIC X status field with values "A", "B", and "C". Write an IF using the condition name and a SET ... TO TRUE.
In a record with FIRST-NAME and LAST-NAME (both PIC X), add a 66 that RENAMEs both as FULL-NAME. (Check your compiler's rules for RENAMES.)
1. Which level number starts a new record or top-level group?
2. What does level 88 define?
3. An item with level 10 is subordinate to:
4. Level 77 is used for: