I have a 2-D array in cobol and I want to write each row to the output file. I write the following code to do this.
FILE-SECTION.
01 FILE-TABLE.
05 FILE-TABLE-ROW OCCURS 10 TIMES INDEXED BY I.
10 FILE-TABLE-COL PIC X(1) OCCURS 10 TIMES INDEXED BY J.
SET I TO 1.
PAR-A.
IF I <= 10 THEN
WRITE FILE-TABLE-ROW(I)
SET I UP BY 1
GO TO PAR-A
END-IF.
Surprisingly, the compiler report the error "FILE-TABLE-ROW needs one subscript" at the WRITE FILE-TABLE-ROW(I) LINE. I don't understand why this is an error.
First off all I see you've now gone for the contracted table with OCCURS after your last question. I think this is the wrong thing to do. This is better.
01 FILE-TABLE.
05 FILE-TABLE-ROW
OCCURS 10 TIMES
INDEXED BY I.
10 FILE-TABLE-COL
OCCURS 10 TIMES
INDEXED BY J.
15 FILE-TABLE-COL PIC X(1).
Just a point I've not mentioned before, since you may be naming to aid you as a beginner, you don't need to name fields if you are not going to use them.
01 FILE-TABLE.
05 FILE-TABLE-ROW
OCCURS 10 TIMES
INDEXED BY I.
10 FILLER
OCCURS 10 TIMES
INDEXED BY J.
15 FILE-TABLE-COL PIC X(1).
Note that since the 1985 Standard, the word FILLER can be written in invisible ink:
05 FILLER PIC X(20).
05 PIC X(20).
The blank in the name is an implicit FILLER. Note also that 05
can be written as 5
, as can every level-number which starts with zero.
READ FILE, WRITE RECORD as the old saying goes. A "Record" in this context is an 01-level beneath an DF. You are attempting to write something which is a subordinate part of a record, which won't work. Seems to have confused the compiler.
I see no FD but presume it is there. Put your table into WORKING-STORAGE (or LOCAL-STORAGE). Define a 10-byte record under your FD, MOVE FILE-TABLE-ROW to that newly-defined record, or use WRITE FROM FILE-TABLE-ROW.
You can't write part of a record (an 01-level) in the FILE SECTION. You can use MOVE, or WRITE ... FROM..., to access data at a non-01-level, and get that data into your 01-level to allow a WRITE.
WORKING-STORAGE SECTION,
01 some-thing PIC X.
Then
MOVE some-thing TO output-record
WRITE output-record
Or
WRITE output-record FROM some-thing
There are two different ways to write WRITE
that interest you here:
WRITE record-name
WRITE record-name FROM somewhere-else
For the first, you fully-define your output under your FD, put values in the fields you need, and then WRITE the record.
For the second, you only need a minimal definition under the FD (enough to define a length for the record, which can be variable, you'll probably come to that later) and you put values in all the fields you need, subordinate to another group item if necessary. The definition under the FD can be complete, it is just that it doesn't have to be.
That data can be from anywhere in the DATA DIVISION. It could even be from somewhere else in the FILE SECTION (WRITE output-record FROM input-record is something you will see).
The FROM
on WRITE, like the INTO
on READ, is an implicit MOVE
. MOVE formatted-data TO output-record and WRITE output-record, is what the WRITE ... FROM ...
says.