CBACT01C
Source: cbl/CBACT01C.cbl
Type: Batch program
CBACT01C — Account File Extract/Transform Program
Purpose
CBACT01C is a batch COBOL program from the CardDemo application that reads account master records from an indexed (VSAM KSDS) file and republishes them into three different output file formats: a fixed-length sequential file, a sequential file containing an array/table structure, and a variable-length (RECFM V) file. It appears to exist primarily to demonstrate/test different COBOL file organizations and record layouts (fixed, array/OCCURS, and variable-length records) derived from the same input data, rather than to perform a distinct business calculation. It is executed as job step READACCT.STEP05.
How it works
The main PROCEDURE DIVISION logic:
- Opens all four files in sequence via
0000-ACCTFILE-OPEN,2000-OUTFILE-OPEN,3000-ARRFILE-OPEN, and4000-VBRFILE-OPEN. - Loops
PERFORM UNTIL END-OF-FILE = 'Y', calling1000-ACCTFILE-GET-NEXTto read one account record at a time and displaying it (DISPLAY ACCOUNT-RECORD) until end-of-file. - For each account record successfully read,
1000-ACCTFILE-GET-NEXTdrives the full transform/write sequence: 1100-DISPLAY-ACCT-RECORD— dumps the input account fields to the job log for auditing/debugging.1300-POPUL-ACCT-RECORD— maps input fields to theOUT-ACCT-REClayout, calls the external date-formatting routineCOBDATFT(via theCODATECNcopybook interface) to reformat the reissue date, and applies a hard-coded default (2525.00) to the cycle-debit amount when it is zero.1350-WRITE-ACCT-RECORD— writes the record toOUT-FILE.1400-POPUL-ARRAY-RECORD— builds anARR-ARRAY-RECcontaining a 5-occurrence table of balance/debit pairs, populated with a mix of real account data and hard-coded test values.1450-WRITE-ARRY-RECORD— writes the array record toARRY-FILE.1500-POPUL-VBRC-RECORD— builds two variable-length record layouts (VBRC-REC1,VBRC-REC2) from the account data and displays them.1550-WRITE-VB1-RECORDand1575-WRITE-VB2-RECORD— each moves its record into theVBR-RECbuffer at a fixed length (12 and 39 bytes respectively) and writes it toVBRC-FILE.- When the read in
1000-ACCTFILE-GET-NEXTreturns file status10(end of file),END-OF-FILEis set to'Y'and the loop exits. 9000-ACCTFILE-CLOSEcloses the account file, and the program displays start/end banner messages and terminates viaGOBACK.
Every I/O paragraph (open, write, close, read) checks the file status and, on any unexpected status, calls 9910-DISPLAY-IO-STATUS to format/log the status code and then 9999-ABEND-PROGRAM to abnormally terminate the job via CALL 'CEE3ABD'.
Inputs & outputs
| File / DD | Direction | Organization | Purpose |
|---|---|---|---|
ACCTFILE-FILE (DD ACCTFILE) |
Input | Indexed (VSAM KSDS), sequential access, keyed on FD-ACCT-ID |
Source account master records (layout defined in copybook CVACT01Y, referenced as ACCOUNT-RECORD) |
OUT-FILE (DD OUTFILE) |
Output | Sequential, fixed-length | Flattened copy of account data (OUT-ACCT-REC) including a reformatted reissue date |
ARRY-FILE (DD ARRYFILE) |
Output | Sequential, fixed-length | Account ID plus a 5-entry OCCURS table of balance/debit values (ARR-ARRAY-REC), partly real data and partly hard-coded test values |
VBRC-FILE (DD VBRCFILE) |
Output | Sequential, variable-length (RECFM V, 10–80 bytes, length driven by WS-RECD-LEN) |
Two record types per account: a short "VB1" record (12 bytes: ID + status) and a longer "VB2" record (39 bytes: ID, balance, credit limit, reissue year) |
Copybooks used:
- CVACT01Y — defines the account record layout (ACCOUNT-RECORD / ACCT-* fields) used for both the input file and working storage.
- CODATECN — defines the interface record (CODATECN-REC) passed to the external date-conversion call.
External calls:
- COBDATFT — an external (likely Assembler) date-formatting routine invoked to convert the account reissue date into an output format.
- CEE3ABD — LE abend service, invoked to terminate the program abnormally on unrecoverable I/O errors.
No CICS commands or SQL tables are used — this is a straight batch, file-to-file program (no DB2 access per parser facts).
Things to know
- Hard-coded / test-like values: Several fields are populated with fixed literals rather than derived from input, which look like placeholder or test data rather than genuine business logic:
1300-POPUL-ACCT-RECORD: ifACCT-CURR-CYC-DEBITis zero, it is overwritten with2525.00.1400-POPUL-ARRAY-RECORD:ARR-ACCT-CURR-CYC-DEBIT(1)=1005.00,(2)=1525.00;ARR-ACCT-CURR-BAL(3)=-1025.00andARR-ACCT-CURR-CYC-DEBIT(3)=-2500.00— none of these come from the account record. Table entries 4 and 5 are never populated (left as initialized/zero fromINITIALIZE ARR-ARRAY-REC).- These hard-coded values suggest this program may be a sample/demo or a test harness rather than production logic — worth confirming with the business owner before relying on it.
- Error handling pattern: Every file operation follows the same idiom — set
APPL-RESULTto a sentinel (8), attempt the operation, check status, and abend via9999-ABEND-PROGRAM/CEE3ABDon unexpected status codes (anything other than'00', or'10'for reads at EOF). This is consistent but terminates the entire job on any I/O anomaly (abend code 999), with no partial-recovery or restart logic evident. - File status
10treated as EOF only in1000-ACCTFILE-GET-NEXT; on writes, status10is tolerated without explanation (treated as non-error alongside'00'), which is unusual — this should be verified, as'10'normally denotes end-of-file, not a valid write status. - Variable-length record construction: In
1550-WRITE-VB1-RECORDand1575-WRITE-VB2-RECORD, the record length is manually set (12 and 39 bytes) and the data is copied into a fixed 80-byte buffer (VBR-REC) via reference modification (VBR-REC(1:WS-RECD-LEN)). Any layout change toVBRC-REC1/VBRC-REC2requires the corresponding length literal to be updated manually — a fragile, easy-to-break coupling. - Date conversion dependency: The reissue date transformation relies entirely on the external
COBDATFTroutine and theCODATECNcopybook contract; the actual conversion logic is opaque to this program and not verifiable from this source alone. - Verbose diagnostics: The program displays every account record’s full contents (
1100-DISPLAY-ACCT-RECORD) and both VBRC records for every input row — this could produce very large job logs for large input files and should be considered if run against production volumes. - No dynamic record counts: The array table is fixed at 5 occurrences (
OCCURS 5 TIMES) with only 3 populated — the purpose of the unused slots is unclear from the code and should be confirmed with whoever authored the design.
Files
| Logical file | DD name |
|---|---|
| ACCTFILE-FILE | ACCTFILE |
| OUT-FILE | OUTFILE |
| ARRY-FILE | ARRYFILE |
| VBRC-FILE | VBRCFILE |
Copybooks
CODATECN, CVACT01Y
Calls
CEE3ABD, COBDATFT
Executed by
READACCT.STEP05
Paragraph flow
flowchart TD
1000_ACCTFILE_GET_NEXT["1000-ACCTFILE-GET-NEXT"]
1100_DISPLAY_ACCT_RECORD["1100-DISPLAY-ACCT-RECORD"]
1300_POPUL_ACCT_RECORD["1300-POPUL-ACCT-RECORD"]
1350_WRITE_ACCT_RECORD["1350-WRITE-ACCT-RECORD"]
1400_POPUL_ARRAY_RECORD["1400-POPUL-ARRAY-RECORD"]
1450_WRITE_ARRY_RECORD["1450-WRITE-ARRY-RECORD"]
1500_POPUL_VBRC_RECORD["1500-POPUL-VBRC-RECORD"]
1550_WRITE_VB1_RECORD["1550-WRITE-VB1-RECORD"]
1575_WRITE_VB2_RECORD["1575-WRITE-VB2-RECORD"]
0000_ACCTFILE_OPEN["0000-ACCTFILE-OPEN"]
2000_OUTFILE_OPEN["2000-OUTFILE-OPEN"]
3000_ARRFILE_OPEN["3000-ARRFILE-OPEN"]
4000_VBRFILE_OPEN["4000-VBRFILE-OPEN"]
9000_ACCTFILE_CLOSE["9000-ACCTFILE-CLOSE"]
9999_ABEND_PROGRAM["9999-ABEND-PROGRAM"]
9910_DISPLAY_IO_STATUS["9910-DISPLAY-IO-STATUS"]
0000_ACCTFILE_OPEN --> 9910_DISPLAY_IO_STATUS
0000_ACCTFILE_OPEN --> 9999_ABEND_PROGRAM
1000_ACCTFILE_GET_NEXT --> 1100_DISPLAY_ACCT_RECORD
1000_ACCTFILE_GET_NEXT --> 1300_POPUL_ACCT_RECORD
1000_ACCTFILE_GET_NEXT --> 1350_WRITE_ACCT_RECORD
1000_ACCTFILE_GET_NEXT --> 1400_POPUL_ARRAY_RECORD
1000_ACCTFILE_GET_NEXT --> 1450_WRITE_ARRY_RECORD
1000_ACCTFILE_GET_NEXT --> 1500_POPUL_VBRC_RECORD
1000_ACCTFILE_GET_NEXT --> 1550_WRITE_VB1_RECORD
1000_ACCTFILE_GET_NEXT --> 1575_WRITE_VB2_RECORD
1000_ACCTFILE_GET_NEXT --> 9910_DISPLAY_IO_STATUS
1000_ACCTFILE_GET_NEXT --> 9999_ABEND_PROGRAM
1350_WRITE_ACCT_RECORD --> 9910_DISPLAY_IO_STATUS
1350_WRITE_ACCT_RECORD --> 9999_ABEND_PROGRAM
1450_WRITE_ARRY_RECORD --> 9910_DISPLAY_IO_STATUS
1450_WRITE_ARRY_RECORD --> 9999_ABEND_PROGRAM
1550_WRITE_VB1_RECORD --> 9910_DISPLAY_IO_STATUS
1550_WRITE_VB1_RECORD --> 9999_ABEND_PROGRAM
1575_WRITE_VB2_RECORD --> 9910_DISPLAY_IO_STATUS
1575_WRITE_VB2_RECORD --> 9999_ABEND_PROGRAM
2000_OUTFILE_OPEN --> 9910_DISPLAY_IO_STATUS
2000_OUTFILE_OPEN --> 9999_ABEND_PROGRAM
3000_ARRFILE_OPEN --> 9910_DISPLAY_IO_STATUS
3000_ARRFILE_OPEN --> 9999_ABEND_PROGRAM
4000_VBRFILE_OPEN --> 9910_DISPLAY_IO_STATUS
4000_VBRFILE_OPEN --> 9999_ABEND_PROGRAM
9000_ACCTFILE_CLOSE --> 9910_DISPLAY_IO_STATUS
9000_ACCTFILE_CLOSE --> 9999_ABEND_PROGRAM
Paragraphs
| Paragraph | Line | Performs |
|---|---|---|
| 1000-ACCTFILE-GET-NEXT | 165 | 1100-DISPLAY-ACCT-RECORD, 1300-POPUL-ACCT-RECORD, 1350-WRITE-ACCT-RECORD, 1400-POPUL-ARRAY-RECORD, 1450-WRITE-ARRY-RECORD, 1500-POPUL-VBRC-RECORD |
| 1100-DISPLAY-ACCT-RECORD | 200 | |
| 1300-POPUL-ACCT-RECORD | 215 | |
| 1350-WRITE-ACCT-RECORD | 242 | 9910-DISPLAY-IO-STATUS, 9999-ABEND-PROGRAM |
| 1400-POPUL-ARRAY-RECORD | 253 | |
| 1450-WRITE-ARRY-RECORD | 263 | 9910-DISPLAY-IO-STATUS, 9999-ABEND-PROGRAM |
| 1500-POPUL-VBRC-RECORD | 276 | |
| 1550-WRITE-VB1-RECORD | 287 | 9910-DISPLAY-IO-STATUS, 9999-ABEND-PROGRAM |
| 1575-WRITE-VB2-RECORD | 302 | 9910-DISPLAY-IO-STATUS, 9999-ABEND-PROGRAM |
| 0000-ACCTFILE-OPEN | 317 | 9910-DISPLAY-IO-STATUS, 9999-ABEND-PROGRAM |
| 2000-OUTFILE-OPEN | 334 | 9910-DISPLAY-IO-STATUS, 9999-ABEND-PROGRAM |
| 3000-ARRFILE-OPEN | 352 | 9910-DISPLAY-IO-STATUS, 9999-ABEND-PROGRAM |
| 4000-VBRFILE-OPEN | 370 | 9910-DISPLAY-IO-STATUS, 9999-ABEND-PROGRAM |
| 9000-ACCTFILE-CLOSE | 388 | 9910-DISPLAY-IO-STATUS, 9999-ABEND-PROGRAM |
| 9999-ABEND-PROGRAM | 406 | |
| 9910-DISPLAY-IO-STATUS | 413 |