For most sites using Cobol, most files will will be single record-type
files (all records in the file are of a single record type). But files with
multiple record types are also reasonable common
One Bank I worked for had a standard of always adding header Records
(containg Date and file-id) and trailing records (must contain basic
check information (e.g. record counts, dollar totals) to every file.
One thing I must emphasize is it is the Cobol Program and not the
Cobol Copybook that determines which record-type to use. There is no
way for JRecord to be absolutely sure which record-type it should use.
One extreme example comes from from a big Store-Chain, they sent/received data
to / from stores, distribution centers (warehouses), suppliers etc.
They used a central VSAM (index file) - database if you like, to control
the format of files that where sent/received from external computers.
So determine which Record-Type to use, the Cobol program looked up a Database.
Three Common ways to define Multi-Record files:
Again in this example the first field in the record determines the type of record.
01 Header-Record.
05 Record-Type Pic X.
88 Header-Record value 'H'.
05 Creation-Date Pic 9(8).
05 Version pic 9(3)V99.
01 Detail-Record.
05 Rec-Type Pic X.
88 Detail-Record value 'D'.
05 Field-1 Pic s9(10).
05 Field-2 Pic X(20).
05 Field-3 Pic X(10).
01 Trailer-Record.
05 Rec-Type Pic X.
88 Trailer-Record value 'T'.
05 Record-Count Pic 9(9).
With JRecord you use the ICobolSplitOptions.SPLIT_01_LEVEL split option for this file.
ICobolIOBuilder iob = JRecordInterface1.COBOL
.newIOBuilder(copybookName)
.setFileOrganization(Constants.IO_BIN_TEXT)
.setSplitCopybook(ICobolSplitOptions.SPLIT_01_LEVEL)
;
Variations include
Not having on record type on all records. If you dropped the Rec-Type field from the Detail-Record
the program logic becomes
If Record-Type = 'H'
process-header
else if Record-Type = 'T'
process-trailer
else
process-details
multiple Record-Type fields
01 Header-Record.
05 Record-Type Pic X.
88 Header-Record value 'H'.
05 Creation-Date Pic 9(8).
...
01 Detail-Record-1.
05 Rec-Type-1 Pic X.
88 Detail-Record value 'D'.
...
05 Rec-Type-2 Pic 9(2).
88 Detail-Record-1 value 1.
...
01 Detail-Record-2.
05 Rec-Type-1 Pic X.
88 Detail-Record value 'D'.
...
05 Rec-Type-2 Pic 9(2).
88 Detail-Record-2 value 2.
...
~~~~
### Using Redefine
It is *normal* for the **first field** to 1/2 bytes long and determine which record
format to use (see Record-Type Rec-type fields below). This *convention* not a Cobol requirement. You could use multiple fields
scattered through the record.
~~~Cobol
01 Redef-File.
03 Record-Type pic x.
88 Header-Record value 'H'.
88 Detail-Record value 'D'.
88 Detail-Record value 'T'.
03 The-Record pic x(40).
03 Header-Record redefines The-Record.
05 Filler pic x.
05 Run-Number pic 9(5).
05 Filler pic x.
05 Run-Date pic 9(8).
03 Detail-Record redefines The-Record.
05 field1 pic x(3).
05 field2 pic x(12).
05 field3 pic x(10).
03 Trailer-Record redefines The-Record.
05 record-count pic 9(8).
In JRecord you would use ICobolSplitOptions.SPLIT_REDEFINE
ICobolIOBuilder iob = JRecordInterface1.COBOL
.newIOBuilder(copybookName)
.setFileOrganization(Constants.IO_BIN_TEXT)
.setSplitCopybook(ICobolSplitOptions.SPLIT_REDEFINE)
;
Instead of storing multiple Records in one copybook file, they could be
in multiple copybook files
HEADER file:
01 Header-Record.
05 Record-Type Pic X.
88 Header-Record value 'H'.
05 Creation-Date Pic 9(8).
05 Version pic 9(3)V99.
DETAIL file:
01 Detail-Record.
05 Rec-Type Pic X.
88 Detail-Record value 'D'.
05 Field-1 Pic X(10).
05 Field-2 Pic X(20).
05 Field-3 Pic X(10).
TRAILER file:
01 Trailer-Record.
05 Rec-Type Pic X.
88 Trailer-Record value 'T'.
05 Record-Count Pic 9(9).
With JRecord you can handle this with the newMultiCopybookIOBuilder method
ICobolIOBuilder iob = JRecordInterface1.COBOL
.newMultiCopybookIOBuilder()
.addCopyBook('HEADER')
...
.addCopyBook('DETAIL')
...
.addCopyBook('TRAILER')
...
;
This example is like Multiple 01's except there are 03 levels
03 Header-Record.
05 Record-Type Pic X.
88 Header-Record value 'H'.
05 Creation-Date Pic 9(8).
05 Version pic 9(3)V99.
03 Detail-Record.
05 Rec-Type Pic X.
88 Detail-Record value 'D'.
05 Field-1 Pic X(10).
05 Field-2 Pic X(20).
05 Field-3 Pic X(10).
03 Trailer-Record.
05 Rec-Type Pic X.
88 Trailer-Record value 'T'.
05 Record-Count Pic 9(9).
With JRecord you use the ICobolSplitOptions.SPLIT_HIGHEST_REPEATING split option for this file.
ICobolIOBuilder iob = JRecordInterface1.COBOL
.newIOBuilder(copybookName)
.setFileOrganization(Constants.IO_BIN_TEXT)
.setSplitCopybook(ICobolSplitOptions.SPLIT_HIGHEST_REPEATING)
;
Currently there is no support for copybooks where the Records
are not the highest level (See Below). In the example below there is
a 02 All-Records above the Record definition.
02 All-Records.
03 Header-Record.
05 Record-Type Pic X.
88 Header-Record value 'H'.
05 Creation-Date Pic 9(8).
05 Version pic 9(3)V99.
03 Detail-Record.
05 Rec-Type Pic X.
88 Detail-Record value 'D'.
05 Field-1 Pic X(10).
05 Field-2 Pic X(20).
05 Field-3 Pic X(10).
03 Trailer-Record.
05 Rec-Type Pic X.
88 Trailer-Record value 'T'.
05 Record-Count Pic 9(9).
Current versions of cobol suport using copy statment in a copybook.
So you could split the copybook in 2 i.e.
02 All-Records.
copy CHILDCPY.
All you Cobol programs will still work and you can then use the Child copybook
in JRecord:
ICobolIOBuilder iob = JRecordInterface1.COBOL
.newIOBuilder("CHILDCPY")
.setFileOrganization(Constants.IO_BIN_TEXT)
.setSplitCopybook(ICobolSplitOptions.SPLIT_HIGHEST_REPEATING)
;
I will probably add an option for this at some stage.