Case Study 1: Enterprise Copybook Library for a Banking System
Background
Continental Federal Bank operates a core banking platform built on IBM z/OS. The platform consists of forty-seven COBOL batch programs and twenty-two CICS online programs that collectively handle customer management, account processing, transaction posting, statement generation, and regulatory reporting. At the center of this ecosystem is a shared copybook library containing the data definitions that every program relies upon.
When the bank was smaller, copybook management was informal. Developers copied and pasted record layouts between programs, making small adjustments as needed. Over the years, this led to a maintenance nightmare: seventeen different versions of the customer record layout existed across the source library, each with slightly different field names, sizes, and orderings. A regulatory audit flagged the inconsistency as a compliance risk, and the CTO authorized a six-month project to consolidate all record layouts into a single, authoritative copybook library.
This case study follows the design and implementation of that consolidated library, demonstrating how COPY and COPY REPLACING enable dozens of programs to share identical record definitions while maintaining their own naming conventions and operational contexts.
Problem Statement
The project team identified three core record types that every banking program shares:
- Customer Record -- personal information, identification, contact details, and customer classification
- Account Record -- account type, status, balances, interest rates, and date fields
- Transaction Record -- transaction codes, amounts, timestamps, and audit fields
The challenge was threefold. First, the copybooks had to be designed so that any program could include them with a single COPY statement, using REPLACING to adapt field name prefixes for the program's specific context (file input, file output, working storage copy, linkage section parameter). Second, the copybooks had to be structured so that environment-specific configuration values -- such as file paths, processing dates, and region codes -- could be injected at compile time through REPLACING without modifying the copybook source. Third, the team needed to demonstrate that the same copybooks would work across at least five representative programs spanning batch and online processing.
Copybook Design
Design Principles
The team established four design principles before writing a single line of code:
-
One logical entity per copybook. The customer record, account record, and transaction record each reside in their own copybook file. A program that only needs customer data does not pull in account or transaction definitions.
-
Consistent prefix convention. Every field in a copybook begins with a short, predictable prefix (
CUST-,ACCT-,TXNR-). This makes COPY REPLACING trivial: a single replacement of the prefix renames every field in the copybook. -
Comprehensive 88-level conditions. Every coded field (status codes, type codes, flag fields) includes 88-level condition names. These condition names follow the prefix convention so they are also renamed by REPLACING.
-
Filler for expansion. Each copybook includes filler bytes at the end of the record for future fields, so that adding new fields does not change the record length until the filler is consumed.
The Customer Record Copybook
******************************************************************
* COPYBOOK: BNK-CUSTOMER-RECORD
* PURPOSE: Standard customer record for Continental Federal Bank
* RECORD LENGTH: 300 bytes
* PREFIX: CUST- (design for COPY REPLACING)
* VERSION: 3.0
* DATE: 2026-01-15
******************************************************************
01 CUST-RECORD.
05 CUST-ID PIC 9(10).
05 CUST-TAX-ID PIC X(11).
05 CUST-NAME-DATA.
10 CUST-LAST-NAME PIC X(25).
10 CUST-FIRST-NAME PIC X(20).
10 CUST-MIDDLE-INIT PIC X(01).
05 CUST-ADDRESS-DATA.
10 CUST-STREET-ADDR PIC X(35).
10 CUST-CITY PIC X(25).
10 CUST-STATE PIC X(02).
10 CUST-ZIP-CODE PIC X(10).
05 CUST-PHONE PIC X(15).
05 CUST-EMAIL PIC X(50).
05 CUST-DOB PIC 9(08).
05 CUST-OPEN-DATE PIC 9(08).
05 CUST-TYPE-CODE PIC X(01).
88 CUST-INDIVIDUAL VALUE 'I'.
88 CUST-BUSINESS VALUE 'B'.
88 CUST-TRUST VALUE 'T'.
88 CUST-GOVERNMENT VALUE 'G'.
05 CUST-STATUS-CODE PIC X(01).
88 CUST-ACTIVE VALUE 'A'.
88 CUST-INACTIVE VALUE 'I'.
88 CUST-SUSPENDED VALUE 'S'.
88 CUST-CLOSED VALUE 'C'.
88 CUST-IS-OPEN VALUE 'A' 'I'.
05 CUST-RISK-RATING PIC 9(01).
88 CUST-LOW-RISK VALUE 1.
88 CUST-MEDIUM-RISK VALUE 2 3.
88 CUST-HIGH-RISK VALUE 4 5.
05 CUST-BRANCH-CODE PIC X(06).
05 CUST-OFFICER-ID PIC 9(06).
05 CUST-FILLER PIC X(46).
The record totals exactly 300 bytes. The 46-byte filler at the end provides room for future expansion. When new fields are added, bytes are carved from the filler, keeping the total at 300 until a major version change is warranted.
The Account Record Copybook
******************************************************************
* COPYBOOK: BNK-ACCOUNT-RECORD
* PURPOSE: Standard account record for Continental Federal Bank
* RECORD LENGTH: 250 bytes
* PREFIX: ACCT- (design for COPY REPLACING)
* VERSION: 3.0
* DATE: 2026-01-15
******************************************************************
01 ACCT-RECORD.
05 ACCT-NUMBER PIC X(12).
05 ACCT-CUST-ID PIC 9(10).
05 ACCT-TYPE-CODE PIC X(02).
88 ACCT-CHECKING VALUE 'CK'.
88 ACCT-SAVINGS VALUE 'SV'.
88 ACCT-MONEY-MARKET VALUE 'MM'.
88 ACCT-CERTIFICATE VALUE 'CD'.
88 ACCT-LOAN VALUE 'LN'.
88 ACCT-MORTGAGE VALUE 'MG'.
88 ACCT-CREDIT-LINE VALUE 'CL'.
88 ACCT-IS-DEPOSIT VALUE 'CK' 'SV'
'MM' 'CD'.
88 ACCT-IS-LENDING VALUE 'LN' 'MG'
'CL'.
05 ACCT-STATUS-CODE PIC X(01).
88 ACCT-OPEN VALUE 'O'.
88 ACCT-FROZEN VALUE 'F'.
88 ACCT-DORMANT VALUE 'D'.
88 ACCT-CLOSED VALUE 'C'.
88 ACCT-IS-ACTIVE VALUE 'O' 'F'.
05 ACCT-OPEN-DATE PIC 9(08).
05 ACCT-CLOSE-DATE PIC 9(08).
05 ACCT-CURRENT-BAL PIC S9(13)V99 COMP-3.
05 ACCT-AVAILABLE-BAL PIC S9(13)V99 COMP-3.
05 ACCT-LEDGER-BAL PIC S9(13)V99 COMP-3.
05 ACCT-INTEREST-RATE PIC 9(02)V9(06) COMP-3.
05 ACCT-LAST-ACTIVITY PIC 9(08).
05 ACCT-LAST-STMT-DATE PIC 9(08).
05 ACCT-OVERDRAFT-LIMIT PIC S9(09)V99 COMP-3.
05 ACCT-YTD-INTEREST PIC S9(09)V99 COMP-3.
05 ACCT-YTD-FEES PIC S9(07)V99 COMP-3.
05 ACCT-BRANCH-CODE PIC X(06).
05 ACCT-PRODUCT-CODE PIC X(04).
05 ACCT-FILLER PIC X(108).
The Transaction Record Copybook
******************************************************************
* COPYBOOK: BNK-TRANSACTION-RECORD
* PURPOSE: Standard transaction record for Continental Federal
* Bank. Used for posting, audit trail, and reporting.
* RECORD LENGTH: 200 bytes
* PREFIX: TXNR- (design for COPY REPLACING)
* VERSION: 3.0
* DATE: 2026-01-15
******************************************************************
01 TXNR-RECORD.
05 TXNR-ID PIC X(16).
05 TXNR-ACCT-NUMBER PIC X(12).
05 TXNR-TYPE-CODE PIC X(03).
88 TXNR-DEPOSIT VALUE 'DEP'.
88 TXNR-WITHDRAWAL VALUE 'WDR'.
88 TXNR-TRANSFER-IN VALUE 'TRI'.
88 TXNR-TRANSFER-OUT VALUE 'TRO'.
88 TXNR-PAYMENT VALUE 'PMT'.
88 TXNR-FEE VALUE 'FEE'.
88 TXNR-INTEREST VALUE 'INT'.
88 TXNR-ADJUSTMENT VALUE 'ADJ'.
88 TXNR-IS-CREDIT VALUE 'DEP' 'TRI'
'INT' 'ADJ'.
88 TXNR-IS-DEBIT VALUE 'WDR' 'TRO'
'PMT' 'FEE'.
05 TXNR-AMOUNT PIC S9(13)V99 COMP-3.
05 TXNR-RUNNING-BAL PIC S9(13)V99 COMP-3.
05 TXNR-POST-DATE PIC 9(08).
05 TXNR-VALUE-DATE PIC 9(08).
05 TXNR-TIMESTAMP PIC X(26).
05 TXNR-DESCRIPTION PIC X(40).
05 TXNR-REF-NUMBER PIC X(20).
05 TXNR-SOURCE-CODE PIC X(02).
88 TXNR-FROM-TELLER VALUE 'TL'.
88 TXNR-FROM-ATM VALUE 'AT'.
88 TXNR-FROM-ONLINE VALUE 'OL'.
88 TXNR-FROM-ACH VALUE 'AC'.
88 TXNR-FROM-WIRE VALUE 'WR'.
88 TXNR-FROM-BATCH VALUE 'BT'.
05 TXNR-USER-ID PIC X(08).
05 TXNR-BRANCH-CODE PIC X(06).
05 TXNR-STATUS-CODE PIC X(01).
88 TXNR-POSTED VALUE 'P'.
88 TXNR-PENDING VALUE 'N'.
88 TXNR-REVERSED VALUE 'R'.
88 TXNR-HELD VALUE 'H'.
05 TXNR-FILLER PIC X(22).
The Environment Configuration Copybook
In addition to the three record layouts, the team created a configuration copybook that holds environment-specific values. Programs use COPY REPLACING to inject the correct values for each deployment environment (development, test, production):
******************************************************************
* COPYBOOK: BNK-ENV-CONFIG
* PURPOSE: Environment-specific configuration constants.
* Use COPY REPLACING to inject actual values.
* VERSION: 1.0
* DATE: 2026-01-15
******************************************************************
01 ENV-CONFIG.
05 ENV-REGION-CODE PIC X(04)
VALUE :ENV-REGION:.
05 ENV-PROCESSING-DATE PIC 9(08)
VALUE :ENV-PROC-DATE:.
05 ENV-DB2-SUBSYSTEM PIC X(04)
VALUE :ENV-DB2-SSID:.
05 ENV-CICS-APPLID PIC X(08)
VALUE :ENV-CICS-APPL:.
05 ENV-TRACE-FLAG PIC X(01)
VALUE :ENV-TRACE:.
88 ENV-TRACE-ON VALUE 'Y'.
88 ENV-TRACE-OFF VALUE 'N'.
05 ENV-MAX-ERRORS PIC 9(04)
VALUE :ENV-MAX-ERR:.
Programs inject their values at compile time:
COPY BNK-ENV-CONFIG
REPLACING ==:ENV-REGION:== BY =='EAST'==
==:ENV-PROC-DATE:== BY ==20260210==
==:ENV-DB2-SSID:== BY =='DB2P'==
==:ENV-CICS-APPL:== BY =='CICSPROD'==
==:ENV-TRACE:== BY =='N'==
==:ENV-MAX-ERR:== BY ==0050==.
This pattern eliminates hardcoded configuration values from program source. A development build uses different REPLACING values than a production build, and the copybook itself never changes.
Five Programs Sharing the Same Copybooks
To prove that the consolidated copybook library works across the application portfolio, the team selected five representative programs. Each program uses the same three record copybooks but in different combinations and with different REPLACING clauses.
Program 1: Daily Transaction Posting (Batch)
The transaction posting program reads a sorted transaction file and an account master file, applies transactions to account balances, and writes an updated master file. It needs all three copybooks, each included twice -- once for the input file records and once for the working storage copies.
IDENTIFICATION DIVISION.
PROGRAM-ID. BNKPOST0.
*================================================================*
* DAILY TRANSACTION POSTING PROGRAM *
* Reads transaction file and account master, posts debits and *
* credits, writes updated master and audit report. *
*================================================================*
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT ACCOUNT-MASTER-IN
ASSIGN TO ACCTMSTI
ORGANIZATION IS SEQUENTIAL
FILE STATUS IS WS-ACCT-IN-STATUS.
SELECT TRANSACTION-FILE
ASSIGN TO TRANFILE
ORGANIZATION IS SEQUENTIAL
FILE STATUS IS WS-TRAN-STATUS.
SELECT ACCOUNT-MASTER-OUT
ASSIGN TO ACCTMSTO
ORGANIZATION IS SEQUENTIAL
FILE STATUS IS WS-ACCT-OUT-STATUS.
SELECT AUDIT-REPORT
ASSIGN TO AUDITRPT
ORGANIZATION IS SEQUENTIAL
FILE STATUS IS WS-RPT-STATUS.
DATA DIVISION.
FILE SECTION.
FD ACCOUNT-MASTER-IN
RECORDING MODE IS F
RECORD CONTAINS 250 CHARACTERS.
COPY BNK-ACCOUNT-RECORD
REPLACING ==ACCT-== BY ==AMIN-==
==ACCT-RECORD== BY ==AMIN-RECORD==.
FD TRANSACTION-FILE
RECORDING MODE IS F
RECORD CONTAINS 200 CHARACTERS.
COPY BNK-TRANSACTION-RECORD
REPLACING ==TXNR-== BY ==TRIN-==
==TXNR-RECORD== BY ==TRIN-RECORD==.
FD ACCOUNT-MASTER-OUT
RECORDING MODE IS F
RECORD CONTAINS 250 CHARACTERS.
COPY BNK-ACCOUNT-RECORD
REPLACING ==ACCT-== BY ==AMOT-==
==ACCT-RECORD== BY ==AMOT-RECORD==.
FD AUDIT-REPORT
RECORDING MODE IS F
RECORD CONTAINS 132 CHARACTERS.
01 AUDIT-LINE PIC X(132).
WORKING-STORAGE SECTION.
01 WS-FILE-STATUSES.
05 WS-ACCT-IN-STATUS PIC X(02).
05 WS-TRAN-STATUS PIC X(02).
05 WS-ACCT-OUT-STATUS PIC X(02).
05 WS-RPT-STATUS PIC X(02).
01 WS-FLAGS.
05 WS-EOF-ACCT PIC X VALUE 'N'.
88 EOF-ACCT VALUE 'Y'.
05 WS-EOF-TRAN PIC X VALUE 'N'.
88 EOF-TRAN VALUE 'Y'.
01 WS-COUNTERS.
05 WS-ACCTS-READ PIC 9(07) VALUE 0.
05 WS-TRANS-READ PIC 9(07) VALUE 0.
05 WS-TRANS-POSTED PIC 9(07) VALUE 0.
05 WS-TRANS-REJECTED PIC 9(07) VALUE 0.
05 WS-ACCTS-UPDATED PIC 9(07) VALUE 0.
* Working storage copy of account record for manipulation
COPY BNK-ACCOUNT-RECORD
REPLACING ==ACCT-== BY ==WS-ACCT-==
==ACCT-RECORD== BY ==WS-ACCT-RECORD==.
* Working storage copy of transaction record
COPY BNK-TRANSACTION-RECORD
REPLACING ==TXNR-== BY ==WS-TXN-==
==TXNR-RECORD== BY ==WS-TXN-RECORD==.
* Environment configuration
COPY BNK-ENV-CONFIG
REPLACING ==:ENV-REGION:== BY =='EAST'==
==:ENV-PROC-DATE:== BY ==20260210==
==:ENV-DB2-SSID:== BY =='DB2P'==
==:ENV-CICS-APPL:== BY ==' '==
==:ENV-TRACE:== BY =='N'==
==:ENV-MAX-ERR:== BY ==0100==.
01 WS-AUDIT-DETAIL.
05 WS-AUD-DATE PIC 9(08).
05 FILLER PIC X(02) VALUE SPACES.
05 WS-AUD-ACCT PIC X(12).
05 FILLER PIC X(02) VALUE SPACES.
05 WS-AUD-TXN-TYPE PIC X(03).
05 FILLER PIC X(02) VALUE SPACES.
05 WS-AUD-AMOUNT PIC -(9)9.99.
05 FILLER PIC X(02) VALUE SPACES.
05 WS-AUD-NEW-BAL PIC -(13)9.99.
05 FILLER PIC X(02) VALUE SPACES.
05 WS-AUD-STATUS PIC X(08).
05 FILLER PIC X(02) VALUE SPACES.
05 WS-AUD-MESSAGE PIC X(40).
PROCEDURE DIVISION.
0000-MAIN.
PERFORM 1000-INITIALIZE
PERFORM 2000-PROCESS-TRANSACTIONS
UNTIL EOF-ACCT AND EOF-TRAN
PERFORM 9000-FINALIZE
STOP RUN.
1000-INITIALIZE.
OPEN INPUT ACCOUNT-MASTER-IN
TRANSACTION-FILE
OUTPUT ACCOUNT-MASTER-OUT
AUDIT-REPORT
PERFORM 1100-READ-ACCOUNT
PERFORM 1200-READ-TRANSACTION.
1100-READ-ACCOUNT.
READ ACCOUNT-MASTER-IN INTO WS-ACCT-RECORD
AT END SET EOF-ACCT TO TRUE
NOT AT END ADD 1 TO WS-ACCTS-READ
END-READ.
1200-READ-TRANSACTION.
READ TRANSACTION-FILE INTO WS-TXN-RECORD
AT END SET EOF-TRAN TO TRUE
NOT AT END ADD 1 TO WS-TRANS-READ
END-READ.
2000-PROCESS-TRANSACTIONS.
* Classic sequential match-merge on account number
EVALUATE TRUE
WHEN WS-ACCT-NUMBER < WS-TXN-ACCT-NUMBER
PERFORM 2100-WRITE-UNMATCHED-ACCT
WHEN WS-ACCT-NUMBER = WS-TXN-ACCT-NUMBER
PERFORM 2200-POST-TRANSACTION
WHEN WS-ACCT-NUMBER > WS-TXN-ACCT-NUMBER
PERFORM 2300-REJECT-UNMATCHED-TXN
END-EVALUATE.
2100-WRITE-UNMATCHED-ACCT.
MOVE WS-ACCT-RECORD TO AMOT-RECORD
WRITE AMOT-RECORD
ADD 1 TO WS-ACCTS-UPDATED
PERFORM 1100-READ-ACCOUNT.
2200-POST-TRANSACTION.
IF WS-ACCT-IS-ACTIVE
EVALUATE TRUE
WHEN WS-TXN-IS-CREDIT
ADD WS-TXN-AMOUNT
TO WS-ACCT-CURRENT-BAL
ADD WS-TXN-AMOUNT
TO WS-ACCT-AVAILABLE-BAL
WHEN WS-TXN-IS-DEBIT
SUBTRACT WS-TXN-AMOUNT
FROM WS-ACCT-CURRENT-BAL
SUBTRACT WS-TXN-AMOUNT
FROM WS-ACCT-AVAILABLE-BAL
END-EVALUATE
MOVE ENV-PROCESSING-DATE
TO WS-ACCT-LAST-ACTIVITY
PERFORM 2210-WRITE-AUDIT-POSTED
ADD 1 TO WS-TRANS-POSTED
ELSE
PERFORM 2220-WRITE-AUDIT-REJECTED
ADD 1 TO WS-TRANS-REJECTED
END-IF
PERFORM 1200-READ-TRANSACTION.
2210-WRITE-AUDIT-POSTED.
MOVE ENV-PROCESSING-DATE TO WS-AUD-DATE
MOVE WS-TXN-ACCT-NUMBER TO WS-AUD-ACCT
MOVE WS-TXN-TYPE-CODE TO WS-AUD-TXN-TYPE
MOVE WS-TXN-AMOUNT TO WS-AUD-AMOUNT
MOVE WS-ACCT-CURRENT-BAL TO WS-AUD-NEW-BAL
MOVE 'POSTED ' TO WS-AUD-STATUS
MOVE WS-TXN-DESCRIPTION TO WS-AUD-MESSAGE
WRITE AUDIT-LINE FROM WS-AUDIT-DETAIL.
2220-WRITE-AUDIT-REJECTED.
MOVE ENV-PROCESSING-DATE TO WS-AUD-DATE
MOVE WS-TXN-ACCT-NUMBER TO WS-AUD-ACCT
MOVE WS-TXN-TYPE-CODE TO WS-AUD-TXN-TYPE
MOVE WS-TXN-AMOUNT TO WS-AUD-AMOUNT
MOVE ZEROES TO WS-AUD-NEW-BAL
MOVE 'REJECTED' TO WS-AUD-STATUS
MOVE 'Account not active' TO WS-AUD-MESSAGE
WRITE AUDIT-LINE FROM WS-AUDIT-DETAIL.
2300-REJECT-UNMATCHED-TXN.
ADD 1 TO WS-TRANS-REJECTED
PERFORM 1200-READ-TRANSACTION.
9000-FINALIZE.
* Write final account if not at EOF
IF NOT EOF-ACCT
MOVE WS-ACCT-RECORD TO AMOT-RECORD
WRITE AMOT-RECORD
ADD 1 TO WS-ACCTS-UPDATED
END-IF
DISPLAY 'BNKPOST0 COMPLETE'
DISPLAY ' ACCOUNTS READ: ' WS-ACCTS-READ
DISPLAY ' TRANSACTIONS READ: ' WS-TRANS-READ
DISPLAY ' TRANS POSTED: ' WS-TRANS-POSTED
DISPLAY ' TRANS REJECTED: ' WS-TRANS-REJECTED
DISPLAY ' ACCOUNTS WRITTEN: ' WS-ACCTS-UPDATED
CLOSE ACCOUNT-MASTER-IN
TRANSACTION-FILE
ACCOUNT-MASTER-OUT
AUDIT-REPORT.
Notice how the same BNK-ACCOUNT-RECORD copybook is included three times -- once for the input file (prefix AMIN-), once for the output file (prefix AMOT-), and once for working storage (prefix WS-ACCT-). Each inclusion creates a distinct set of field names from the identical layout, guaranteeing structural consistency.
Program 2: Customer Inquiry (CICS Online)
The online inquiry program uses the customer and account copybooks in its WORKING-STORAGE SECTION, with the standard WS- prefix for working copies and a DI- prefix for the display map fields:
IDENTIFICATION DIVISION.
PROGRAM-ID. BNKINQ0.
*================================================================*
* CUSTOMER INQUIRY - CICS ONLINE PROGRAM *
* Displays customer information and account summary. *
*================================================================*
DATA DIVISION.
WORKING-STORAGE SECTION.
COPY BNK-CUSTOMER-RECORD
REPLACING ==CUST-== BY ==WS-CUST-==
==CUST-RECORD== BY ==WS-CUST-RECORD==.
COPY BNK-ACCOUNT-RECORD
REPLACING ==ACCT-== BY ==WS-ACCT-==
==ACCT-RECORD== BY ==WS-ACCT-RECORD==.
01 WS-COMMAREA.
05 CA-CUST-ID PIC 9(10).
05 CA-STATE PIC X(02).
88 CA-FIRST-TIME VALUE '00'.
88 CA-DISPLAY-CUST VALUE '10'.
PROCEDURE DIVISION.
EVALUATE TRUE
WHEN CA-FIRST-TIME
PERFORM 1000-SEND-EMPTY-MAP
WHEN CA-DISPLAY-CUST
PERFORM 2000-RECEIVE-AND-INQUIRE
END-EVALUATE
EXEC CICS RETURN
TRANSID('BINQ')
COMMAREA(WS-COMMAREA)
LENGTH(LENGTH OF WS-COMMAREA)
END-EXEC.
Program 3: Statement Generation (Batch)
The statement program reads customer and transaction records together, using REPLACING with STMT- prefixes to create statement-specific field names:
COPY BNK-CUSTOMER-RECORD
REPLACING ==CUST-== BY ==STMT-CUST-==
==CUST-RECORD== BY ==STMT-CUST-RECORD==.
COPY BNK-TRANSACTION-RECORD
REPLACING ==TXNR-== BY ==STMT-TXN-==
==TXNR-RECORD== BY ==STMT-TXN-RECORD==.
Program 4: Interest Calculation (Batch)
The interest calculation program only needs account records, but it includes the copybook twice -- once for reading the current state and once for writing the updated state:
COPY BNK-ACCOUNT-RECORD
REPLACING ==ACCT-== BY ==CURR-==
==ACCT-RECORD== BY ==CURR-RECORD==.
COPY BNK-ACCOUNT-RECORD
REPLACING ==ACCT-== BY ==UPD-==
==ACCT-RECORD== BY ==UPD-RECORD==.
Program 5: Regulatory Reporting Extract (Batch)
The regulatory reporting program needs all three copybooks and also uses the environment configuration copybook with production-specific settings:
COPY BNK-CUSTOMER-RECORD
REPLACING ==CUST-== BY ==REG-CUST-==
==CUST-RECORD== BY ==REG-CUST-RECORD==.
COPY BNK-ACCOUNT-RECORD
REPLACING ==ACCT-== BY ==REG-ACCT-==
==ACCT-RECORD== BY ==REG-ACCT-RECORD==.
COPY BNK-TRANSACTION-RECORD
REPLACING ==TXNR-== BY ==REG-TXN-==
==TXNR-RECORD== BY ==REG-TXN-RECORD==.
COPY BNK-ENV-CONFIG
REPLACING ==:ENV-REGION:== BY =='EAST'==
==:ENV-PROC-DATE:== BY ==20260210==
==:ENV-DB2-SSID:== BY =='DB2P'==
==:ENV-CICS-APPL:== BY ==' '==
==:ENV-TRACE:== BY =='Y'==
==:ENV-MAX-ERR:== BY ==0010==.
Notice that the regulatory program sets ENV-TRACE to 'Y' -- the team wanted full trace logging for regulatory extracts, even in production, for audit trail purposes.
Compile and Deploy Strategy
JCL for Compiling with the Shared Copybook Library
All five programs compile against the same copybook library. The SYSLIB concatenation ensures the compiler finds the consolidated copybooks:
//BNKPOST0 JOB (ACCT),'COMPILE POST PGM',CLASS=A,MSGCLASS=X
//COMPILE EXEC PGM=IGYCRCTL,
// PARM='RENT,APOST,DATA(31),XREF,SOURCE,MAP'
//STEPLIB DD DSN=IGY.V6R4M0.SIGYCOMP,DISP=SHR
//SYSLIB DD DSN=BNKAPP.PROD.COPYLIB,DISP=SHR
// DD DSN=BNKAPP.COMMON.COPYLIB,DISP=SHR
// DD DSN=COMPANY.SHARED.COPYLIB,DISP=SHR
//SYSIN DD DSN=BNKAPP.PROD.SOURCE(BNKPOST0),DISP=SHR
//SYSLIN DD DSN=&&OBJMOD,DISP=(MOD,PASS),UNIT=SYSDA,
// SPACE=(TRK,(5,5)),DCB=(BLKSIZE=3200)
//SYSPRINT DD SYSOUT=*
//SYSUT1 DD UNIT=SYSDA,SPACE=(TRK,(5,5))
//SYSUT2 DD UNIT=SYSDA,SPACE=(TRK,(5,5))
//SYSUT3 DD UNIT=SYSDA,SPACE=(TRK,(5,5))
//SYSUT4 DD UNIT=SYSDA,SPACE=(TRK,(5,5))
//SYSUT5 DD UNIT=SYSDA,SPACE=(TRK,(5,5))
//SYSUT6 DD UNIT=SYSDA,SPACE=(TRK,(5,5))
//SYSUT7 DD UNIT=SYSDA,SPACE=(TRK,(5,5))
//*
//LKED EXEC PGM=IEWL,PARM='LIST,MAP,RENT',
// COND=(4,LT,COMPILE)
//SYSLIB DD DSN=CEE.SCEELKED,DISP=SHR
//SYSLIN DD DSN=&&OBJMOD,DISP=(OLD,DELETE)
//SYSLMOD DD DSN=BNKAPP.PROD.LOADLIB(BNKPOST0),DISP=SHR
//SYSPRINT DD SYSOUT=*
The three-level SYSLIB concatenation implements the layered library strategy: application-specific copybooks override common copybooks, which override enterprise-wide copybooks.
GnuCOBOL Compile Command
For development and testing with GnuCOBOL:
cobc -x -I ./copybooks -I ../../shared-copybooks bnkpost0.cob
Solution Walkthrough
The key insight of this design is that the copybook is written once and used everywhere, but each program sees it through the lens of its own naming convention. Consider the account balance field:
- In the input file of BNKPOST0, it is
AMIN-CURRENT-BAL - In the working storage of BNKPOST0, it is
WS-ACCT-CURRENT-BAL - In the output file of BNKPOST0, it is
AMOT-CURRENT-BAL - In the CICS inquiry program, it is
WS-ACCT-CURRENT-BAL - In the interest calculation program, it is
CURR-CURRENT-BAL(input) andUPD-CURRENT-BAL(output) - In the regulatory extract, it is
REG-ACCT-CURRENT-BAL
Every one of these names refers to the same field at the same offset within the same 250-byte record structure. If the business decides to change the balance field from PIC S9(13)V99 to PIC S9(15)V99, that change happens in one place -- the BNK-ACCOUNT-RECORD copybook -- and all five programs pick up the change upon recompilation. No manual synchronization is required.
The environment configuration copybook adds another dimension. The same program source code compiles differently depending on the REPLACING values supplied. A development build might use:
COPY BNK-ENV-CONFIG
REPLACING ==:ENV-REGION:== BY =='TEST'==
==:ENV-PROC-DATE:== BY ==20260101==
==:ENV-DB2-SSID:== BY =='DB2T'==
==:ENV-CICS-APPL:== BY =='CICSTEST'==
==:ENV-TRACE:== BY =='Y'==
==:ENV-MAX-ERR:== BY ==9999==.
This injects test-friendly values (trace logging on, high error threshold, test DB2 subsystem) without modifying the copybook or the program logic. The production build uses production values. The source code is identical in both environments.
Results and Impact
After migrating all forty-seven batch programs and twenty-two online programs to the consolidated copybook library, the bank measured the following improvements:
- Record layout definitions reduced from 174 scattered definitions to 3 authoritative copybooks
- Field naming inconsistencies eliminated -- every program now uses the same field names (modulo prefix), making cross-program debugging and impact analysis straightforward
- New program development time reduced by 40% -- developers no longer spend time reverse-engineering record layouts from existing programs
- Copybook change propagation now tracked automatically through the Endevor change management system, which reports exactly which programs require recompilation after any copybook modification
Discussion Questions
-
The design uses short, fixed prefixes (
CUST-,ACCT-,TXNR-) to make COPY REPLACING simple. What problems could arise if a copybook used inconsistent prefixes (some fields starting withCUST-and others withCUSTOMER-)? How would this affect the REPLACING clause? -
The environment configuration copybook uses placeholder tokens (
:ENV-REGION:,:ENV-PROC-DATE:) that are replaced at compile time. What are the advantages and disadvantages of this approach compared to reading configuration values from a file at runtime? -
Program 1 (BNKPOST0) includes the account record copybook three times with different prefixes. If the copybook were 500 bytes instead of 250, how would this affect the program's WORKING-STORAGE usage? At what point would you consider a different design approach?
-
The 46-byte filler in the customer record provides expansion room. What happens when a new field requirement exceeds the available filler space and the record length must change? How would you coordinate this change across all forty-seven programs that use the copybook?
-
The current design requires every program to specify its own REPLACING clauses. Could you design a "master" copybook that nests the three record copybooks with pre-defined REPLACING clauses for common use cases (e.g., a
BNK-ALL-WScopybook that includes all three withWS-prefixes)? What are the trade-offs of this approach?