Skip to content

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:

  1. Opens all four files in sequence via 0000-ACCTFILE-OPEN, 2000-OUTFILE-OPEN, 3000-ARRFILE-OPEN, and 4000-VBRFILE-OPEN.
  2. Loops PERFORM UNTIL END-OF-FILE = 'Y', calling 1000-ACCTFILE-GET-NEXT to read one account record at a time and displaying it (DISPLAY ACCOUNT-RECORD) until end-of-file.
  3. For each account record successfully read, 1000-ACCTFILE-GET-NEXT drives the full transform/write sequence:
  4. 1100-DISPLAY-ACCT-RECORD — dumps the input account fields to the job log for auditing/debugging.
  5. 1300-POPUL-ACCT-RECORD — maps input fields to the OUT-ACCT-REC layout, calls the external date-formatting routine COBDATFT (via the CODATECN copybook interface) to reformat the reissue date, and applies a hard-coded default (2525.00) to the cycle-debit amount when it is zero.
  6. 1350-WRITE-ACCT-RECORD — writes the record to OUT-FILE.
  7. 1400-POPUL-ARRAY-RECORD — builds an ARR-ARRAY-REC containing a 5-occurrence table of balance/debit pairs, populated with a mix of real account data and hard-coded test values.
  8. 1450-WRITE-ARRY-RECORD — writes the array record to ARRY-FILE.
  9. 1500-POPUL-VBRC-RECORD — builds two variable-length record layouts (VBRC-REC1, VBRC-REC2) from the account data and displays them.
  10. 1550-WRITE-VB1-RECORD and 1575-WRITE-VB2-RECORD — each moves its record into the VBR-REC buffer at a fixed length (12 and 39 bytes respectively) and writes it to VBRC-FILE.
  11. When the read in 1000-ACCTFILE-GET-NEXT returns file status 10 (end of file), END-OF-FILE is set to 'Y' and the loop exits.
  12. 9000-ACCTFILE-CLOSE closes the account file, and the program displays start/end banner messages and terminates via GOBACK.

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: if ACCT-CURR-CYC-DEBIT is zero, it is overwritten with 2525.00.
  • 1400-POPUL-ARRAY-RECORD: ARR-ACCT-CURR-CYC-DEBIT(1) = 1005.00, (2) = 1525.00; ARR-ACCT-CURR-BAL(3) = -1025.00 and ARR-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 from INITIALIZE 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-RESULT to a sentinel (8), attempt the operation, check status, and abend via 9999-ABEND-PROGRAM/CEE3ABD on 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 10 treated as EOF only in 1000-ACCTFILE-GET-NEXT; on writes, status 10 is 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-RECORD and 1575-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 to VBRC-REC1/VBRC-REC2 requires 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 COBDATFT routine and the CODATECN copybook 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