>>SOURCE FORMAT IS FREE *> cobol-copybook-audit.cob - ACCT-AUDIT, the third of *> three programs sharing one record layout: read last month's *> and this month's masters side by side and prove the posting *> run balanced (same accounts in the same order, no status *> changed, no balance fell, no closed account credited, and *> old total + movement = new total) *> Dialect: GnuCOBOL 3.x, free format *> Status : desk-checked against the GnuCOBOL Programmer's Guide (3.2 *> COPY, 3.3 REPLACE) and the IBM Enterprise COBOL 6.4 Language *> Reference (pp. 700-703); compiled and run with GnuCOBOL 3.2 *> on 2026-10-29 *> Inputs : datasets/cobol-copybook-copy-replacing.dat (last month) *> acct-master-new.dat (this month, written by ACCT-POST) *> code/cobol-copybook-copy-replacing.cpy (the layout, renamed *> here by REPLACE statements rather than a phrase on the COPY) *> Outputs: DISPLAY lines only *> Build : cobc -x -I code -o acct-audit code/cobol-copybook-audit.cob *> Run : ./acct-audit (after ./acct-post, from the same folder) IDENTIFICATION DIVISION. PROGRAM-ID. ACCT-AUDIT. ENVIRONMENT DIVISION. INPUT-OUTPUT SECTION. FILE-CONTROL. SELECT Old-Master ASSIGN TO "datasets/cobol-copybook-copy-replacing.dat" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS WS-Old-FS. SELECT New-Master ASSIGN TO "acct-master-new.dat" ORGANIZATION IS LINE SEQUENTIAL FILE STATUS IS WS-New-FS. DATA DIVISION. FILE SECTION. *> The same renaming ACCT-POST does, written as REPLACE statements. *> Each one stays in force until the next; REPLACE OFF ends the last. REPLACE LEADING ==Acct-== BY ==Old-==. FD Old-Master. COPY "cobol-copybook-copy-replacing.cpy". REPLACE LEADING ==Acct-== BY ==New-==. FD New-Master. COPY "cobol-copybook-copy-replacing.cpy". REPLACE OFF. WORKING-STORAGE SECTION. 77 WS-Old-FS PIC XX. 77 WS-New-FS PIC XX. 01 WS-Flags. 05 WS-Old-EOF PIC X VALUE "N". 88 Old-Done VALUE "Y". 05 WS-New-EOF PIC X VALUE "N". 88 New-Done VALUE "Y". 77 WS-Pairs PIC 9(5) VALUE 0. 77 WS-Raised PIC 9(5) VALUE 0. 77 WS-Unchanged PIC 9(5) VALUE 0. 77 WS-Problems PIC 9(5) VALUE 0. 77 WS-Old-Total PIC 9(9)V99 VALUE 0. 77 WS-New-Total PIC 9(9)V99 VALUE 0. 77 WS-Movement PIC 9(9)V99 VALUE 0. 77 WS-Check-Total PIC 9(9)V99 VALUE 0. 77 WS-Show-Count PIC ZZ,ZZ9. 77 WS-Show-Money PIC Z,ZZZ,ZZ9.99. PROCEDURE DIVISION. Main-Paragraph. OPEN INPUT Old-Master IF WS-Old-FS NOT = "00" DISPLAY "Cannot open the old master, status " WS-Old-FS STOP RUN END-IF OPEN INPUT New-Master IF WS-New-FS NOT = "00" DISPLAY "Cannot open acct-master-new.dat, status " WS-New-FS CLOSE Old-Master STOP RUN END-IF PERFORM Read-Old PERFORM Read-New PERFORM UNTIL Old-Done OR New-Done PERFORM Compare-Pair PERFORM Read-Old PERFORM Read-New END-PERFORM IF NOT (Old-Done AND New-Done) ADD 1 TO WS-Problems DISPLAY "Record counts differ between the two masters" END-IF CLOSE Old-Master New-Master ADD WS-Old-Total WS-Movement GIVING WS-Check-Total MOVE WS-Pairs TO WS-Show-Count DISPLAY "ACCT-AUDIT pairs compared " WS-Show-Count MOVE WS-Raised TO WS-Show-Count DISPLAY "ACCT-AUDIT balances raised " WS-Show-Count MOVE WS-Unchanged TO WS-Show-Count DISPLAY "ACCT-AUDIT balances same " WS-Show-Count MOVE WS-Old-Total TO WS-Show-Money DISPLAY "ACCT-AUDIT old total " WS-Show-Money MOVE WS-Movement TO WS-Show-Money DISPLAY "ACCT-AUDIT movement " WS-Show-Money MOVE WS-New-Total TO WS-Show-Money DISPLAY "ACCT-AUDIT new total " WS-Show-Money IF WS-Problems = 0 AND WS-Check-Total = WS-New-Total DISPLAY "ACCT-AUDIT result balanced" ELSE MOVE WS-Problems TO WS-Show-Count DISPLAY "ACCT-AUDIT result NOT balanced, problems " WS-Show-Count END-IF STOP RUN. Read-Old. READ Old-Master AT END SET Old-Done TO TRUE END-READ IF WS-Old-FS NOT = "00" AND WS-Old-FS NOT = "10" DISPLAY "Old master read failed, status " WS-Old-FS STOP RUN END-IF. Read-New. READ New-Master AT END SET New-Done TO TRUE END-READ IF WS-New-FS NOT = "00" AND WS-New-FS NOT = "10" DISPLAY "New master read failed, status " WS-New-FS STOP RUN END-IF. *> Every Old- and New- name below exists only because of the REPLACE *> statements in the FILE SECTION. Compare-Pair. ADD 1 TO WS-Pairs ADD Old-Balance TO WS-Old-Total ADD New-Balance TO WS-New-Total IF New-Id NOT = Old-Id ADD 1 TO WS-Problems DISPLAY "Out of step: old " Old-Id " new " New-Id END-IF IF New-Status NOT = Old-Status ADD 1 TO WS-Problems DISPLAY "Status changed on account " Old-Id END-IF IF New-Balance > Old-Balance ADD 1 TO WS-Raised COMPUTE WS-Movement = WS-Movement + New-Balance - Old-Balance IF New-Closed ADD 1 TO WS-Problems DISPLAY "Closed account credited: " Old-Id END-IF ELSE IF New-Balance = Old-Balance ADD 1 TO WS-Unchanged ELSE ADD 1 TO WS-Problems DISPLAY "Balance fell on account " Old-Id END-IF END-IF.