Tables with OCCURS
COBOL-85 allowed up to 7 dimensions; later standards raised the minimum limit.
17.1 One-dimensional tables
Subscripts start at 1. WS-SALES(0) or WS-SALES(13) is out of bounds — undetected unless you compile with SSRANGE (IBM) or -debug / -fec=bound-subscript (GnuCOBOL). OCCURS cannot be used at the 01, 66, 77, or 88 level.
01 WS-MONTHLY-SALES.
05 WS-SALES PIC 9(7)V99 OCCURS 12 TIMES.
* ...
MOVE 1500.00 TO WS-SALES(1)
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 12
ADD WS-SALES(WS-I) TO WS-YEAR-TOTAL
END-PERFORM17.2 Tables of groups and multi-dimensional tables
COBOL-85 allowed up to 7 dimensions; later standards raised the minimum limit. GnuCOBOL and IBM Enterprise COBOL support at least 7 — check your compiler's documented limits before going deeper (and ask whether you really need to).
01 WS-EMPLOYEE-TABLE.
05 WS-EMP OCCURS 100 TIMES.
10 WS-EMP-ID PIC 9(5).
10 WS-EMP-NAME PIC X(20).
10 WS-EMP-HOURS PIC 99V9 OCCURS 7 TIMES.
* ...
MOVE "SMITH" TO WS-EMP-NAME(3)
MOVE 8.5 TO WS-EMP-HOURS(3, 2) *> employee 3, day 217.3 Initializing a table with literals (REDEFINES idiom)
DISPLAY WS-DAY-NAME(WS-DAY-OF-WEEK) now prints the day name (pairs nicely with ACCEPT ... FROM DAY-OF-WEEK). (COBOL 2002 also allows VALUE directly on OCCURS items in some compilers, but the REDEFINES idiom is portable.)
01 WS-DAY-NAMES-DATA.
05 FILLER PIC X(9) VALUE "MONDAY".
05 FILLER PIC X(9) VALUE "TUESDAY".
05 FILLER PIC X(9) VALUE "WEDNESDAY".
05 FILLER PIC X(9) VALUE "THURSDAY".
05 FILLER PIC X(9) VALUE "FRIDAY".
05 FILLER PIC X(9) VALUE "SATURDAY".
05 FILLER PIC X(9) VALUE "SUNDAY".
01 WS-DAY-TABLE REDEFINES WS-DAY-NAMES-DATA.
05 WS-DAY-NAME PIC X(9) OCCURS 7 TIMES.17.4 Subscripts vs indexes
Any integer item (PIC S9(4) COMP recommended) INDEXED BY name on the OCCURS clause Occurrence number (1, 2, 3…)
Byte displacement (implementation detail) MOVE, ADD, COMPUTE
SET idx TO n, SET idx UP BY 1, PERFORM VARYING idx Must be converted to a displacement each use Faster (already a displacement) SEARCH, SEARCH ALL
Relative indexing (WS-RATE-CODE(RATE-IDX + 1)) is allowed.
01 WS-RATE-TABLE.
05 WS-RATE-ENTRY OCCURS 50 TIMES INDEXED BY RATE-IDX.
10 WS-RATE-CODE PIC X(3).
10 WS-RATE-PCT PIC 9V999.
01 WS-SAVED-IDX USAGE INDEX.
* ...
SET RATE-IDX TO 1
SET RATE-IDX UP BY 1
SET WS-SAVED-IDX TO RATE-IDX
PERFORM VARYING RATE-IDX FROM 1 BY 1 UNTIL RATE-IDX > 50
MOVE SPACES TO WS-RATE-CODE(RATE-IDX)
END-PERFORM17.5 Variable-length tables: OCCURS DEPENDING ON
Storage is allocated for the maximum (200) in WORKING-STORAGE, but the group's length and SEARCH limits follow WS-ITEM-COUNT.
Set the DEPENDING ON object before moving or writing the group. In file records, ODO gives true variable-length records.
COBOL 2014 also defines dynamic-capacity tables (OCCURS DYNAMIC) that grow at run time; support varies (check GnuCOBOL/IBM documentation).
01 WS-ORDER.
05 WS-ITEM-COUNT PIC S9(4) COMP.
05 WS-ITEM OCCURS 1 TO 200 TIMES
DEPENDING ON WS-ITEM-COUNT
INDEXED BY ITEM-IDX.
10 WS-ITEM-SKU PIC X(10).
10 WS-ITEM-QTY PIC 9(5).