>>SOURCE FORMAT IS FREE *> cobol-bank-statement-batch-job.cob — read a sorted transaction file, *> validate every record, reject the bad ones, and write a statement with *> one section per account and grand totals at the end *> Dialect: GnuCOBOL 3.x, free format *> Status : desk-checked against the GnuCOBOL 3.2 Programmer's Guide; *> compiled and run with GnuCOBOL 3.2 on 2026-10-29 *> Inputs : datasets/cobol-bank-statement-batch-job.dat *> (LINE SEQUENTIAL, LF line endings, 72 bytes per record, *> sorted by account then date) *> Outputs: statement.txt (the report) and rejects.dat (bad records) *> in the current folder; counts on standard output *> Build : cobc -x -I code code/cobol-bank-statement-batch-job.cob *> Run : ./cobol-bank-statement-batch-job (from the site folder) IDENTIFICATION DIVISION. PROGRAM-ID. BANK-STATEMENT. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT Txn-File ASSIGN TO "datasets/cobol-bank-statement-batch-job.dat" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS WS-Txn-Status. SELECT Stmt-File ASSIGN TO "statement.txt" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS WS-Stmt-Status. SELECT Reject-File ASSIGN TO "rejects.dat" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS WS-Reject-Status. DATA DIVISION. FILE SECTION. FD Txn-File. COPY "cobol-bank-statement-batch-job.cpy". FD Stmt-File. 01 Stmt-Line PIC X(100). FD Reject-File. 01 Reject-Line PIC X(105). WORKING-STORAGE SECTION. 01 WS-Statuses. 05 WS-Txn-Status PIC X(2). 05 WS-Stmt-Status PIC X(2). 05 WS-Reject-Status PIC X(2). 01 WS-Eof-Flag PIC X VALUE "N". 88 End-Of-File VALUE "Y". 01 WS-Account-Flag PIC X VALUE "N". 88 Account-Open VALUE "Y". 01 WS-Current-Account PIC 9(8) VALUE 0. 01 WS-Reason PIC X(30). 01 WS-Amounts. 05 WS-Balance PIC S9(11)V99 VALUE 0. 05 WS-Acct-Debits PIC 9(11)V99 VALUE 0. 05 WS-Acct-Credits PIC 9(11)V99 VALUE 0. 05 WS-Grand-Debits PIC 9(11)V99 VALUE 0. 05 WS-Grand-Credits PIC 9(11)V99 VALUE 0. 01 WS-Counts. 05 WS-Read-Count PIC 9(6) VALUE 0. 05 WS-Accept-Count PIC 9(6) VALUE 0. 05 WS-Reject-Count PIC 9(6) VALUE 0. 05 WS-Account-Count PIC 9(6) VALUE 0. 01 WS-Title-Line PIC X(14) VALUE "BANK STATEMENT". 01 WS-Account-Header. 05 FILLER PIC X(8) VALUE "Account ". 05 WS-AH-Account PIC 9(8). 01 WS-Column-Header. 05 FILLER PIC X(2) VALUE SPACES. 05 FILLER PIC X(10) VALUE "Date". 05 FILLER PIC X(2) VALUE SPACES. 05 FILLER PIC X(1) VALUE "T". 05 FILLER PIC X(2) VALUE SPACES. 05 FILLER PIC X(30) VALUE "Description". 05 FILLER PIC X(1) VALUE SPACES. 05 FILLER PIC X(16) VALUE " Amount". 05 FILLER PIC X(1) VALUE SPACES. 05 FILLER PIC X(16) VALUE " Balance". 01 WS-Detail-Line. 05 FILLER PIC X(2) VALUE SPACES. 05 WS-DL-Date PIC 9(4)/9(2)/9(2). 05 FILLER PIC X(2) VALUE SPACES. 05 WS-DL-Type PIC X(1). 05 FILLER PIC X(2) VALUE SPACES. 05 WS-DL-Desc PIC X(30). 05 FILLER PIC X(1) VALUE SPACES. 05 WS-DL-Amount PIC Z,ZZZ,ZZZ,ZZ9.99. 05 FILLER PIC X(1) VALUE SPACES. 05 WS-DL-Balance PIC -,---,---,--9.99. 01 WS-Acct-Summary. 05 FILLER PIC X(11) VALUE " Debits ". 05 WS-AS-Debits PIC Z,ZZZ,ZZZ,ZZ9.99. 05 FILLER PIC X(11) VALUE " Credits ". 05 WS-AS-Credits PIC Z,ZZZ,ZZZ,ZZ9.99. 01 WS-Total-Line. 05 FILLER PIC X(17) VALUE " Closing balance". 05 FILLER PIC X(48) VALUE SPACES. 05 WS-TL-Balance PIC -,---,---,--9.99. 01 WS-Grand-Count-Line. 05 WS-GC-Label PIC X(22). 05 WS-GC-Count PIC ZZZ,ZZ9. 01 WS-Grand-Amount-Line. 05 WS-GA-Label PIC X(22). 05 WS-GA-Amount PIC Z,ZZZ,ZZZ,ZZ9.99. 01 WS-Reject-Data. 05 WS-RJ-Record PIC X(72). 05 FILLER PIC X(3) VALUE " | ". 05 WS-RJ-Reason PIC X(30). PROCEDURE DIVISION. Main-Paragraph. PERFORM Open-Files PERFORM Read-Txn PERFORM UNTIL End-Of-File PERFORM Process-Txn PERFORM Read-Txn END-PERFORM IF Account-Open PERFORM Account-Break END-IF PERFORM Write-Grand-Totals CLOSE Txn-File Stmt-File Reject-File DISPLAY "Read " WS-Read-Count " accepted " WS-Accept-Count " rejected " WS-Reject-Count " accounts " WS-Account-Count STOP RUN. Open-Files. OPEN INPUT Txn-File IF WS-Txn-Status NOT = "00" DISPLAY "Cannot open transactions, status " WS-Txn-Status STOP RUN END-IF OPEN OUTPUT Stmt-File Reject-File WRITE Stmt-Line FROM WS-Title-Line. Read-Txn. READ Txn-File AT END SET End-Of-File TO TRUE END-READ. Process-Txn. ADD 1 TO WS-Read-Count MOVE SPACES TO WS-Reason EVALUATE TRUE WHEN Txn-Account IS NOT NUMERIC MOVE "ACCOUNT NOT NUMERIC" TO WS-Reason WHEN Txn-Date IS NOT NUMERIC MOVE "DATE NOT NUMERIC" TO WS-Reason WHEN Txn-Amount IS NOT NUMERIC MOVE "AMOUNT NOT NUMERIC" TO WS-Reason WHEN NOT Txn-Type-Valid MOVE "UNKNOWN TYPE" TO WS-Reason END-EVALUATE IF WS-Reason NOT = SPACES PERFORM Write-Reject ELSE IF NOT Account-Open OR Txn-Account NOT = WS-Current-Account IF Account-Open PERFORM Account-Break END-IF PERFORM Account-Start END-IF PERFORM Post-Txn END-IF. Account-Start. MOVE Txn-Account TO WS-Current-Account SET Account-Open TO TRUE ADD 1 TO WS-Account-Count MOVE 0 TO WS-Balance WS-Acct-Debits WS-Acct-Credits MOVE SPACES TO Stmt-Line WRITE Stmt-Line MOVE WS-Current-Account TO WS-AH-Account WRITE Stmt-Line FROM WS-Account-Header WRITE Stmt-Line FROM WS-Column-Header. Post-Txn. ADD 1 TO WS-Accept-Count IF Txn-Credit ADD Txn-Amount TO WS-Balance WS-Acct-Credits WS-Grand-Credits ELSE SUBTRACT Txn-Amount FROM WS-Balance ADD Txn-Amount TO WS-Acct-Debits WS-Grand-Debits END-IF MOVE Txn-Date TO WS-DL-Date MOVE Txn-Type TO WS-DL-Type MOVE Txn-Desc TO WS-DL-Desc MOVE Txn-Amount TO WS-DL-Amount MOVE WS-Balance TO WS-DL-Balance WRITE Stmt-Line FROM WS-Detail-Line. Account-Break. MOVE WS-Acct-Debits TO WS-AS-Debits MOVE WS-Acct-Credits TO WS-AS-Credits WRITE Stmt-Line FROM WS-Acct-Summary MOVE WS-Balance TO WS-TL-Balance WRITE Stmt-Line FROM WS-Total-Line MOVE "N" TO WS-Account-Flag. Write-Reject. ADD 1 TO WS-Reject-Count MOVE Txn-Record TO WS-RJ-Record MOVE WS-Reason TO WS-RJ-Reason WRITE Reject-Line FROM WS-Reject-Data. Write-Grand-Totals. MOVE SPACES TO Stmt-Line WRITE Stmt-Line MOVE "Accounts :" TO WS-GC-Label MOVE WS-Account-Count TO WS-GC-Count WRITE Stmt-Line FROM WS-Grand-Count-Line MOVE "Transactions accepted:" TO WS-GC-Label MOVE WS-Accept-Count TO WS-GC-Count WRITE Stmt-Line FROM WS-Grand-Count-Line MOVE "Transactions rejected:" TO WS-GC-Label MOVE WS-Reject-Count TO WS-GC-Count WRITE Stmt-Line FROM WS-Grand-Count-Line MOVE "Total debits :" TO WS-GA-Label MOVE WS-Grand-Debits TO WS-GA-Amount WRITE Stmt-Line FROM WS-Grand-Amount-Line MOVE "Total credits :" TO WS-GA-Label MOVE WS-Grand-Credits TO WS-GA-Amount WRITE Stmt-Line FROM WS-Grand-Amount-Line.