Case Study 2: Branch Performance Summary Report

Background

Great Plains National Bank operates 42 branches organized into 6 regions across a four-state territory. Executive leadership requires a weekly performance summary report that shows key metrics at the branch level, with subtotals at the regional level and grand totals at the company level. The report includes transaction volumes, deposit totals, loan origination amounts, and revenue figures.

This report is a classic example of a multi-level control break report -- the kind of report that Report Writer was specifically designed to handle. The data is sorted by region, then by branch within each region. As the program reads through the data, it must detect when the branch changes (minor control break) and when the region changes (major control break), printing appropriate subtotals at each transition.

Without Report Writer, implementing a three-level control break report requires approximately 15 to 20 paragraphs of procedural code: save-and-compare logic for each control field, separate accumulator variables at each level, explicit rollup of minor-level totals into major-level totals, and page overflow handling that interacts with the control break logic. With Report Writer, the entire control break mechanism is declared in the REPORT SECTION and managed automatically by the runtime.


Data Design

The Performance Input File

The input file is sorted by region code and branch code. Each record represents one branch's weekly performance data:

       SELECT PERFORMANCE-INPUT-FILE
           ASSIGN TO PERFINP
           ORGANIZATION IS SEQUENTIAL
           FILE STATUS IS WS-INPUT-STATUS.

       FD  PERFORMANCE-INPUT-FILE
           RECORDING MODE IS F
           RECORD CONTAINS 200 CHARACTERS.

       01  PERFORMANCE-INPUT-RECORD.
           05  PIR-REGION-CODE         PIC X(3).
           05  PIR-REGION-NAME         PIC X(20).
           05  PIR-BRANCH-CODE         PIC X(5).
           05  PIR-BRANCH-NAME         PIC X(25).
           05  PIR-BRANCH-MANAGER      PIC X(25).
           05  PIR-WEEK-ENDING         PIC 9(8).
           05  PIR-TXN-COUNT           PIC 9(7).
           05  PIR-NEW-ACCOUNTS        PIC 9(4).
           05  PIR-CLOSED-ACCOUNTS     PIC 9(4).
           05  PIR-DEPOSIT-TOTAL       PIC S9(11)V99.
           05  PIR-WITHDRAWAL-TOTAL    PIC S9(11)V99.
           05  PIR-LOAN-ORIGINATIONS   PIC S9(11)V99.
           05  PIR-INTEREST-INCOME     PIC S9(9)V99.
           05  PIR-FEE-INCOME          PIC S9(9)V99.
           05  PIR-OPERATING-EXPENSE   PIC S9(9)V99.
           05  PIR-FILLER              PIC X(43).

Working-Storage Computed Fields

Several metrics on the report are derived from the raw input data:

       WORKING-STORAGE SECTION.
       01  WS-COMPUTED-FIELDS.
           05  WS-NET-DEPOSIT-FLOW     PIC S9(11)V99.
           05  WS-TOTAL-REVENUE        PIC S9(11)V99.
           05  WS-NET-INCOME           PIC S9(11)V99.
           05  WS-EFFICIENCY-RATIO     PIC 9(3)V99.
           05  WS-BRANCH-COUNT         PIC 9(3).
           05  WS-REGION-BRANCH-COUNT  PIC 9(3).
           05  WS-TOTAL-BRANCH-COUNT   PIC 9(3).

The Report Output File

       SELECT PERFORMANCE-REPORT-FILE
           ASSIGN TO PERFRPT
           ORGANIZATION IS SEQUENTIAL
           FILE STATUS IS WS-REPORT-STATUS.

       FD  PERFORMANCE-REPORT-FILE
           REPORT IS BRANCH-PERFORMANCE-REPORT.

The Report Section

Report Description (RD)

       REPORT SECTION.
       RD  BRANCH-PERFORMANCE-REPORT
           CONTROLS ARE FINAL
                       PIR-REGION-CODE
                       PIR-BRANCH-CODE
           PAGE LIMIT IS 66 LINES
           HEADING 1
           FIRST DETAIL 10
           LAST DETAIL 56
           FOOTING 62.

The three control levels create the hierarchical structure: - FINAL: Company-level grand totals (printed once at the end) - PIR-REGION-CODE: Region-level subtotals (printed when the region changes) - PIR-BRANCH-CODE: Branch-level detail (one line per branch)

Report Heading

       01  TYPE IS REPORT HEADING.
           02  LINE 1.
               05  COLUMN 1   PIC X(80) VALUE ALL "=".
           02  LINE 2.
               05  COLUMN 20  PIC X(40) VALUE
                   "GREAT PLAINS NATIONAL BANK".
           02  LINE 3.
               05  COLUMN 17  PIC X(45) VALUE
                   "WEEKLY BRANCH PERFORMANCE SUMMARY".
           02  LINE 4.
               05  COLUMN 1   PIC X(80) VALUE ALL "=".
           02  LINE 5.
               05  COLUMN 1   PIC X(20) VALUE
                   "Report Generated: ".
               05  COLUMN 22  PIC X(10)
                   SOURCE WS-REPORT-DATE-FORMATTED.
               05  COLUMN 45  PIC X(15) VALUE
                   "Week Ending: ".
               05  COLUMN 61  PIC X(10)
                   SOURCE WS-WEEK-ENDING-FORMATTED.

Page Heading

       01  TYPE IS PAGE HEADING.
           02  LINE 7.
               05  COLUMN 1   PIC X(5)  VALUE "Brch".
               05  COLUMN 8   PIC X(15) VALUE "Branch Name".
               05  COLUMN 25  PIC X(7)  VALUE "Txn Cnt".
               05  COLUMN 34  PIC X(8)  VALUE "New Acct".
               05  COLUMN 44  PIC X(14) VALUE "Net Deposits".
               05  COLUMN 60  PIC X(14) VALUE "Loan Orig.".
               05  COLUMN 76  PIC X(12) VALUE "Net Income".
           02  LINE 8.
               05  COLUMN 1   PIC X(90) VALUE ALL "-".

Region Control Heading

When the region changes, a heading line announces the new region:

       01  TYPE IS CONTROL HEADING PIR-REGION-CODE.
           02  LINE PLUS 2.
               05  COLUMN 1   PIC X(10) VALUE "REGION: ".
               05  COLUMN 11  PIC X(3)
                   SOURCE PIR-REGION-CODE.
               05  COLUMN 16  PIC X(20)
                   SOURCE PIR-REGION-NAME.
           02  LINE PLUS 1.
               05  COLUMN 1   PIC X(50) VALUE ALL "-".

Detail Line (One Per Branch)

The detail line shows each branch's performance on a single row:

       01  BRANCH-DETAIL TYPE IS DETAIL.
           02  LINE PLUS 1.
               05  COLUMN 1   PIC X(5)
                   SOURCE PIR-BRANCH-CODE.
               05  COLUMN 8   PIC X(15)
                   SOURCE PIR-BRANCH-NAME.
               05  COLUMN 24  PIC ZZZ,ZZ9
                   SOURCE PIR-TXN-COUNT.
               05  COLUMN 35  PIC Z,ZZ9
                   SOURCE PIR-NEW-ACCOUNTS.
               05  COLUMN 42  PIC $(5),$$9,999.99-
                   SOURCE WS-NET-DEPOSIT-FLOW.
               05  COLUMN 58  PIC $(5),$$9,999.99-
                   SOURCE PIR-LOAN-ORIGINATIONS.
               05  COLUMN 74  PIC $(4),$$9,999.99-
                   SOURCE WS-NET-INCOME.
```

### Branch Control Footing

Since each branch has only one detail line, the branch control footing is used not for subtotals but for an efficiency indicator that prints below each branch when the ratio exceeds a threshold:

```cobol
       01  TYPE IS CONTROL FOOTING PIR-BRANCH-CODE.
           02  LINE PLUS 1.
               05  COLUMN 8   PIC X(25)
                   SOURCE WS-EFFICIENCY-MESSAGE.
```

### Region Control Footing (Regional Subtotals)

```cobol
       01  REGION-FOOTING
           TYPE IS CONTROL FOOTING PIR-REGION-CODE.
           02  LINE PLUS 1.
               05  COLUMN 1   PIC X(50) VALUE ALL "-".
           02  LINE PLUS 1.
               05  COLUMN 1   PIC X(7)  VALUE "Region".
               05  COLUMN 9   PIC X(3)
                   SOURCE PIR-REGION-CODE.
               05  COLUMN 14  PIC X(7)  VALUE "Total:".
               05  COLUMN 22  PIC ZZZZ,ZZ9
                   SUM PIR-TXN-COUNT.
               05  COLUMN 33  PIC ZZ,ZZ9
                   SUM PIR-NEW-ACCOUNTS.
               05  COLUMN 42  PIC $(5),$$9,999.99-
                   SUM WS-NET-DEPOSIT-FLOW.
               05  COLUMN 58  PIC $(5),$$9,999.99-
                   SUM PIR-LOAN-ORIGINATIONS.
               05  COLUMN 74  PIC $(4),$$9,999.99-
                   SUM WS-NET-INCOME.
           02  LINE PLUS 1.
               05  COLUMN 8   PIC X(10) VALUE "Branches:".
               05  COLUMN 20  PIC ZZ9
                   SOURCE WS-REGION-BRANCH-COUNT.
               05  COLUMN 28  PIC X(15) VALUE
                   "Avg Efficiency:".
               05  COLUMN 45  PIC ZZ9.99
                   SOURCE WS-REGION-AVG-EFFICIENCY.
               05  COLUMN 52  PIC X(1)  VALUE "%".

The SUM clauses at the region level automatically accumulate the values from every branch detail line within the region. When the region code changes, these accumulated totals are printed and then reset to zero for the next region.

Final Control Footing (Company Grand Totals)

       01  TYPE IS CONTROL FOOTING FINAL.
           02  LINE PLUS 2.
               05  COLUMN 1   PIC X(80) VALUE ALL "=".
           02  LINE PLUS 1.
               05  COLUMN 1   PIC X(30) VALUE
                   "COMPANY GRAND TOTALS".
           02  LINE PLUS 1.
               05  COLUMN 8   PIC X(14) VALUE
                   "Transactions:".
               05  COLUMN 22  PIC Z,ZZZ,ZZ9
                   SUM PIR-TXN-COUNT.
           02  LINE PLUS 1.
               05  COLUMN 8   PIC X(14) VALUE
                   "New Accounts:".
               05  COLUMN 22  PIC ZZZ,ZZ9
                   SUM PIR-NEW-ACCOUNTS.
           02  LINE PLUS 1.
               05  COLUMN 8   PIC X(14) VALUE
                   "Net Deposits:".
               05  COLUMN 22  PIC $(9),$$9,999.99-
                   SUM WS-NET-DEPOSIT-FLOW.
           02  LINE PLUS 1.
               05  COLUMN 8   PIC X(14) VALUE
                   "Loan Orig.:".
               05  COLUMN 22  PIC $(9),$$9,999.99-
                   SUM PIR-LOAN-ORIGINATIONS.
           02  LINE PLUS 1.
               05  COLUMN 8   PIC X(14) VALUE
                   "Net Income:".
               05  COLUMN 22  PIC $(9),$$9,999.99-
                   SUM WS-NET-INCOME.
           02  LINE PLUS 1.
               05  COLUMN 8   PIC X(14) VALUE
                   "Total Branches:".
               05  COLUMN 22  PIC ZZ9
                   SOURCE WS-TOTAL-BRANCH-COUNT.
           02  LINE PLUS 1.
               05  COLUMN 1   PIC X(80) VALUE ALL "=".

At the FINAL level, the SUM clauses accumulate from all region-level SUMs, providing the automatic three-tier rollup: branch detail accumulates into region subtotals, and region subtotals accumulate into company grand totals.

Page Footing

       01  TYPE IS PAGE FOOTING.
           02  LINE 64.
               05  COLUMN 1   PIC X(30) VALUE
                   "CONFIDENTIAL - INTERNAL USE".
               05  COLUMN 55  PIC X(5)  VALUE "Page ".
               05  COLUMN 60  PIC ZZ9
                   SOURCE PAGE-COUNTER.

The Procedure Division

       PROCEDURE DIVISION.
       DECLARATIVES.
       BEFORE-DETAIL SECTION.
           USE BEFORE REPORTING BRANCH-DETAIL.
       COMPUTE-BRANCH-METRICS.
      *    Calculate derived fields before each detail line
           COMPUTE WS-NET-DEPOSIT-FLOW =
               PIR-DEPOSIT-TOTAL - PIR-WITHDRAWAL-TOTAL

           COMPUTE WS-TOTAL-REVENUE =
               PIR-INTEREST-INCOME + PIR-FEE-INCOME

           COMPUTE WS-NET-INCOME =
               WS-TOTAL-REVENUE - PIR-OPERATING-EXPENSE

           IF WS-TOTAL-REVENUE > 0
               COMPUTE WS-EFFICIENCY-RATIO ROUNDED =
                   (PIR-OPERATING-EXPENSE /
                    WS-TOTAL-REVENUE) * 100
           ELSE
               MOVE 999.99 TO WS-EFFICIENCY-RATIO
           END-IF

           IF WS-EFFICIENCY-RATIO > 80
               MOVE "** HIGH COST BRANCH **"
                   TO WS-EFFICIENCY-MESSAGE
           ELSE IF WS-EFFICIENCY-RATIO < 50
               MOVE "(Top Performer)"
                   TO WS-EFFICIENCY-MESSAGE
           ELSE
               MOVE SPACES TO WS-EFFICIENCY-MESSAGE
           END-IF

           ADD 1 TO WS-REGION-BRANCH-COUNT
           ADD 1 TO WS-TOTAL-BRANCH-COUNT

      *    Accumulate for region average efficiency
           ADD WS-EFFICIENCY-RATIO
               TO WS-REGION-EFFICIENCY-TOTAL
           .

       BEFORE-REGION-FOOT SECTION.
           USE BEFORE REPORTING REGION-FOOTING.
       COMPUTE-REGION-AVERAGES.
           IF WS-REGION-BRANCH-COUNT > 0
               COMPUTE WS-REGION-AVG-EFFICIENCY ROUNDED =
                   WS-REGION-EFFICIENCY-TOTAL /
                   WS-REGION-BRANCH-COUNT
           ELSE
               MOVE 0 TO WS-REGION-AVG-EFFICIENCY
           END-IF
      *    Reset region-level accumulators
           MOVE 0 TO WS-REGION-BRANCH-COUNT
           MOVE 0 TO WS-REGION-EFFICIENCY-TOTAL
           .
       END DECLARATIVES.

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

           INITIATE BRANCH-PERFORMANCE-REPORT

           MOVE 0 TO WS-TOTAL-BRANCH-COUNT
           MOVE 0 TO WS-REGION-BRANCH-COUNT
           MOVE 0 TO WS-REGION-EFFICIENCY-TOTAL

           PERFORM 1000-READ-INPUT
           PERFORM UNTIL WS-INPUT-EOF
               GENERATE BRANCH-DETAIL
               PERFORM 1000-READ-INPUT
           END-PERFORM

           TERMINATE BRANCH-PERFORMANCE-REPORT

           CLOSE PERFORMANCE-INPUT-FILE
           CLOSE PERFORMANCE-REPORT-FILE

           DISPLAY "REPORT COMPLETE: "
               WS-TOTAL-BRANCH-COUNT " BRANCHES PROCESSED"
           STOP RUN
           .

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

The Role of USE BEFORE REPORTING

This program uses two USE BEFORE REPORTING declaratives:

  1. BEFORE-DETAIL: Fires before each branch detail line. It computes derived metrics (net deposit flow, total revenue, net income, efficiency ratio) from the raw input fields. These computed fields are then available as SOURCE items in the detail line and as operands for SUM accumulation.

  2. BEFORE-REGION-FOOT: Fires before each region control footing. It computes the average efficiency ratio for the region by dividing the accumulated efficiency total by the branch count. It then resets the region-level accumulators for the next region.

This pattern -- computing derived values in a declarative and resetting accumulators in a control footing declarative -- is a standard Report Writer technique. The accumulators for values that Report Writer cannot SUM automatically (like averages, which cannot be computed by summing) must be managed manually in the declaratives.


JCL for the Performance Report

//PERFRPT  JOB (ACCT),'BRANCH PERF REPORT',
//         CLASS=A,MSGCLASS=X,NOTIFY=&SYSUID
//*
//* ENSURE INPUT IS SORTED BY REGION AND BRANCH
//*
//SORT     EXEC PGM=SORT
//SORTIN   DD DSN=BANK.WEEKLY.BRANCH.METRICS,DISP=SHR
//SORTOUT  DD DSN=&&SORTED,DISP=(NEW,PASS),
//         SPACE=(CYL,(5,2)),
//         DCB=(RECFM=FB,LRECL=200,BLKSIZE=0)
//SYSIN    DD *
  SORT FIELDS=(1,3,CH,A,24,5,CH,A)
//SYSOUT   DD SYSOUT=*
//*
//* GENERATE THE PERFORMANCE REPORT
//*
//REPORT   EXEC PGM=PERFRPT
//STEPLIB  DD DSN=PROD.LOADLIB,DISP=SHR
//PERFINP  DD DSN=&&SORTED,DISP=(OLD,DELETE)
//PERFRPT  DD SYSOUT=A,
//         DCB=(RECFM=FBA,LRECL=133,BLKSIZE=0)
//SYSOUT   DD SYSOUT=*
//SYSUDUMP DD SYSOUT=*

Sample Output

================================================================================
                   GREAT PLAINS NATIONAL BANK
                WEEKLY BRANCH PERFORMANCE SUMMARY
================================================================================
Report Generated: 02/10/2026              Week Ending: 02/07/2026

Brch   Branch Name      Txn Cnt  New Acct  Net Deposits    Loan Orig.    Net Income
------------------------------------------------------------------------------------------

REGION: MW1  Midwest North
--------------------------------------------------
MW101  Minneapolis       187,443    247    $  12,445,102   $  8,291,445  $   345,221
MW102  St. Paul          142,887    183    $   9,876,334   $  5,443,221  $   287,109
       (Top Performer)
MW103  Duluth             67,221     89    $   3,221,009   $  2,108,776  $    98,443
MW104  Rochester          73,445     94    $   4,112,887   $  2,556,332  $   112,776
--------------------------------------------------
Region MW1 Total:         470,996    613   $  29,655,332   $ 18,399,774  $   843,549
       Branches:   4   Avg Efficiency:  62.34%

REGION: MW2  Midwest South
--------------------------------------------------
MW201  Kansas City       198,776    312    $  14,887,221   $  9,776,554  $   412,887
MW202  Omaha             156,443    234    $  11,221,887   $  7,332,109  $   298,554
MW203  Wichita            89,112    127    $   5,443,665   $  3,887,221  $   156,221
       ** HIGH COST BRANCH **
MW204  Lincoln            71,887    101    $   3,998,776   $  2,665,443  $   121,887
--------------------------------------------------
Region MW2 Total:         516,218    774   $  35,551,549   $ 23,661,327  $   989,549
       Branches:   4   Avg Efficiency:  65.12%

...

================================================================================
COMPANY GRAND TOTALS

       Transactions:  2,847,221
       New Accounts:     4,287
       Net Deposits:  $187,443,221.34
       Loan Orig.:    $124,887,665.78
       Net Income:    $  5,221,887.45
       Total Branches:     42
================================================================================

CONFIDENTIAL - INTERNAL USE                                       Page   1

The Three-Level SUM Rollup in Action

The SUM mechanism works through automatic cascading:

  1. Detail level: Each GENERATE adds the branch's PIR-TXN-COUNT to the region-level SUM accumulator for that field.

  2. Region level: When the region changes, the region footing prints the accumulated SUM and the value automatically rolls up to the FINAL-level SUM accumulator. The region accumulator resets to zero.

  3. FINAL level: When TERMINATE executes, the FINAL footing prints the grand totals, which are the sum of all region-level subtotals.

This cascade happens entirely within the Report Writer runtime. The programmer never writes an ADD statement for these fields, never declares an accumulator variable, and never writes reset logic. The REPORT SECTION declarations alone define the entire accumulation hierarchy.


Lessons Learned

1. Report Writer Handles Control Breaks Flawlessly

The three-level control break (branch within region within company) is managed entirely by the CONTROLS clause and the control heading/footing groups. In manual code, this pattern requires careful save-and-compare logic, explicit footing triggers before heading triggers, and proper ordering of reset operations. Report Writer eliminates this entire class of bugs.

2. Computed Fields Require USE BEFORE REPORTING

Report Writer's SUM can only accumulate fields that appear as SOURCE items on detail lines. For derived metrics like net income (revenue minus expense) or efficiency ratio (expense divided by revenue), the programmer must compute these values in a USE BEFORE REPORTING declarative so they are ready when the detail line is generated.

3. Averages Cannot Be Computed by SUM

The average efficiency ratio across branches in a region cannot be computed by summing and dividing at the CONTROL FOOTING level, because Report Writer's SUM operates on individual detail values, not on aggregated values. The solution is to maintain manual accumulators in the declaratives and compute the average in the USE BEFORE REPORTING for the region footing.

4. Input Must Be Sorted Correctly

Report Writer assumes the input is sorted on the CONTROLS fields in major-to-minor order. If the input is not sorted correctly, Report Writer triggers control breaks at incorrect points, producing garbled output with wrong subtotals. The JCL includes a pre-sort step to guarantee correct ordering.


Discussion Questions

  1. The report currently shows one line per branch. If the bank wanted to show weekly trends (four weeks of data per branch, with each week on a separate detail line), what changes to the CONTROLS clause and detail line definition would be needed?

  2. The efficiency ratio average is computed manually because SUM cannot produce averages. Describe an alternative approach using GENERATE with a summary report group instead of detail lines. Would this simplify or complicate the program?

  3. What happens when a region has no branches (an empty control group)? Does Report Writer generate a region heading followed immediately by a region footing with zero totals?

  4. The report is currently sent to SYSOUT for printing. If management wanted the same data in a comma-separated format for import into a spreadsheet, could Report Writer produce CSV output? Why or why not?

  5. How would you modify the report to highlight branches where net income is negative (operating at a loss)? Consider both Report Writer capabilities and the limitations of line-printer output.