LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 2118 min read

Reading a COBOL Program

Walk through a short, fully annotated COBOL example so a systems person can confidently read — though not necessarily write — a real COBOL program.

Introduction

The previous lesson introduced COBOL's four-division skeleton conceptually. This lesson puts that structure to work on a real, if small, complete COBOL program, walking through it piece by piece the way an experienced systems person actually would: not memorizing syntax rules, but reading purposefully to answer a practical question — what does this program actually do, what data does it touch, and how does it connect to the JCL that runs it?

A Reading Strategy, Not a Writing Lesson

Reading code and writing code are different skills, and reading is considerably easier to build quickly. The strategy this lesson teaches is deliberately practical: skim the IDENTIFICATION DIVISION for the program's name and purpose, check the ENVIRONMENT DIVISION for which files it touches, scan the DATA DIVISION for the shape of the data involved, and then read the PROCEDURE DIVISION for overall flow before worrying about every individual statement.

The Example Program

Here is a small, complete, and heavily commented COBOL program. It reads daily transaction records, keeps a running total of debit amounts, and writes a one-line summary report. Read it once from top to bottom before the walkthrough that follows.

A complete, annotated example program: DEBITSUM
IDENTIFICATION DIVISION.
PROGRAM-ID. DEBITSUM.
* Summarizes total debit amount from a daily transaction file.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT TRANS-FILE ASSIGN TO TRANIN.
SELECT REPORT-FILE ASSIGN TO RPTOUT.
DATA DIVISION.
FILE SECTION.
FD TRANS-FILE.
01 TRANS-RECORD.
05 TRANS-ACCT PIC 9(10).
05 TRANS-TYPE PIC X(2).
05 TRANS-AMOUNT PIC 9(7)V99.
FD REPORT-FILE.
01 REPORT-LINE PIC X(80).
WORKING-STORAGE SECTION.
01 WS-EOF-SWITCH PIC X VALUE 'N'.
88 END-OF-FILE VALUE 'Y'.
01 WS-DEBIT-TOTAL PIC 9(9)V99 VALUE ZERO.
01 WS-REPORT-LINE.
05 FILLER PIC X(20) VALUE 'TOTAL DEBITS: '.
05 WS-TOTAL-OUT PIC ZZZ,ZZZ,ZZ9.99.
PROCEDURE DIVISION.
0000-MAIN.
OPEN INPUT TRANS-FILE
OUTPUT REPORT-FILE.
PERFORM UNTIL END-OF-FILE
READ TRANS-FILE
AT END
SET END-OF-FILE TO TRUE
NOT AT END
PERFORM 1000-PROCESS-RECORD
END-READ
END-PERFORM.
MOVE WS-DEBIT-TOTAL TO WS-TOTAL-OUT.
WRITE REPORT-LINE FROM WS-REPORT-LINE.
CLOSE TRANS-FILE
REPORT-FILE.
STOP RUN.
1000-PROCESS-RECORD.
IF TRANS-TYPE = 'DR'
ADD TRANS-AMOUNT TO WS-DEBIT-TOTAL
END-IF.

Walking Through IDENTIFICATION and ENVIRONMENT

PROGRAM-ID DEBITSUM tells us the compiled load module will be named DEBITSUM — that is what a JCL EXEC PGM=DEBITSUM statement would reference. The line beginning with an asterisk is a comment, giving a one-line summary of the program's purpose, exactly the kind of thing worth reading first. The ENVIRONMENT DIVISION's two SELECT...ASSIGN clauses tell us immediately that this program touches exactly two files, using the internal names TRANS-FILE and REPORT-FILE, connected to ddnames TRANIN and RPTOUT — so any JCL that runs this program must supply DD statements with exactly those two ddnames.

Walking Through DATA DIVISION

The FILE SECTION tells us the shape of the two files: an incoming transaction record has a 10-digit account number, a 2-character transaction type code, and an amount with 7 digits plus 2 decimal places; the outgoing report is a simple 80-character line. The WORKING-STORAGE SECTION defines the program's internal working variables: an end-of-file switch (using the common COBOL pattern of an 88-level condition name, END-OF-FILE, tied to a value of the switch field), a running debit total, and a formatted report line template with editing characters (the ZZZ,ZZZ,ZZ9.99 picture, which formats the numeric total with commas and suppresses leading zeros for a clean report).

Walking Through PROCEDURE DIVISION

The PROCEDURE DIVISION here is organized into two labeled paragraphs, 0000-MAIN and 1000-PROCESS-RECORD — a very common COBOL convention of naming logical blocks with numbered labels, letting a main control paragraph delegate detail work to smaller, focused ones. 0000-MAIN opens both files, loops through every record in TRANS-FILE using a standard read-until-end-of-file pattern, formats and writes the final total once the loop ends, then closes the files and stops. The actual business rule lives entirely in 1000-PROCESS-RECORD: if a record's transaction type equals 'DR' (debit), its amount is added to the running total; anything else is silently skipped.

The one-sentence summary a systems reader should be able to give

Click Run to see what this code prints.

What to Look For in Any Unfamiliar Program

  • PROGRAM-ID, to know what load module name JCL will reference.
  • Every SELECT...ASSIGN clause in the ENVIRONMENT DIVISION, to know exactly which ddnames the program expects.
  • The FILE SECTION record layouts, to understand the shape of the data flowing in and out.
  • Condition names (88-levels) in WORKING-STORAGE, since they usually name the business-meaningful states a program cares about (like END-OF-FILE here).
  • The overall shape of PROCEDURE DIVISION paragraphs — a main control paragraph plus supporting detail paragraphs is an extremely common pattern.

Common Mistakes

Avoid These Mistakes
  • Trying to read every line in strict top-to-bottom order on a first pass, rather than orienting first (division headers, PROGRAM-ID, SELECT clauses) and then reading PROCEDURE DIVISION for flow.
  • Overlooking 88-level condition names and instead trying to track raw switch values (like 'Y'/'N') directly — the condition name is the readable, intended way to reason about program state.
  • Assuming a numbered paragraph name (1000-PROCESS-RECORD) implies execution order by itself — paragraphs run in the order the PROCEDURE DIVISION logic actually invokes them (via PERFORM), not simply by ascending number.
  • Ignoring FILLER fields in the DATA DIVISION as unimportant — they are often literal text used to build formatted report output, as seen in WS-REPORT-LINE above.

Best Practices

  • Read comments (lines starting with an asterisk in the indicator area) first — they often summarize a program's purpose far faster than the code itself.
  • Build a habit of immediately identifying every SELECT...ASSIGN clause, since that tells you exactly which JCL DD statements a program requires.
  • When a program has multiple PROCEDURE DIVISION paragraphs, sketch the calling relationship (which paragraph performs which) before assuming you understand overall flow.
  • When unsure what a field actually represents, check both its PIC clause and any nearby comments or 88-level names before guessing from the field name alone.

Frequently Asked Questions

It is a condition-name entry that gives a meaningful name to a specific value (or set of values) of another field — for example, tying the name END-OF-FILE to the value 'Y' of a switch field, so the rest of the program can test IF END-OF-FILE instead of comparing raw values directly, which is far more readable.

It is a long-standing COBOL convention for organizing logic into a main control flow paragraph plus smaller, focused detail paragraphs invoked from it, similar in spirit to breaking code into functions in other languages.

No, not for systems-level reading. Knowing roughly what a field represents (a 10-digit account number, a formatted currency amount) is usually enough; exact PIC syntax mastery matters more for someone actually writing or modifying COBOL logic.

Check the ENVIRONMENT DIVISION's SELECT...ASSIGN clauses — each one names the exact ddname the program expects, which must then appear on a DD statement in any JCL that runs it.

Key Takeaways

  • Reading a COBOL program effectively starts with orientation — PROGRAM-ID, SELECT clauses, and FILE SECTION layouts — before diving into detailed logic.
  • The ENVIRONMENT DIVISION's SELECT...ASSIGN clauses directly tell you which ddnames the program's JCL must supply.
  • Condition names (88-levels) make program state readable and are worth learning to recognize even without writing them yourself.
  • PROCEDURE DIVISION logic is commonly organized into a main paragraph that performs smaller, focused detail paragraphs.
  • A systems-level reading goal is a short, accurate summary of what a program does — not line-by-line mastery.

Summary

You have now walked through a complete, if small, COBOL program using a practical, systems-oriented reading strategy — exactly the skill you will keep using every time an unfamiliar PGM= value turns out to be a COBOL program. In the next lesson, you will close the loop on this brief COBOL detour by learning how a COBOL program actually gets from source code to something JCL can run: the compile-link-go pattern.

Next Lesson →

Compiling & Running COBOL on z/OS