Copybooks & Modular Program Design

COBOL Intermediate/Advanced

Chapter 2 · Copybooks & Modular Program Design

Fundamentals' own capstone, TXNBATCH, hand-typed CUSTOMER-RECORD directly into its own DATA DIVISION. Any other real program touching the same customer data — a report writer, a validation subprogram, a nightly reconciliation job — would need that identical layout retyped by hand too. A real COPY statement makes that unnecessary, and genuinely safer.

The Problem COPY Solves

If ten real programs each hand-type their own copy of CUSTOMER-RECORD, and the field CUST-BALANCE ever needs to grow from PIC S9(7)V99 to PIC S9(9)V99, all ten need finding and updating — miss one, and it silently reads or writes the wrong number of bytes the next time it runs.

The COPY Statement: Real Compile-Time Inclusion

A real copybook is just a separate text file holding a fragment of COBOL source. COPY pulls its content directly into the compiling program, at the exact point the statement appears:

FD CUSTOMER-FILE. 01 CUSTOMER-RECORD. COPY CUSTREC.

CUSTREC itself might hold nothing more than:

05 CUST-ID PIC 9(6). 05 CUST-NAME PIC X(30). 05 CUST-BALANCE PIC S9(7)V99.
Genuinely Textual, Not a Runtime Call COPY does its real work entirely at compile time — the copybook's own text is logically substituted directly into the source before the program is ever compiled. This is a fundamentally different real mechanism from Fundamentals' own CALL: there's no separate compiled unit, no runtime linkage, and no positional parameter matching. Once compiled, a program that used COPY looks exactly as if the copybook's own lines had been typed there by hand.

REPLACING: One Copybook, Genuinely Different Field Names

The same real layout is often needed under two different real prefixes — once as an FD record, once as a subprogram's own LINKAGE SECTION item. Real pseudo-text delimiters (==...==) inside the copybook mark exactly what REPLACING should substitute:

01 ==PREFIX==-CUSTOMER-RECORD. 05 ==PREFIX==-CUST-ID PIC 9(6). 05 ==PREFIX==-CUST-NAME PIC X(30). 05 ==PREFIX==-CUST-BALANCE PIC S9(7)V99.
FD CUSTOMER-FILE. COPY CUSTREC REPLACING ==PREFIX== BY ==FD==.

That real inclusion expands to FD-CUSTOMER-RECORD, FD-CUST-ID, and so on. The identical copybook, included elsewhere with a different real substitution:

LINKAGE SECTION. COPY CUSTREC REPLACING ==PREFIX== BY ==LS==.

genuinely expands to LS-CUSTOMER-RECORD, LS-CUST-ID, and the rest — the exact same real field shapes, under whatever prefix each including program actually needs.

Where COPY Can Genuinely Appear

COPY is real anywhere a character string or separator can legally appear in the source — not confined to one division. In real practice it's overwhelmingly used in the DATA DIVISION for shared record layouts, but a real, shared block of PROCEDURE DIVISION logic — a common validation routine, say — can be copied into multiple programs exactly the same way.

A Real, Enforced Constraint A real copybook can't include itself, even indirectly through a chain of other copybooks, until its own inclusion is fully finished — COBOL genuinely prevents a copybook from being named again partway through its own nested inclusion, closing off any real risk of infinite recursive expansion.

Hands-On Exercises

Exercise 1

Using this chapter's own real material, explain in your own words why updating CUST-BALANCE's PICTURE clause inside CUSTREC genuinely fixes every program that used COPY CUSTREC the next time each one is recompiled, without any of those programs' own source files needing to be edited directly.

📄 View solution
Exercise 2

Using this chapter's own real FD-prefix and LS-prefix examples, explain in your own words why both real inclusions can safely coexist across different programs even though they produce genuinely different field names from the exact same copybook file.

📄 View solution
Exercise 3

Using this chapter's own real material, explain in your own words the genuine, structural difference between COPY and CALL — specifically, why a change to a copybook requires every including program to be recompiled, while a change to a real subprogram called via CALL does not require the calling program itself to be recompiled at all.

📄 View solution

Chapter 2 Quick Reference

  • COPY copybook-name. — real compile-time textual substitution; the copybook's own text is logically inserted at that exact point
  • REPLACING ==old== BY ==new== — real pseudo-text substitution, letting one copybook produce genuinely different field names per including program
  • COPY vs. CALL — COPY is text merged in before compilation, with no runtime linkage at all; CALL is a real, separately compiled unit linked at runtime
  • Legal locations — anywhere a character string/separator can appear; overwhelmingly used in DATA DIVISION, also valid in PROCEDURE DIVISION
  • Real constraint — a copybook can't be named again inside its own nested inclusion chain until that inclusion finishes, blocking recursive expansion