Case Study 1: Monthly Account Statement Report

Background

Columbia Trust Bank produces monthly account statements for each of its 185,000 active retail customers. Each statement includes a page header with the bank's branding and the customer's account information, a chronological listing of every transaction during the statement period, subtotals for debits and credits, and a closing balance summary. Statements for customers with multiple account types (checking, savings, money market) include separate sections for each account with grand totals across all accounts.

Historically, the statement generation program was a 4,500-line COBOL program with intricate procedural logic for page overflow detection, control break handling, subtotal accumulation, and header/footer formatting. Every time the marketing department wanted to change the statement layout -- adding a promotional message, adjusting column widths, or modifying the subtotal format -- the programmers had to modify dozens of interconnected paragraphs and retest the entire page flow logic.

The bank has decided to rewrite the statement generation program using COBOL's Report Writer module. Report Writer's declarative approach separates the "what" (the report layout) from the "how" (the page and control break mechanics), allowing layout changes to be made in the REPORT SECTION without touching the PROCEDURE DIVISION.


Data Design

The Input File

The input is a sorted file containing one record per transaction, ordered by customer number, then account number, then transaction date:

       SELECT STATEMENT-INPUT-FILE
           ASSIGN TO STMTINP
           ORGANIZATION IS SEQUENTIAL
           FILE STATUS IS WS-INPUT-STATUS.

       FD  STATEMENT-INPUT-FILE
           RECORDING MODE IS F
           RECORD CONTAINS 150 CHARACTERS.

       01  STATEMENT-INPUT-RECORD.
           05  SIR-CUSTOMER-NUMBER     PIC X(8).
           05  SIR-CUSTOMER-NAME       PIC X(30).
           05  SIR-CUSTOMER-ADDRESS.
               10  SIR-STREET          PIC X(30).
               10  SIR-CITY            PIC X(20).
               10  SIR-STATE           PIC X(2).
               10  SIR-ZIP             PIC X(10).
           05  SIR-ACCOUNT-NUMBER      PIC X(10).
           05  SIR-ACCOUNT-TYPE        PIC X(2).
               88  SIR-CHECKING        VALUE "CK".
               88  SIR-SAVINGS         VALUE "SV".
               88  SIR-MONEY-MARKET    VALUE "MM".
           05  SIR-TXN-DATE            PIC 9(8).
           05  SIR-TXN-DESCRIPTION     PIC X(25).
           05  SIR-TXN-AMOUNT          PIC S9(9)V99.
           05  SIR-RUNNING-BALANCE     PIC S9(9)V99.
           05  SIR-FILLER              PIC X(2).

The Report Output File

       SELECT STATEMENT-REPORT-FILE
           ASSIGN TO STMTRPT
           ORGANIZATION IS SEQUENTIAL
           FILE STATUS IS WS-REPORT-STATUS.

       FD  STATEMENT-REPORT-FILE
           REPORT IS MONTHLY-STATEMENT.

Note that the FD for a Report Writer file contains no record description. Instead, it references the report name defined in the REPORT SECTION. The runtime generates the output records based on the report group definitions.


The Report Section: Declaring the Statement Layout

The REPORT SECTION is where Report Writer programs define the entire visual structure of the report. Each report group specifies its type, position, and content:

       REPORT SECTION.
       RD  MONTHLY-STATEMENT
           CONTROLS ARE FINAL
                       SIR-CUSTOMER-NUMBER
                       SIR-ACCOUNT-NUMBER
           PAGE LIMIT IS 66 LINES
           HEADING 1
           FIRST DETAIL 12
           LAST DETAIL 58
           FOOTING 62.

The RD entry establishes several critical parameters:

  • CONTROLS ARE: Lists the control fields in major-to-minor order. FINAL is the highest level (triggered once at the very end of the report). SIR-CUSTOMER-NUMBER is the next level (triggered when the customer changes). SIR-ACCOUNT-NUMBER is the minor level (triggered when the account changes within a customer).

  • PAGE LIMIT IS 66: The physical page is 66 lines (standard for mainframe printing on 11-inch paper at 6 lines per inch).

  • HEADING 1: Page headings start on line 1.

  • FIRST DETAIL 12: Detail lines begin no earlier than line 12 (leaving room for headers).

  • LAST DETAIL 58: Detail lines print no later than line 58 (leaving room for footers).

  • FOOTING 62: Page footings print no later than line 62.

Report Heading (First Page Only)

       01  TYPE IS REPORT HEADING.
           02  LINE 1.
               05  COLUMN 1   PIC X(60) VALUE
                   "========================================="
                 & "===================".
           02  LINE 2.
               05  COLUMN 5   PIC X(30) VALUE
                   "COLUMBIA TRUST BANK".
           02  LINE 3.
               05  COLUMN 5   PIC X(30) VALUE
                   "MONTHLY ACCOUNT STATEMENT".
           02  LINE 4.
               05  COLUMN 1   PIC X(60) VALUE
                   "========================================="
                 & "===================".

Page Heading (Top of Every Page)

       01  TYPE IS PAGE HEADING.
           02  LINE 6.
               05  COLUMN 1   PIC X(20) VALUE
                   "Statement Date:".
               05  COLUMN 22  PIC X(10)
                   SOURCE WS-STATEMENT-DATE-FORMATTED.
               05  COLUMN 50  PIC X(5)  VALUE "Page ".
               05  COLUMN 55  PIC ZZ9
                   SOURCE PAGE-COUNTER.
           02  LINE 8.
               05  COLUMN 1   PIC X(10) VALUE "DATE".
               05  COLUMN 14  PIC X(25) VALUE "DESCRIPTION".
               05  COLUMN 42  PIC X(11) VALUE "DEBITS".
               05  COLUMN 55  PIC X(11) VALUE "CREDITS".
               05  COLUMN 68  PIC X(12) VALUE "BALANCE".
           02  LINE 9.
               05  COLUMN 1   PIC X(79) VALUE ALL "-".

Customer Control Heading

When a new customer begins, the statement prints the customer's name and mailing address:

       01  TYPE IS CONTROL HEADING SIR-CUSTOMER-NUMBER.
           02  LINE PLUS 1.
               05  COLUMN 1   PIC X(30)
                   SOURCE SIR-CUSTOMER-NAME.
           02  LINE PLUS 1.
               05  COLUMN 1   PIC X(8)  VALUE "Acct #: ".
               05  COLUMN 10  PIC X(8)
                   SOURCE SIR-CUSTOMER-NUMBER.
           02  LINE PLUS 1.
               05  COLUMN 1   PIC X(30)
                   SOURCE SIR-STREET.
           02  LINE PLUS 1.
               05  COLUMN 1   PIC X(20)
                   SOURCE SIR-CITY.
               05  COLUMN 22  PIC X(2)
                   SOURCE SIR-STATE.
               05  COLUMN 26  PIC X(10)
                   SOURCE SIR-ZIP.

Account Control Heading

When a new account begins within a customer, the account type and number are printed:

       01  TYPE IS CONTROL HEADING SIR-ACCOUNT-NUMBER.
           02  LINE PLUS 2.
               05  COLUMN 1   PIC X(12) VALUE
                   "Account:    ".
               05  COLUMN 14  PIC X(10)
                   SOURCE SIR-ACCOUNT-NUMBER.
               05  COLUMN 28  PIC X(6) VALUE "Type: ".
               05  COLUMN 35  PIC X(2)
                   SOURCE SIR-ACCOUNT-TYPE.
           02  LINE PLUS 1.
               05  COLUMN 1   PIC X(60) VALUE ALL "-".

Detail Line (One Per Transaction)

       01  STATEMENT-DETAIL TYPE IS DETAIL.
           02  LINE PLUS 1.
               05  COLUMN 1   PIC X(10)
                   SOURCE WS-TXN-DATE-FORMATTED.
               05  COLUMN 14  PIC X(25)
                   SOURCE SIR-TXN-DESCRIPTION.
               05  COLUMN 40  PIC $(7),$$9.99-
                   SOURCE WS-DEBIT-AMOUNT.
               05  COLUMN 54  PIC $(7),$$9.99-
                   SOURCE WS-CREDIT-AMOUNT.
               05  COLUMN 67  PIC $(7),$$9.99-
                   SOURCE SIR-RUNNING-BALANCE.
```

### Account Control Footing (Subtotals Per Account)

```cobol
       01  TYPE IS CONTROL FOOTING SIR-ACCOUNT-NUMBER.
           02  LINE PLUS 1.
               05  COLUMN 1   PIC X(60) VALUE ALL "-".
           02  LINE PLUS 1.
               05  COLUMN 14  PIC X(16) VALUE
                   "Account Totals:".
               05  COLUMN 40  PIC $(7),$$9.99-
                   SUM WS-DEBIT-AMOUNT.
               05  COLUMN 54  PIC $(7),$$9.99-
                   SUM WS-CREDIT-AMOUNT.
               05  COLUMN 67  PIC $(7),$$9.99-
                   SOURCE SIR-RUNNING-BALANCE.

The SUM clause is one of Report Writer's most powerful features. It automatically accumulates the values of the specified data items across all detail lines within the control group. When the account number changes, the accumulated sums are printed automatically, then reset to zero for the next group.

Customer Control Footing (Grand Total Per Customer)

       01  TYPE IS CONTROL FOOTING SIR-CUSTOMER-NUMBER.
           02  LINE PLUS 2.
               05  COLUMN 1   PIC X(60) VALUE ALL "=".
           02  LINE PLUS 1.
               05  COLUMN 5   PIC X(25) VALUE
                   "CUSTOMER GRAND TOTAL:".
               05  COLUMN 40  PIC $(7),$$9.99-
                   SUM WS-DEBIT-AMOUNT.
               05  COLUMN 54  PIC $(7),$$9.99-
                   SUM WS-CREDIT-AMOUNT.
           02  LINE PLUS 2.
               05  COLUMN 5   PIC X(40) VALUE
                   "Thank you for banking with Columbia Trust".

At the customer control footing level, the SUM clause accumulates the account-level sums from the control footings below it. This automatic "rollup" of subtotals is a key advantage of Report Writer -- in manual code, you would need to explicitly add account subtotals into customer grand totals.

Report Footing (Last Page Only)

       01  TYPE IS REPORT FOOTING.
           02  LINE PLUS 3.
               05  COLUMN 1   PIC X(60) VALUE ALL "=".
           02  LINE PLUS 1.
               05  COLUMN 5   PIC X(30) VALUE
                   "*** END OF STATEMENTS ***".
           02  LINE PLUS 1.
               05  COLUMN 5   PIC X(40) VALUE
                   "Total Customers Processed:".
               05  COLUMN 46  PIC ZZ,ZZ9
                   SOURCE WS-CUSTOMER-COUNT.
           02  LINE PLUS 1.
               05  COLUMN 1   PIC X(60) VALUE ALL "=".

The Procedure Division: Minimal Code

With Report Writer, the PROCEDURE DIVISION is remarkably simple. The runtime handles all page breaks, control breaks, subtotal accumulation, and header/footer generation:

       PROCEDURE DIVISION.
       DECLARATIVES.
       USE-BEFORE-DETAIL SECTION.
           USE BEFORE REPORTING STATEMENT-DETAIL.
       PREPARE-DETAIL-DATA.
      *    Format the transaction date for display
           MOVE SIR-TXN-DATE(5:2) TO WS-TXN-MM
           MOVE SIR-TXN-DATE(7:2) TO WS-TXN-DD
           MOVE SIR-TXN-DATE(1:4) TO WS-TXN-YYYY
           STRING WS-TXN-MM "/" WS-TXN-DD "/"
                  WS-TXN-YYYY DELIMITED SIZE
               INTO WS-TXN-DATE-FORMATTED

      *    Split amount into debit/credit columns
           IF SIR-TXN-AMOUNT < 0
               COMPUTE WS-DEBIT-AMOUNT =
                   SIR-TXN-AMOUNT * -1
               MOVE 0 TO WS-CREDIT-AMOUNT
           ELSE
               MOVE 0 TO WS-DEBIT-AMOUNT
               MOVE SIR-TXN-AMOUNT TO WS-CREDIT-AMOUNT
           END-IF
           .
       END DECLARATIVES.

       MAIN-PROCESSING SECTION.
       0000-MAIN.
           OPEN INPUT  STATEMENT-INPUT-FILE
           OPEN OUTPUT STATEMENT-REPORT-FILE

           INITIATE MONTHLY-STATEMENT

           MOVE 0 TO WS-CUSTOMER-COUNT
           MOVE SPACES TO WS-PREV-CUSTOMER

           PERFORM 1000-READ-INPUT
           PERFORM UNTIL WS-INPUT-EOF
               IF SIR-CUSTOMER-NUMBER NOT = WS-PREV-CUSTOMER
                   ADD 1 TO WS-CUSTOMER-COUNT
                   MOVE SIR-CUSTOMER-NUMBER
                       TO WS-PREV-CUSTOMER
               END-IF
               GENERATE STATEMENT-DETAIL
               PERFORM 1000-READ-INPUT
           END-PERFORM

           TERMINATE MONTHLY-STATEMENT

           CLOSE STATEMENT-INPUT-FILE
           CLOSE STATEMENT-REPORT-FILE

           DISPLAY "STATEMENTS GENERATED FOR "
               WS-CUSTOMER-COUNT " CUSTOMERS"
           STOP RUN
           .

       1000-READ-INPUT.
           READ STATEMENT-INPUT-FILE
               AT END SET WS-INPUT-EOF TO TRUE
           END-READ
           .

The entire PROCEDURE DIVISION, excluding the declaratives section, is under 30 lines. Compare this to the 500+ lines that the equivalent manual report logic would require. Three statements do all the work:

  • INITIATE: Activates the report, initializes all SUM counters, and triggers the Report Heading.
  • GENERATE: Produces one detail line and handles all automatic processing: page overflow (triggers Page Heading/Footing), control breaks (triggers Control Headings and Footings), and SUM accumulation.
  • TERMINATE: Triggers the final Control Footings at all levels and the Report Footing.

The USE BEFORE REPORTING Declarative

The USE BEFORE REPORTING declarative executes custom logic just before a specific report group is presented. In this case, it formats the transaction date and splits the transaction amount into separate debit and credit fields for display in two columns.

This is necessary because the input record stores the amount as a single signed field (negative for debits, positive for credits), but the statement displays debits and credits in separate columns. The declarative performs this transformation immediately before each detail line is generated.


JCL for Statement Generation

//STMTGEN  JOB (ACCT),'MONTHLY STATEMENTS',
//         CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID
//*
//GENSTMT  EXEC PGM=STMTGEN
//STEPLIB  DD DSN=PROD.LOADLIB,DISP=SHR
//*
//* SORTED TRANSACTION INPUT
//STMTINP  DD DSN=BANK.MONTHLY.STMT.INPUT,DISP=SHR
//*
//* REPORT OUTPUT (PRINT FILE)
//STMTRPT  DD SYSOUT=A,
//         DCB=(RECFM=FBA,LRECL=133,BLKSIZE=0)
//*
//SYSOUT   DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*

The output file uses RECFM=FBA (Fixed Block with ASA carriage control). The ASA carriage control character in column 1 controls printer page ejects and line spacing. Report Writer generates these control characters automatically.


Sample Output

===========================================================
    COLUMBIA TRUST BANK
    MONTHLY ACCOUNT STATEMENT
===========================================================

Statement Date: 01/31/2026                           Page   1

DATE        DESCRIPTION                DEBITS      CREDITS       BALANCE
-------------------------------------------------------------------------------
Margaret A. Thompson
Acct #: 00045721
742 Elmwood Drive
Springfield            IL  62704-1122

Account:      2847100445  Type: CK
------------------------------------------------------------
01/02/2026  OPENING BALANCE                                    $  5,247.83
01/03/2026  POS PURCHASE #4721        $    47.95                $  5,199.88
01/05/2026  ATM WITHDRAWAL            $   200.00                $  4,999.88
01/07/2026  DIRECT DEPOSIT                         $ 3,285.00   $  8,284.88
01/10/2026  CHECK #1047               $   850.00                $  7,434.88
01/15/2026  ONLINE PAYMENT            $   125.50                $  7,309.38
01/22/2026  DIRECT DEPOSIT                         $ 3,285.00   $ 10,594.38
01/28/2026  UTILITY PAYMENT           $   187.43                $ 10,406.95
------------------------------------------------------------
                Account Totals:       $ 1,410.88   $ 6,570.00   $ 10,406.95

Account:      2847100446  Type: SV
------------------------------------------------------------
01/01/2026  OPENING BALANCE                                    $ 12,500.00
01/15/2026  TRANSFER FROM CK                       $ 1,000.00   $ 13,500.00
01/31/2026  INTEREST EARNED                        $    11.25   $ 13,511.25
------------------------------------------------------------
                Account Totals:       $      0.00  $ 1,011.25   $ 13,511.25

===========================================================
    CUSTOMER GRAND TOTAL:             $ 1,410.88   $ 7,581.25
    Thank you for banking with Columbia Trust

Lessons Learned

1. Report Writer Dramatically Reduces Code Volume

The original manual statement program was 4,500 lines. The Report Writer version is approximately 300 lines total (including the REPORT SECTION declarations). The reduction comes primarily from eliminating the procedural page-break, control-break, and accumulation logic that Report Writer handles automatically.

2. Layout Changes Are Isolated to the REPORT SECTION

When the marketing department requested a new promotional message line in the customer footing, the change required modifying only the CONTROL FOOTING SIR-CUSTOMER-NUMBER group in the REPORT SECTION. No changes to the PROCEDURE DIVISION were needed, and the change was tested in a single afternoon.

3. SUM Rollup Eliminates Manual Accumulator Management

In the manual version, the programmer maintained six separate accumulators (account-debit, account-credit, customer-debit, customer-credit, grand-debit, grand-credit) with explicit ADD, reset, and rollup logic. Report Writer's cascading SUM replaces all of this with two SUM clauses that automatically roll up from account to customer to final level.

4. USE BEFORE REPORTING Bridges the Gap

The declarative section provides a clean hook for data transformation logic that does not fit naturally into the REPORT SECTION's declarative model. Without it, the program would need to pre-process every record in the PROCEDURE DIVISION before calling GENERATE, which would add complexity to the main loop.


Discussion Questions

  1. What happens when a customer has so many transactions that the account section spans multiple pages? How does Report Writer handle the Page Heading reprinting, and does the Account Control Heading reprint on the new page?

  2. The FIRST DETAIL line is set to 12, leaving 11 lines for headers. If the customer address section requires more lines (for example, adding a second address line for suite numbers), what changes to the RD entry are needed?

  3. Why is the customer count tracked manually in the PROCEDURE DIVISION rather than using a Report Writer SUM or counter? Could Report Writer's built-in mechanisms handle this?

  4. Compare the Report Writer approach to generating statements as PDF files using a modern reporting tool. What are the advantages of each approach, and in what scenarios would Report Writer still be preferred?

  5. If the bank wanted to produce statements in two formats (paper and electronic/CSV), how much of the Report Writer program could be reused for the electronic format?