The General Ledger (GL) is the financial backbone of every organization. It is the single authoritative repository of all financial transactions, the source from which financial statements are produced, and the foundation upon which management...
In This Chapter
- Introduction
- 36.1 Double-Entry Bookkeeping in COBOL
- 36.2 General Ledger System Architecture
- 36.3 Chart of Accounts
- 36.4 Journal Entry Processing
- 36.5 General Ledger Master File
- 36.6 Financial Reporting
- 36.7 Period-End Processing
- 36.8 Subledger Integration
- 36.9 Audit Trail Requirements
- 36.10 COBOL Data Structures for Accounting
- 36.11 Batch Processing for GL
- 36.12 Report Formatting for Financial Statements
- 36.13 Currency and Multi-Company Considerations
- 36.14 Common GL Programming Patterns in COBOL
- 36.15 Summary
Chapter 36: Accounting and General Ledger Systems
Introduction
The General Ledger (GL) is the financial backbone of every organization. It is the single authoritative repository of all financial transactions, the source from which financial statements are produced, and the foundation upon which management decisions, regulatory filings, and audit opinions rest. For decades, COBOL has been the dominant language powering General Ledger systems at banks, insurance companies, hospitals, manufacturers, government agencies, and Fortune 500 corporations worldwide.
This chapter covers the complete lifecycle of a General Ledger system implemented in COBOL: from designing a chart of accounts and processing journal entries, through period-end closing procedures, to generating the financial statements that stakeholders rely upon. You will learn the fundamental accounting principles that drive system design, the COBOL data structures that model financial data, and the batch processing patterns that keep these systems running reliably night after night.
Whether you are maintaining a legacy GL system or building interfaces to modern ERP platforms, understanding how General Ledger processing works in COBOL is essential knowledge for any enterprise developer.
36.1 Double-Entry Bookkeeping in COBOL
The Foundation of All Accounting Systems
Double-entry bookkeeping, formalized by Luca Pacioli in 1494, remains the foundation of every accounting system ever built. The principle is simple yet powerful: every financial transaction must be recorded with at least two entries -- one debit and one credit -- and the total debits must always equal the total credits.
This fundamental rule provides a built-in error-detection mechanism. If debits do not equal credits, something has gone wrong. COBOL systems enforce this rule at the journal entry level, at the batch level, and at the period level.
THE ACCOUNTING EQUATION:
Assets = Liabilities + Equity
Expanded:
Assets = Liabilities + Equity + Revenue - Expenses
Every transaction maintains this equation in balance.
Debit and Credit Rules
The terms "debit" and "credit" have specific meanings that differ by account type:
| Account Type | Normal Balance | Increased By | Decreased By |
|---|---|---|---|
| Assets | Debit | Debit | Credit |
| Liabilities | Credit | Credit | Debit |
| Equity | Credit | Credit | Debit |
| Revenue | Credit | Credit | Debit |
| Expenses | Debit | Debit | Credit |
In COBOL, we typically represent this with a sign convention or a debit/credit indicator:
01 WS-JOURNAL-LINE.
05 WS-JL-ACCOUNT PIC X(10).
05 WS-JL-DC-IND PIC X(01).
88 JL-DEBIT VALUE 'D'.
88 JL-CREDIT VALUE 'C'.
05 WS-JL-AMOUNT PIC S9(13)V99.
Enforcing Balance in COBOL
Every journal entry batch must balance. The validation logic is straightforward but critical:
VALIDATE-JOURNAL-BALANCE.
MOVE ZEROS TO WS-TOTAL-DEBITS
WS-TOTAL-CREDITS
PERFORM VARYING WS-LINE-IDX FROM 1 BY 1
UNTIL WS-LINE-IDX > WS-LINE-COUNT
IF JL-DEBIT(WS-LINE-IDX)
ADD WS-JL-AMOUNT(WS-LINE-IDX)
TO WS-TOTAL-DEBITS
ELSE
ADD WS-JL-AMOUNT(WS-LINE-IDX)
TO WS-TOTAL-CREDITS
END-IF
END-PERFORM
IF WS-TOTAL-DEBITS NOT = WS-TOTAL-CREDITS
SET WS-ENTRY-OUT-OF-BALANCE TO TRUE
COMPUTE WS-DIFFERENCE =
WS-TOTAL-DEBITS - WS-TOTAL-CREDITS
END-IF.
36.2 General Ledger System Architecture
High-Level Architecture
A complete General Ledger system consists of several interconnected components:
+-------------------+ +-------------------+ +------------------+
| SUBLEDGERS | | JOURNAL ENTRY | | CHART OF |
| | | PROCESSING | | ACCOUNTS |
| - Accounts Pay. |--->| |<---| MAINTENANCE |
| - Accounts Rec. | | - Validation | | |
| - Payroll | | - Balancing | | - Account CRUD |
| - Fixed Assets | | - Posting | | - Hierarchy |
| - Inventory | | | | - Mapping |
+-------------------+ +--------+----------+ +------------------+
|
v
+--------+----------+
| GENERAL LEDGER |
| MASTER FILE |
| |
| - Account Balances|
| - Period Totals |
| - Budget Data |
| - History |
+---------+---------+
|
+--------------+--------------+
| | |
v v v
+-------+----+ +------+-----+ +-----+------+
| TRIAL | | FINANCIAL | | PERIOD-END |
| BALANCE | | STATEMENTS | | PROCESSING |
| | | | | |
| - Detail | | - Income | | - Close |
| - Summary | | Statement| | - Accrue |
| - Adjusted | | - Balance | | - Reverse |
| | | Sheet | | - Carry Fwd|
+------------+ | - Cash Flow| +------------+
+------------+
Batch Processing Model
Most GL systems operate on a batch processing model, which aligns naturally with COBOL's strengths:
- Daily processing: Journal entries are collected throughout the day (from subledgers, manual entry, automated interfaces) and posted to the GL in an evening batch run.
- Monthly processing: At month-end, accruals are generated, depreciation is calculated, the period is closed, and financial statements are produced.
- Annual processing: Revenue and expense accounts are closed to retained earnings, and opening balances for the new year are established.
File Organization
A typical GL system uses these key files:
| File | Organization | Key | Purpose |
|---|---|---|---|
| Chart of Accounts | VSAM KSDS | Account Number | Account master data |
| GL Master | VSAM KSDS | Company + Account + Period | Balances and activity |
| Journal Entry | Sequential | Entry Number | Transaction input |
| Journal History | VSAM KSDS | Entry Number | Posted transactions |
| Budget Master | VSAM KSDS | Company + Account + Period | Budget amounts |
| Period Control | VSAM KSDS | Company + Period | Open/closed status |
36.3 Chart of Accounts
Account Numbering Schemes
The chart of accounts is the classification system for all financial transactions. A well-designed account numbering scheme is critical for accurate reporting and analysis. Most organizations use a hierarchical numbering system:
ACCOUNT NUMBER STRUCTURE:
XXXX-XXX-XXXX-XX
| | | |
| | | +-- Sub-account (optional detail)
| | +------- Cost Center / Department
| +----------- Natural Account
+---------------- Company Code
Example:
0100-4100-3200-00
| | | |
| | | +-- Default sub-account
| | +------- Marketing Department
| +----------- Travel & Entertainment
+---------------- North American Operations
Account Types
Accounts are classified into five fundamental types, each mapping to a position on the financial statements:
Balance Sheet Accounts (Permanent): - Assets (1000-1999): Resources owned by the organization. Examples: Cash (1010), Accounts Receivable (1200), Equipment (1500), Accumulated Depreciation (1510). - Liabilities (2000-2999): Obligations owed to others. Examples: Accounts Payable (2100), Accrued Expenses (2200), Long-term Debt (2500). - Equity (3000-3999): Owners' residual interest. Examples: Common Stock (3100), Retained Earnings (3200), Current Year Earnings (3900).
Income Statement Accounts (Temporary): - Revenue (4000-4999): Income earned. Examples: Product Sales (4100), Service Revenue (4200), Interest Income (4500). - Expenses (5000-9999): Costs incurred. Examples: Salaries (5100), Rent (5200), Depreciation (5300), Cost of Goods Sold (6000).
COBOL Record Structure for Chart of Accounts
01 COA-RECORD.
05 COA-ACCOUNT-KEY.
10 COA-COMPANY PIC X(04).
10 COA-NATURAL-ACCT PIC X(04).
10 COA-COST-CENTER PIC X(04).
10 COA-SUB-ACCOUNT PIC X(02).
05 COA-DESCRIPTION PIC X(40).
05 COA-SHORT-DESC PIC X(15).
05 COA-ACCOUNT-TYPE PIC X(01).
88 COA-ASSET VALUE 'A'.
88 COA-LIABILITY VALUE 'L'.
88 COA-EQUITY VALUE 'E'.
88 COA-REVENUE VALUE 'R'.
88 COA-EXPENSE VALUE 'X'.
05 COA-NORMAL-BALANCE PIC X(01).
88 COA-NORMAL-DEBIT VALUE 'D'.
88 COA-NORMAL-CREDIT VALUE 'C'.
05 COA-STATUS PIC X(01).
88 COA-ACTIVE VALUE 'A'.
88 COA-INACTIVE VALUE 'I'.
88 COA-FROZEN VALUE 'F'.
05 COA-PARENT-ACCOUNT PIC X(14).
05 COA-ROLLUP-LEVEL PIC 9(02).
05 COA-POSTING-ALLOWED PIC X(01).
88 COA-POSTABLE VALUE 'Y'.
88 COA-SUMMARY-ONLY VALUE 'N'.
05 COA-BUDGET-REQUIRED PIC X(01).
05 COA-SUBLEDGER-TYPE PIC X(02).
88 COA-NO-SUBLEDGER VALUE SPACES.
88 COA-AP-CONTROL VALUE 'AP'.
88 COA-AR-CONTROL VALUE 'AR'.
88 COA-FA-CONTROL VALUE 'FA'.
88 COA-PY-CONTROL VALUE 'PY'.
05 COA-CREATED-DATE PIC 9(08).
05 COA-CREATED-BY PIC X(08).
05 COA-MODIFIED-DATE PIC 9(08).
05 COA-MODIFIED-BY PIC X(08).
05 FILLER PIC X(20).
Account Hierarchy and Roll-Up
Financial reporting requires the ability to summarize accounts at multiple levels. For example, total "Office Supplies" for the Marketing department, then total all Marketing expenses, then total all expenses for the North American company.
The hierarchy is typically implemented through parent-child relationships in the chart of accounts:
Level 1: 0100-5000-0000-00 Total Expenses (Company 0100)
Level 2: 0100-5100-0000-00 Salary Expenses (All Departments)
Level 3: 0100-5100-3200-00 Salary Expenses (Marketing)
Level 3: 0100-5100-3300-00 Salary Expenses (Engineering)
Level 3: 0100-5100-3400-00 Salary Expenses (Finance)
Level 2: 0100-5200-0000-00 Facilities Expenses (All Departments)
Level 3: 0100-5200-3200-00 Facilities (Marketing)
...
The roll-up process in COBOL reads detail-level accounts and accumulates balances upward through the hierarchy using the parent account pointer stored in each account record.
Natural Account vs. Cost Center vs. Department Coding
The segmented account number separates different dimensions of financial data:
- Natural Account: What type of transaction is it? (Salary, Rent, Revenue)
- Cost Center: Where did it occur? (Building A, Plant 3, Region East)
- Department: Who is responsible? (Marketing, Engineering, Finance)
This segmentation allows flexible reporting: you can report on all salary expenses across the company, all expenses for a single department, or a specific expense type for a specific department.
36.4 Journal Entry Processing
Journal Entry Structure
A journal entry consists of a header and one or more lines. The header identifies the entry; the lines specify the accounts and amounts:
01 JE-HEADER-RECORD.
05 JE-ENTRY-NUMBER PIC 9(10).
05 JE-COMPANY PIC X(04).
05 JE-JOURNAL-CODE PIC X(03).
88 JE-GENERAL-JRNL VALUE 'GJ '.
88 JE-CASH-RECEIPTS VALUE 'CR '.
88 JE-CASH-DISBMNT VALUE 'CD '.
88 JE-PAYROLL-JRNL VALUE 'PY '.
88 JE-AP-JRNL VALUE 'AP '.
88 JE-AR-JRNL VALUE 'AR '.
88 JE-ADJ-JRNL VALUE 'AJ '.
05 JE-ENTRY-DATE PIC 9(08).
05 JE-PERIOD PIC 9(02).
05 JE-FISCAL-YEAR PIC 9(04).
05 JE-DESCRIPTION PIC X(40).
05 JE-SOURCE-REF PIC X(20).
05 JE-ENTRY-TYPE PIC X(01).
88 JE-STANDARD VALUE 'S'.
88 JE-RECURRING VALUE 'R'.
88 JE-AUTO-REVERSE VALUE 'A'.
88 JE-STATISTICAL VALUE 'T'.
05 JE-STATUS PIC X(01).
88 JE-PENDING VALUE 'P'.
88 JE-APPROVED VALUE 'A'.
88 JE-POSTED VALUE 'D'.
88 JE-REJECTED VALUE 'R'.
88 JE-REVERSED VALUE 'V'.
05 JE-LINE-COUNT PIC 9(04).
05 JE-TOTAL-DEBITS PIC S9(13)V99.
05 JE-TOTAL-CREDITS PIC S9(13)V99.
05 JE-ENTERED-BY PIC X(08).
05 JE-ENTERED-DATE PIC 9(08).
05 JE-APPROVED-BY PIC X(08).
05 JE-APPROVED-DATE PIC 9(08).
05 JE-POSTED-BY PIC X(08).
05 JE-POSTED-DATE PIC 9(08).
01 JE-LINE-RECORD.
05 JE-LN-ENTRY-NUMBER PIC 9(10).
05 JE-LN-LINE-NUMBER PIC 9(04).
05 JE-LN-ACCOUNT.
10 JE-LN-COMPANY PIC X(04).
10 JE-LN-NATURAL PIC X(04).
10 JE-LN-COST-CTR PIC X(04).
10 JE-LN-SUB-ACCT PIC X(02).
05 JE-LN-DC-IND PIC X(01).
88 JE-LN-DEBIT VALUE 'D'.
88 JE-LN-CREDIT VALUE 'C'.
05 JE-LN-AMOUNT PIC S9(13)V99.
05 JE-LN-DESCRIPTION PIC X(30).
05 JE-LN-REFERENCE PIC X(20).
Journal Entry Validation
Before a journal entry can be posted, it must pass several validation checks:
- Balance check: Total debits must equal total credits.
- Account validation: Every account referenced must exist in the chart of accounts and must be active and postable.
- Period validation: The posting period must be open for the specified company.
- Amount validation: No zero-amount lines; amounts must be positive (the debit/credit indicator determines the direction).
- Authorization check: The entry must be approved if the amount exceeds the submitter's authorization limit.
- Cross-company check: If lines span multiple companies, intercompany accounts must be used.
VALIDATE-JOURNAL-ENTRY.
SET WS-VALID TO TRUE
* CHECK 1: ENTRY MUST BALANCE
IF JE-TOTAL-DEBITS NOT = JE-TOTAL-CREDITS
STRING 'Entry ' JE-ENTRY-NUMBER
' out of balance by '
WS-DIFFERENCE
DELIMITED BY SIZE
INTO WS-ERROR-MSG
PERFORM WRITE-ERROR-RECORD
SET WS-INVALID TO TRUE
END-IF
* CHECK 2: VALIDATE EACH LINE ACCOUNT
PERFORM VARYING WS-IDX FROM 1 BY 1
UNTIL WS-IDX > JE-LINE-COUNT
MOVE JE-LN-ACCOUNT(WS-IDX) TO COA-ACCOUNT-KEY
READ CHART-OF-ACCOUNTS-FILE
KEY IS COA-ACCOUNT-KEY
INVALID KEY
STRING 'Line ' WS-IDX
' invalid account '
JE-LN-ACCOUNT(WS-IDX)
DELIMITED BY SIZE
INTO WS-ERROR-MSG
PERFORM WRITE-ERROR-RECORD
SET WS-INVALID TO TRUE
END-READ
IF WS-VALID
IF NOT COA-ACTIVE
STRING 'Line ' WS-IDX
' account inactive'
DELIMITED BY SIZE
INTO WS-ERROR-MSG
PERFORM WRITE-ERROR-RECORD
SET WS-INVALID TO TRUE
END-IF
IF COA-SUMMARY-ONLY
STRING 'Line ' WS-IDX
' account not postable'
DELIMITED BY SIZE
INTO WS-ERROR-MSG
PERFORM WRITE-ERROR-RECORD
SET WS-INVALID TO TRUE
END-IF
END-IF
END-PERFORM
* CHECK 3: VALIDATE POSTING PERIOD
PERFORM CHECK-PERIOD-STATUS
.
Auto-Reversing Entries
Auto-reversing entries are accruals that are automatically reversed on the first day of the next period. This is a common accounting practice: accrue an expense at month-end, then reverse it in the next month when the actual invoice is received.
PROCESS-AUTO-REVERSALS.
OPEN INPUT JOURNAL-HISTORY-FILE
OPEN OUTPUT REVERSAL-OUTPUT-FILE
PERFORM UNTIL WS-EOF-HISTORY
READ JOURNAL-HISTORY-FILE
AT END SET WS-EOF-HISTORY TO TRUE
END-READ
IF NOT WS-EOF-HISTORY
IF JH-AUTO-REVERSE AND
JH-STATUS = 'D' AND
JH-PERIOD = WS-PRIOR-PERIOD
PERFORM CREATE-REVERSAL-ENTRY
END-IF
END-IF
END-PERFORM
CLOSE JOURNAL-HISTORY-FILE
REVERSAL-OUTPUT-FILE
.
CREATE-REVERSAL-ENTRY.
ADD 1 TO WS-REVERSAL-COUNT
MOVE JH-ENTRY-NUMBER TO WS-REV-ORIG-ENTRY
MOVE WS-CURRENT-PERIOD TO WS-REV-PERIOD
MOVE WS-CURRENT-DATE TO WS-REV-DATE
* SWAP DEBITS AND CREDITS
PERFORM VARYING WS-IDX FROM 1 BY 1
UNTIL WS-IDX > JH-LINE-COUNT
IF JH-LN-DC-IND(WS-IDX) = 'D'
MOVE 'C' TO WS-REV-DC-IND(WS-IDX)
ELSE
MOVE 'D' TO WS-REV-DC-IND(WS-IDX)
END-IF
MOVE JH-LN-AMOUNT(WS-IDX)
TO WS-REV-AMOUNT(WS-IDX)
MOVE JH-LN-ACCOUNT(WS-IDX)
TO WS-REV-ACCOUNT(WS-IDX)
END-PERFORM
PERFORM WRITE-REVERSAL-RECORD
.
Recurring Entries
Recurring entries are templates that generate the same journal entry each period. Examples include monthly rent expense, insurance amortization, or fixed depreciation:
PROCESS-RECURRING-ENTRIES.
OPEN INPUT RECURRING-TEMPLATE-FILE
OPEN OUTPUT GENERATED-JE-FILE
PERFORM UNTIL WS-EOF-TEMPLATES
READ RECURRING-TEMPLATE-FILE
AT END SET WS-EOF-TEMPLATES TO TRUE
END-READ
IF NOT WS-EOF-TEMPLATES
IF RT-ACTIVE AND
WS-CURRENT-PERIOD >= RT-START-PERIOD AND
(RT-END-PERIOD = ZEROS OR
WS-CURRENT-PERIOD <= RT-END-PERIOD)
PERFORM GENERATE-FROM-TEMPLATE
ADD 1 TO WS-RECURRING-COUNT
END-IF
END-IF
END-PERFORM
.
Batch vs. Real-Time Posting
Traditional COBOL GL systems use batch posting, where journal entries are accumulated and posted in a scheduled batch run. This approach offers several advantages:
- Atomicity: The entire batch either posts or rolls back.
- Audit trail: A complete posting run report is produced.
- Performance: Batch processing optimizes I/O by processing records sequentially.
- Control: Management can review and approve entries before posting.
The posting process reads validated journal entries and updates the GL master file:
POST-JOURNAL-ENTRY.
PERFORM VARYING WS-IDX FROM 1 BY 1
UNTIL WS-IDX > JE-LINE-COUNT
MOVE JE-LN-ACCOUNT(WS-IDX) TO GL-ACCOUNT-KEY
MOVE JE-PERIOD TO GL-PERIOD
READ GL-MASTER-FILE
KEY IS GL-FULL-KEY
INVALID KEY
PERFORM INITIALIZE-GL-RECORD
END-READ
IF JE-LN-DEBIT(WS-IDX)
ADD JE-LN-AMOUNT(WS-IDX) TO GL-MTD-DEBITS
ELSE
ADD JE-LN-AMOUNT(WS-IDX) TO GL-MTD-CREDITS
END-IF
COMPUTE GL-MTD-NET =
GL-MTD-DEBITS - GL-MTD-CREDITS
ADD JE-LN-AMOUNT(WS-IDX) TO GL-YTD-BALANCE
REWRITE GL-MASTER-RECORD
INVALID KEY
PERFORM GL-REWRITE-ERROR
END-REWRITE
ADD 1 TO WS-LINES-POSTED
END-PERFORM
MOVE 'D' TO JE-STATUS
MOVE WS-CURRENT-DATE TO JE-POSTED-DATE
.
36.5 General Ledger Master File
GL Account Record Structure
The GL master file is the central repository of account balances. Each record typically holds all period balances for one account in one fiscal year, using the OCCURS clause to store 13 periods (12 calendar months plus an adjustment period):
01 GL-MASTER-RECORD.
05 GL-FULL-KEY.
10 GL-COMPANY PIC X(04).
10 GL-ACCOUNT-NUM PIC X(10).
10 GL-FISCAL-YEAR PIC 9(04).
05 GL-ACCOUNT-DESC PIC X(40).
05 GL-ACCOUNT-TYPE PIC X(01).
05 GL-NORMAL-BALANCE PIC X(01).
05 GL-BEGINNING-BALANCE PIC S9(13)V99.
05 GL-PERIOD-DATA OCCURS 13 TIMES.
10 GL-PRD-DEBITS PIC S9(13)V99.
10 GL-PRD-CREDITS PIC S9(13)V99.
10 GL-PRD-NET PIC S9(13)V99.
10 GL-PRD-END-BAL PIC S9(13)V99.
10 GL-PRD-BUDGET PIC S9(13)V99.
10 GL-PRD-STATUS PIC X(01).
88 GL-PRD-OPEN VALUE 'O'.
88 GL-PRD-CLOSED VALUE 'C'.
88 GL-PRD-LOCKED VALUE 'L'.
05 GL-YTD-DEBITS PIC S9(13)V99.
05 GL-YTD-CREDITS PIC S9(13)V99.
05 GL-YTD-NET PIC S9(13)V99.
05 GL-ENDING-BALANCE PIC S9(13)V99.
05 GL-LAST-ACTIVITY-DATE PIC 9(08).
05 GL-LAST-ACTIVITY-PRD PIC 9(02).
Period Balances: 13 Periods
The use of 13 periods is a standard practice in GL systems:
- Periods 01-12: Correspond to the twelve calendar months (or fiscal periods).
- Period 13: The adjustment period, used for year-end audit adjustments that should not affect any specific month's reporting.
This design allows auditors to post adjustments after the regular December close without disturbing the monthly statements that have already been distributed to management.
Budget vs. Actual Amounts
Many GL systems store budget data alongside actual data, enabling variance reporting:
COMPUTE-BUDGET-VARIANCE.
COMPUTE WS-VARIANCE =
GL-PRD-BUDGET(WS-PERIOD) -
GL-PRD-NET(WS-PERIOD)
IF GL-PRD-BUDGET(WS-PERIOD) NOT = ZEROS
COMPUTE WS-VARIANCE-PCT =
(WS-VARIANCE /
GL-PRD-BUDGET(WS-PERIOD)) * 100
ELSE
MOVE ZEROS TO WS-VARIANCE-PCT
END-IF
.
Year-to-Date and Month-to-Date Totals
GL systems maintain both MTD and YTD totals. The YTD balance is the running accumulation from period 1 through the current period. For balance sheet accounts, the YTD balance represents the account's current balance. For income statement accounts, the YTD balance represents activity since the start of the fiscal year.
CALCULATE-YTD-BALANCE.
MOVE GL-BEGINNING-BALANCE TO WS-RUNNING-BALANCE
PERFORM VARYING WS-PRD FROM 1 BY 1
UNTIL WS-PRD > WS-CURRENT-PERIOD
ADD GL-PRD-NET(WS-PRD) TO WS-RUNNING-BALANCE
END-PERFORM
MOVE WS-RUNNING-BALANCE TO GL-ENDING-BALANCE
.
36.6 Financial Reporting
Trial Balance Generation
The trial balance is the most fundamental GL report. It lists every account with its balance, and the total of all debit balances must equal the total of all credit balances. A trial balance that does not balance indicates a system error.
There are three types of trial balance:
- Unadjusted Trial Balance: Prepared before any adjusting entries.
- Adjusted Trial Balance: Prepared after adjusting entries but before closing entries.
- Post-Closing Trial Balance: Prepared after closing entries; includes only balance sheet accounts.
The trial balance report in COBOL reads the GL master file sequentially and accumulates totals:
GENERATE-TRIAL-BALANCE.
OPEN INPUT GL-MASTER-FILE
OPEN OUTPUT TRIAL-BALANCE-REPORT
PERFORM PRINT-TB-HEADERS
MOVE ZEROS TO WS-TOTAL-DR-BALANCES
WS-TOTAL-CR-BALANCES
PERFORM UNTIL WS-EOF-GL
READ GL-MASTER-FILE
AT END SET WS-EOF-GL TO TRUE
END-READ
IF NOT WS-EOF-GL
PERFORM CALCULATE-ACCOUNT-BALANCE
IF WS-ACCOUNT-BALANCE > ZEROS
ADD WS-ACCOUNT-BALANCE
TO WS-TOTAL-DR-BALANCES
MOVE WS-ACCOUNT-BALANCE
TO WS-TB-DEBIT-AMT
MOVE SPACES TO WS-TB-CREDIT-AMT
ELSE
COMPUTE WS-ABS-BALANCE =
WS-ACCOUNT-BALANCE * -1
ADD WS-ABS-BALANCE
TO WS-TOTAL-CR-BALANCES
MOVE SPACES TO WS-TB-DEBIT-AMT
MOVE WS-ABS-BALANCE
TO WS-TB-CREDIT-AMT
END-IF
PERFORM PRINT-TB-DETAIL-LINE
END-IF
END-PERFORM
PERFORM PRINT-TB-TOTALS
.
Income Statement (Profit and Loss)
The income statement reports revenue and expenses for a period, showing net income or loss. In COBOL, this typically involves:
- Reading all revenue accounts (type 'R') and expense accounts (type 'X').
- Grouping them by category.
- Computing subtotals for major categories.
- Computing net income (total revenue minus total expenses).
REGIONAL HOSPITAL NETWORK
INCOME STATEMENT
FOR THE PERIOD ENDING DECEMBER 31, 2025
REVENUE:
Patient Services Revenue $12,450,000.00
Laboratory Revenue $2,180,000.00
Pharmacy Revenue $3,240,000.00
Grant Revenue $890,000.00
--------------
TOTAL REVENUE $18,760,000.00
EXPENSES:
Salaries and Wages $8,920,000.00
Benefits $2,670,000.00
Medical Supplies $1,850,000.00
Depreciation $960,000.00
Utilities $480,000.00
Insurance $720,000.00
Other Operating Expenses $890,000.00
--------------
TOTAL EXPENSES $16,490,000.00
==============
NET INCOME $2,270,000.00
Balance Sheet
The balance sheet reports the financial position at a point in time. It lists assets, liabilities, and equity, demonstrating that the accounting equation holds:
GENERATE-BALANCE-SHEET.
MOVE ZEROS TO WS-TOTAL-ASSETS
WS-TOTAL-LIABILITIES
WS-TOTAL-EQUITY
PERFORM PROCESS-ASSET-ACCOUNTS
PERFORM PROCESS-LIABILITY-ACCOUNTS
PERFORM PROCESS-EQUITY-ACCOUNTS
* VERIFY THE ACCOUNTING EQUATION
COMPUTE WS-CHECK-TOTAL =
WS-TOTAL-LIABILITIES + WS-TOTAL-EQUITY
IF WS-TOTAL-ASSETS NOT = WS-CHECK-TOTAL
PERFORM BALANCE-SHEET-ERROR
END-IF
PERFORM FORMAT-BALANCE-SHEET-REPORT
.
Cash Flow Statement (Indirect Method)
The cash flow statement reconciles net income to the change in cash, categorized into operating, investing, and financing activities. The indirect method starts with net income and adjusts for non-cash items:
CASH FLOWS FROM OPERATING ACTIVITIES:
Net Income $2,270,000.00
Adjustments:
Depreciation $960,000.00
Increase in Accounts Receivable ($340,000.00)
Decrease in Inventory $120,000.00
Increase in Accounts Payable $210,000.00
--------------
NET CASH FROM OPERATIONS $3,220,000.00
CASH FLOWS FROM INVESTING ACTIVITIES:
Purchase of Equipment ($1,800,000.00)
Sale of Investments $500,000.00
--------------
NET CASH FROM INVESTING ($1,300,000.00)
CASH FLOWS FROM FINANCING ACTIVITIES:
Proceeds from Long-term Debt $1,000,000.00
Repayment of Notes Payable ($400,000.00)
--------------
NET CASH FROM FINANCING $600,000.00
==============
NET INCREASE IN CASH $2,520,000.00
BEGINNING CASH BALANCE $4,100,000.00
ENDING CASH BALANCE $6,620,000.00
Departmental and Divisional Reporting
The segmented account structure enables reporting at any organizational level. The COBOL program reads GL records and aggregates by the desired segment:
PROCESS-DEPARTMENTAL-REPORT.
MOVE GL-COST-CENTER TO WS-CURRENT-DEPT
PERFORM UNTIL WS-EOF-GL OR
GL-COST-CENTER NOT = WS-CURRENT-DEPT
ADD GL-PRD-NET(WS-PERIOD)
TO WS-DEPT-TOTAL
READ GL-MASTER-FILE
AT END SET WS-EOF-GL TO TRUE
END-READ
END-PERFORM
PERFORM PRINT-DEPT-SUBTOTAL
.
36.7 Period-End Processing
Month-End Close Procedures
The month-end close is a carefully orchestrated sequence of steps:
- Verify all subledger postings are complete (AP, AR, Payroll, etc.).
- Generate and post recurring entries (rent, insurance amortization).
- Calculate and post depreciation.
- Generate and post accruals (accrued salaries, accrued interest).
- Post any manual adjusting entries.
- Generate the trial balance and verify it balances.
- Produce financial statements.
- Close the period (change period status from Open to Closed).
- Generate auto-reversals for the next period.
- Archive transaction detail if needed.
PERFORM-MONTH-END-CLOSE.
PERFORM VERIFY-SUBLEDGER-POSTINGS
PERFORM PROCESS-RECURRING-ENTRIES
PERFORM CALCULATE-DEPRECIATION
PERFORM GENERATE-ACCRUALS
PERFORM POST-ADJUSTING-ENTRIES
PERFORM GENERATE-TRIAL-BALANCE
IF WS-TB-BALANCED
PERFORM GENERATE-FINANCIAL-STMTS
PERFORM CLOSE-CURRENT-PERIOD
PERFORM GENERATE-AUTO-REVERSALS
PERFORM ARCHIVE-PERIOD-DETAIL
DISPLAY 'MONTH-END CLOSE COMPLETE FOR PERIOD '
WS-CURRENT-PERIOD
ELSE
DISPLAY 'TRIAL BALANCE OUT OF BALANCE - '
'CLOSE ABORTED'
MOVE 8 TO RETURN-CODE
END-IF
.
Accruals and Deferrals
Accruals recognize revenue earned or expenses incurred but not yet recorded (e.g., wages earned by employees but not yet paid). Deferrals recognize that cash received or paid relates to future periods (e.g., prepaid insurance).
GENERATE-ACCRUALS.
OPEN INPUT ACCRUAL-TEMPLATE-FILE
OPEN OUTPUT ACCRUAL-JE-FILE
PERFORM UNTIL WS-EOF-TEMPLATES
READ ACCRUAL-TEMPLATE-FILE
AT END SET WS-EOF-TEMPLATES TO TRUE
END-READ
IF NOT WS-EOF-TEMPLATES
EVALUATE AT-TYPE
WHEN 'SALARY'
PERFORM CALCULATE-SALARY-ACCRUAL
WHEN 'INTEREST'
PERFORM CALCULATE-INTEREST-ACCRUAL
WHEN 'FIXED'
PERFORM GENERATE-FIXED-ACCRUAL
WHEN OTHER
PERFORM LOG-UNKNOWN-ACCRUAL-TYPE
END-EVALUATE
END-IF
END-PERFORM
.
Depreciation Posting
Depreciation is calculated by the Fixed Assets subledger and posted to the GL as a journal entry:
CALCULATE-DEPRECIATION.
* DEBIT DEPRECIATION EXPENSE,
* CREDIT ACCUMULATED DEPRECIATION
MOVE WS-DEPR-EXPENSE-ACCT TO JE-LN-ACCOUNT(1)
MOVE 'D' TO JE-LN-DC-IND(1)
MOVE WS-MONTHLY-DEPR TO JE-LN-AMOUNT(1)
MOVE WS-ACCUM-DEPR-ACCT TO JE-LN-ACCOUNT(2)
MOVE 'C' TO JE-LN-DC-IND(2)
MOVE WS-MONTHLY-DEPR TO JE-LN-AMOUNT(2)
.
Intercompany Eliminations
When a parent company consolidates financial statements with subsidiaries, intercompany transactions must be eliminated to avoid double-counting:
GENERATE-IC-ELIMINATIONS.
OPEN INPUT IC-TRANSACTION-FILE
OPEN OUTPUT IC-ELIMINATION-JE
PERFORM UNTIL WS-EOF-IC
READ IC-TRANSACTION-FILE
AT END SET WS-EOF-IC TO TRUE
END-READ
IF NOT WS-EOF-IC
* REVERSE THE INTERCOMPANY SALE
MOVE IC-REVENUE-ACCT TO JE-LN-ACCOUNT(1)
MOVE 'D' TO JE-LN-DC-IND(1)
MOVE IC-AMOUNT TO JE-LN-AMOUNT(1)
* REVERSE THE INTERCOMPANY PURCHASE
MOVE IC-EXPENSE-ACCT TO JE-LN-ACCOUNT(2)
MOVE 'C' TO JE-LN-DC-IND(2)
MOVE IC-AMOUNT TO JE-LN-AMOUNT(2)
PERFORM WRITE-IC-ELIMINATION
END-IF
END-PERFORM
.
Year-End Close
The year-end close is the most significant period-end process. It involves closing all revenue and expense (temporary) accounts to Retained Earnings:
PERFORM-YEAR-END-CLOSE.
MOVE ZEROS TO WS-NET-INCOME
PERFORM CLOSE-REVENUE-ACCOUNTS
PERFORM CLOSE-EXPENSE-ACCOUNTS
* POST NET INCOME TO RETAINED EARNINGS
MOVE WS-RETAINED-EARNINGS-ACCT
TO JE-LN-ACCOUNT(1)
IF WS-NET-INCOME >= ZEROS
MOVE 'C' TO JE-LN-DC-IND(1)
MOVE WS-NET-INCOME TO JE-LN-AMOUNT(1)
ELSE
MOVE 'D' TO JE-LN-DC-IND(1)
COMPUTE JE-LN-AMOUNT(1) =
WS-NET-INCOME * -1
END-IF
PERFORM POST-CLOSING-ENTRY
PERFORM CREATE-OPENING-BALANCES
.
CLOSE-REVENUE-ACCOUNTS.
PERFORM UNTIL WS-EOF-GL
READ GL-MASTER-FILE
AT END SET WS-EOF-GL TO TRUE
END-READ
IF NOT WS-EOF-GL AND GL-ACCOUNT-TYPE = 'R'
ADD GL-ENDING-BALANCE TO WS-NET-INCOME
* DEBIT REVENUE TO CLOSE IT
MOVE GL-ACCOUNT-NUM TO JE-LN-ACCOUNT(1)
MOVE 'D' TO JE-LN-DC-IND(1)
MOVE GL-ENDING-BALANCE
TO JE-LN-AMOUNT(1)
PERFORM POST-CLOSING-LINE
END-IF
END-PERFORM
.
CREATE-OPENING-BALANCES.
* FOR BALANCE SHEET ACCOUNTS ONLY, CARRY FORWARD
* THE ENDING BALANCE AS THE NEW YEAR'S BEGINNING BALANCE
PERFORM UNTIL WS-EOF-GL
READ GL-MASTER-FILE
AT END SET WS-EOF-GL TO TRUE
END-READ
IF NOT WS-EOF-GL
IF GL-ACCOUNT-TYPE = 'A' OR
GL-ACCOUNT-TYPE = 'L' OR
GL-ACCOUNT-TYPE = 'E'
MOVE GL-ENDING-BALANCE
TO NEW-GL-BEGINNING-BALANCE
ELSE
MOVE ZEROS TO NEW-GL-BEGINNING-BALANCE
END-IF
PERFORM WRITE-NEW-YEAR-RECORD
END-IF
END-PERFORM
.
36.8 Subledger Integration
The Subledger-to-GL Relationship
Subledgers contain the detail that supports GL control account balances. The GL does not store individual customer invoices or vendor payments; those details reside in the Accounts Receivable and Accounts Payable subledgers, respectively. The GL stores only the summary total.
ACCOUNTS RECEIVABLE SUBLEDGER GENERAL LEDGER
+---------------------------+ +------------------+
| Customer A: $5,000.00 | | |
| Customer B: $3,200.00 | ---> | Accts Receivable |
| Customer C: $1,800.00 | | $10,000.00 |
| ---------- | | |
| Total: $10,000.00 | +------------------+
+---------------------------+
Subledger Posting to GL
Each subledger generates summary journal entries that are posted to the GL:
POST-AP-TO-GL.
* ACCOUNTS PAYABLE SUBLEDGER SUMMARY
* DEBIT: EXPENSE ACCOUNTS (DETAIL)
* CREDIT: ACCOUNTS PAYABLE CONTROL ACCOUNT
OPEN INPUT AP-SUMMARY-FILE
MOVE ZEROS TO WS-AP-TOTAL
PERFORM UNTIL WS-EOF-AP
READ AP-SUMMARY-FILE
AT END SET WS-EOF-AP TO TRUE
END-READ
IF NOT WS-EOF-AP
MOVE AP-EXPENSE-ACCOUNT TO JE-LN-ACCOUNT
MOVE 'D' TO JE-LN-DC-IND
MOVE AP-AMOUNT TO JE-LN-AMOUNT
PERFORM WRITE-JE-LINE
ADD AP-AMOUNT TO WS-AP-TOTAL
END-IF
END-PERFORM
* CREDIT THE AP CONTROL ACCOUNT
MOVE WS-AP-CONTROL-ACCT TO JE-LN-ACCOUNT
MOVE 'C' TO JE-LN-DC-IND
MOVE WS-AP-TOTAL TO JE-LN-AMOUNT
PERFORM WRITE-JE-LINE
.
Reconciliation of Subledger to GL Control Accounts
One of the most critical month-end procedures is reconciling each subledger's total to the corresponding GL control account balance. Discrepancies indicate posting errors or timing differences:
RECONCILE-SUBLEDGERS.
PERFORM RECONCILE-AP
PERFORM RECONCILE-AR
PERFORM RECONCILE-FA
PERFORM RECONCILE-PAYROLL
.
RECONCILE-AP.
PERFORM GET-AP-SUBLEDGER-TOTAL
PERFORM GET-GL-AP-CONTROL-BALANCE
COMPUTE WS-RECON-DIFF =
WS-AP-SUBLEDGER-TOTAL -
WS-GL-AP-CONTROL-BAL
IF WS-RECON-DIFF NOT = ZEROS
MOVE 'AP' TO WS-RECON-TYPE
PERFORM WRITE-RECON-EXCEPTION
ADD 1 TO WS-EXCEPTION-COUNT
ELSE
MOVE 'AP' TO WS-RECON-TYPE
PERFORM WRITE-RECON-MATCHED
END-IF
.
36.9 Audit Trail Requirements
Transaction Logging
Every GL system must maintain a complete audit trail. Every transaction must be traceable from the financial statements back to the source document. In COBOL, this means writing comprehensive audit records:
01 AUDIT-TRAIL-RECORD.
05 AT-TIMESTAMP PIC X(26).
05 AT-USER-ID PIC X(08).
05 AT-TERMINAL-ID PIC X(08).
05 AT-PROGRAM-NAME PIC X(08).
05 AT-ACTION-CODE PIC X(02).
88 AT-ADD VALUE 'AD'.
88 AT-CHANGE VALUE 'CH'.
88 AT-DELETE VALUE 'DL'.
88 AT-POST VALUE 'PS'.
88 AT-REVERSE VALUE 'RV'.
88 AT-CLOSE VALUE 'CL'.
05 AT-RECORD-TYPE PIC X(02).
05 AT-RECORD-KEY PIC X(20).
05 AT-FIELD-CHANGED PIC X(30).
05 AT-OLD-VALUE PIC X(50).
05 AT-NEW-VALUE PIC X(50).
05 AT-JE-ENTRY-NUM PIC 9(10).
05 AT-SOURCE-DOCUMENT PIC X(20).
05 AT-BATCH-NUMBER PIC 9(08).
SOX Compliance Considerations
The Sarbanes-Oxley Act (SOX) imposes strict requirements on financial systems:
- Segregation of duties: The person who creates a journal entry should not be the same person who approves or posts it.
- Access controls: Only authorized users can access GL functions.
- Change management: All changes to the chart of accounts, GL programs, and processing parameters must be documented and approved.
- Data retention: Financial records must be retained for the legally required period (typically 7 years).
- Internal controls: The system must enforce business rules that prevent or detect material misstatements.
CHECK-SOX-CONTROLS.
* VERIFY SEGREGATION OF DUTIES
IF JE-ENTERED-BY = JE-APPROVED-BY
MOVE 'SOX VIOLATION: SAME USER ENTERED AND '
'APPROVED ENTRY'
TO WS-ERROR-MSG
PERFORM WRITE-SOX-VIOLATION
SET WS-SOX-FAILED TO TRUE
END-IF
* VERIFY APPROVAL FOR LARGE ENTRIES
IF JE-TOTAL-DEBITS > WS-APPROVAL-THRESHOLD
IF JE-APPROVED-BY = SPACES
MOVE 'SOX VIOLATION: LARGE ENTRY WITHOUT '
'APPROVAL'
TO WS-ERROR-MSG
PERFORM WRITE-SOX-VIOLATION
SET WS-SOX-FAILED TO TRUE
END-IF
END-IF
.
36.10 COBOL Data Structures for Accounting
GL Account Master Record (Complete)
Here is a complete, production-quality GL master record layout:
01 GL-MASTER-RECORD.
* KEY FIELDS
05 GL-KEY.
10 GL-COMPANY PIC X(04).
10 GL-NATURAL-ACCT PIC X(04).
10 GL-COST-CENTER PIC X(04).
10 GL-SUB-ACCOUNT PIC X(02).
10 GL-FISCAL-YEAR PIC 9(04).
* ACCOUNT ATTRIBUTES
05 GL-DESCRIPTION PIC X(40).
05 GL-ACCOUNT-TYPE PIC X(01).
05 GL-NORMAL-BALANCE PIC X(01).
05 GL-CURRENCY-CODE PIC X(03).
* BEGINNING BALANCE
05 GL-BEG-BALANCE PIC S9(13)V99
COMP-3.
* PERIOD ACTIVITY (13 PERIODS)
05 GL-PERIOD-TABLE.
10 GL-PERIOD-ENTRY OCCURS 13 TIMES
INDEXED BY GL-PRD-IDX.
15 GL-PRD-DEBITS PIC S9(13)V99
COMP-3.
15 GL-PRD-CREDITS PIC S9(13)V99
COMP-3.
15 GL-PRD-NET PIC S9(13)V99
COMP-3.
15 GL-PRD-BUDGET PIC S9(13)V99
COMP-3.
* YEAR-TO-DATE TOTALS
05 GL-YTD-DEBITS PIC S9(13)V99
COMP-3.
05 GL-YTD-CREDITS PIC S9(13)V99
COMP-3.
05 GL-YTD-NET PIC S9(13)V99
COMP-3.
05 GL-END-BALANCE PIC S9(13)V99
COMP-3.
* ACTIVITY TRACKING
05 GL-LAST-POST-DATE PIC 9(08).
05 GL-LAST-POST-PERIOD PIC 9(02).
05 GL-ENTRY-COUNT-YTD PIC 9(06).
* FILLER FOR FUTURE USE
05 FILLER PIC X(50).
Journal Entry Record (Complete)
01 JE-COMPLETE-RECORD.
* HEADER SECTION
05 JE-RECORD-TYPE PIC X(01).
88 JE-IS-HEADER VALUE 'H'.
88 JE-IS-LINE VALUE 'L'.
05 JE-ENTRY-NUMBER PIC 9(10).
05 JE-HEADER-DATA.
10 JE-COMPANY PIC X(04).
10 JE-JOURNAL-CODE PIC X(03).
10 JE-ENTRY-DATE PIC 9(08).
10 JE-POST-PERIOD PIC 9(02).
10 JE-FISCAL-YEAR PIC 9(04).
10 JE-DESCRIPTION PIC X(40).
10 JE-SOURCE-REF PIC X(20).
10 JE-ENTRY-TYPE PIC X(01).
10 JE-STATUS PIC X(01).
10 JE-LINE-COUNT PIC 9(04).
10 JE-TOTAL-DEBITS PIC S9(13)V99.
10 JE-TOTAL-CREDITS PIC S9(13)V99.
10 JE-CREATED-BY PIC X(08).
10 JE-CREATED-TS PIC X(26).
10 JE-APPROVED-BY PIC X(08).
10 JE-APPROVED-TS PIC X(26).
10 JE-POSTED-BY PIC X(08).
10 JE-POSTED-TS PIC X(26).
05 JE-LINE-DATA REDEFINES JE-HEADER-DATA.
10 JE-LN-LINE-NUM PIC 9(04).
10 JE-LN-ACCOUNT PIC X(14).
10 JE-LN-DC-IND PIC X(01).
10 JE-LN-AMOUNT PIC S9(13)V99.
10 JE-LN-DESCRIPTION PIC X(30).
10 JE-LN-REFERENCE PIC X(20).
10 FILLER PIC X(119).
Multi-Company Support
Enterprise GL systems must support multiple companies within a single installation. The company code in the account key provides this capability:
01 WS-COMPANY-TABLE.
05 WS-COMPANY-ENTRY OCCURS 50 TIMES
INDEXED BY WS-CO-IDX.
10 WS-CO-CODE PIC X(04).
10 WS-CO-NAME PIC X(40).
10 WS-CO-CURRENCY PIC X(03).
10 WS-CO-PARENT PIC X(04).
10 WS-CO-CONSOL-IND PIC X(01).
88 WS-CO-CONSOLIDATE VALUE 'Y'.
10 WS-CO-FISCAL-START PIC 9(02).
10 WS-CO-CURRENT-PRD PIC 9(02).
10 WS-CO-CURRENT-YR PIC 9(04).
36.11 Batch Processing for GL
Daily Processing: Post Journal Entries
The daily batch cycle typically runs in the evening after business hours:
JOB: GL-DAILY-POST
STEP 1: SORT journal entries by company/account
STEP 2: VALIDATE all entries (balance, accounts, period)
STEP 3: POST validated entries to GL master
STEP 4: UPDATE journal status to 'Posted'
STEP 5: WRITE audit trail records
STEP 6: GENERATE posting summary report
STEP 7: GENERATE error report for rejected entries
Monthly Processing: Close Period and Generate Financials
JOB: GL-MONTH-END
STEP 1: VERIFY all daily postings complete
STEP 2: PROCESS recurring entries
STEP 3: PROCESS subledger summaries (AP, AR, FA, PY)
STEP 4: CALCULATE and post depreciation
STEP 5: GENERATE and post accruals
STEP 6: POST manual adjusting entries
STEP 7: GENERATE trial balance
STEP 8: VERIFY trial balance is in balance
STEP 9: GENERATE income statement
STEP 10: GENERATE balance sheet
STEP 11: GENERATE departmental reports
STEP 12: RECONCILE subledgers to GL
STEP 13: CLOSE the period
STEP 14: GENERATE auto-reversals for next period
STEP 15: PRODUCE month-end close report package
Annual Processing: Year-End Close
JOB: GL-YEAR-END
STEP 1: COMPLETE final month-end close (Period 12)
STEP 2: POST period 13 audit adjustments
STEP 3: GENERATE adjusted trial balance
STEP 4: GENERATE intercompany eliminations
STEP 5: CLOSE revenue accounts to income summary
STEP 6: CLOSE expense accounts to income summary
STEP 7: CLOSE income summary to retained earnings
STEP 8: GENERATE post-closing trial balance
STEP 9: CREATE new year GL master records
STEP 10: CARRY FORWARD balance sheet balances
STEP 11: GENERATE annual financial statements
STEP 12: ARCHIVE current year detail
STEP 13: PRODUCE year-end audit package
36.12 Report Formatting for Financial Statements
Professional Financial Statement Formatting
Financial statements must follow Generally Accepted Accounting Principles (GAAP) formatting standards. COBOL programs use detailed WRITE ... AFTER ADVANCING statements to produce publication-quality reports:
01 WS-INCOME-STMT-HDR1.
05 FILLER PIC X(20) VALUE SPACES.
05 WS-ISH1-COMPANY PIC X(40).
05 FILLER PIC X(72) VALUE SPACES.
01 WS-INCOME-STMT-HDR2.
05 FILLER PIC X(20) VALUE SPACES.
05 FILLER PIC X(30)
VALUE 'STATEMENT OF OPERATIONS'.
05 FILLER PIC X(82) VALUE SPACES.
01 WS-INCOME-STMT-HDR3.
05 FILLER PIC X(20) VALUE SPACES.
05 FILLER PIC X(28)
VALUE 'FOR THE PERIOD ENDING '.
05 WS-ISH3-DATE PIC X(18).
05 FILLER PIC X(66) VALUE SPACES.
01 WS-IS-DETAIL-LINE.
05 FILLER PIC X(04) VALUE SPACES.
05 WS-ISD-DESCRIPTION PIC X(40).
05 FILLER PIC X(04) VALUE SPACES.
05 WS-ISD-CURRENT PIC $$$,$$$,$$$,$$9.99-.
05 FILLER PIC X(04) VALUE SPACES.
05 WS-ISD-BUDGET PIC $$$,$$$,$$$,$$9.99-.
05 FILLER PIC X(04) VALUE SPACES.
05 WS-ISD-VARIANCE PIC $$$,$$$,$$$,$$9.99-.
05 FILLER PIC X(04) VALUE SPACES.
05 WS-ISD-VAR-PCT PIC --9.9.
05 FILLER PIC X(01) VALUE '%'.
01 WS-IS-TOTAL-LINE.
05 FILLER PIC X(04) VALUE SPACES.
05 WS-IST-DESCRIPTION PIC X(40).
05 FILLER PIC X(04) VALUE SPACES.
05 WS-IST-AMOUNT PIC $$$,$$$,$$$,$$9.99-.
05 FILLER PIC X(04) VALUE SPACES.
05 WS-IST-UNDERLINE PIC X(20).
Handling Negative Numbers in Financial Statements
Accounting convention uses parentheses for negative numbers rather than minus signs:
FORMAT-FINANCIAL-AMOUNT.
IF WS-AMOUNT < ZEROS
COMPUTE WS-ABS-AMOUNT = WS-AMOUNT * -1
MOVE WS-ABS-AMOUNT TO WS-FORMATTED-NUM
STRING '(' WS-FORMATTED-NUM ')'
DELIMITED BY SIZE
INTO WS-DISPLAY-AMOUNT
ELSE
MOVE WS-AMOUNT TO WS-FORMATTED-NUM
MOVE WS-FORMATTED-NUM TO WS-DISPLAY-AMOUNT
END-IF
.
36.13 Currency and Multi-Company Considerations
Multi-Currency Processing
Global organizations must handle transactions in multiple currencies. Each transaction is recorded in both the local (functional) currency and a reporting currency:
01 WS-CURRENCY-RECORD.
05 WS-CUR-FROM-CODE PIC X(03).
05 WS-CUR-TO-CODE PIC X(03).
05 WS-CUR-RATE PIC 9(05)V9(08).
05 WS-CUR-RATE-DATE PIC 9(08).
05 WS-CUR-RATE-TYPE PIC X(01).
88 WS-CUR-SPOT VALUE 'S'.
88 WS-CUR-AVERAGE VALUE 'A'.
88 WS-CUR-HISTORICAL VALUE 'H'.
CONVERT-CURRENCY.
COMPUTE WS-CONVERTED-AMOUNT ROUNDED =
WS-LOCAL-AMOUNT * WS-CUR-RATE
.
POST-MULTI-CURRENCY.
* POST IN LOCAL CURRENCY
MOVE WS-LOCAL-AMOUNT TO GL-PRD-NET(WS-PERIOD)
* POST IN REPORTING CURRENCY
PERFORM CONVERT-CURRENCY
MOVE WS-CONVERTED-AMOUNT
TO GL-RPT-PRD-NET(WS-PERIOD)
* CALCULATE TRANSLATION DIFFERENCE
COMPUTE WS-TRANSLATION-DIFF =
WS-CONVERTED-AMOUNT -
(WS-LOCAL-AMOUNT * WS-PRIOR-RATE)
.
Consolidation Processing
Multi-company consolidation combines the financial statements of parent and subsidiary companies:
- Translate subsidiary financials from local currency to reporting currency.
- Eliminate intercompany transactions and balances.
- Aggregate the translated, eliminated balances.
- Report consolidated financial statements.
36.14 Common GL Programming Patterns in COBOL
Pattern 1: Account Lookup with Caching
Since GL programs frequently look up the same accounts, caching reduces I/O:
01 WS-ACCOUNT-CACHE.
05 WS-CACHE-SIZE PIC 9(04) VALUE 100.
05 WS-CACHE-COUNT PIC 9(04) VALUE ZEROS.
05 WS-CACHE-ENTRY OCCURS 100 TIMES
INDEXED BY WS-CACHE-IDX.
10 WS-CACHE-KEY PIC X(14).
10 WS-CACHE-DESC PIC X(40).
10 WS-CACHE-TYPE PIC X(01).
10 WS-CACHE-NORMAL PIC X(01).
LOOKUP-ACCOUNT-CACHED.
SET WS-CACHE-IDX TO 1
SEARCH WS-CACHE-ENTRY
AT END
PERFORM READ-ACCOUNT-FROM-FILE
IF WS-ACCOUNT-FOUND
PERFORM ADD-TO-CACHE
END-IF
WHEN WS-CACHE-KEY(WS-CACHE-IDX) =
WS-LOOKUP-ACCOUNT
MOVE WS-CACHE-DESC(WS-CACHE-IDX)
TO WS-RESULT-DESC
MOVE WS-CACHE-TYPE(WS-CACHE-IDX)
TO WS-RESULT-TYPE
SET WS-ACCOUNT-FOUND TO TRUE
END-SEARCH
.
Pattern 2: Control Break Reporting
Financial reports rely heavily on control break logic for subtotals:
PROCESS-GL-WITH-BREAKS.
PERFORM READ-GL-RECORD
MOVE GL-COMPANY TO WS-PREV-COMPANY
MOVE GL-COST-CENTER TO WS-PREV-DEPT
PERFORM UNTIL WS-EOF-GL
IF GL-COMPANY NOT = WS-PREV-COMPANY
PERFORM PRINT-DEPT-SUBTOTAL
PERFORM PRINT-COMPANY-SUBTOTAL
PERFORM PRINT-COMPANY-HEADER
MOVE GL-COMPANY TO WS-PREV-COMPANY
END-IF
IF GL-COST-CENTER NOT = WS-PREV-DEPT
PERFORM PRINT-DEPT-SUBTOTAL
MOVE GL-COST-CENTER TO WS-PREV-DEPT
END-IF
PERFORM ACCUMULATE-DETAIL
PERFORM PRINT-DETAIL-LINE
PERFORM READ-GL-RECORD
END-PERFORM
PERFORM PRINT-DEPT-SUBTOTAL
PERFORM PRINT-COMPANY-SUBTOTAL
PERFORM PRINT-GRAND-TOTAL
.
Pattern 3: Period-Sensitive Balance Calculation
CALC-BALANCE-AS-OF-PERIOD.
MOVE GL-BEG-BALANCE TO WS-CALC-BALANCE
PERFORM VARYING WS-PRD FROM 1 BY 1
UNTIL WS-PRD > WS-AS-OF-PERIOD
ADD GL-PRD-NET(WS-PRD) TO WS-CALC-BALANCE
END-PERFORM
MOVE WS-CALC-BALANCE TO WS-ACCOUNT-BALANCE
.
Pattern 4: Hash Total Verification
Batch processing uses hash totals to detect lost or duplicated records:
COMPUTE-HASH-TOTALS.
MOVE ZEROS TO WS-HASH-ACCOUNT
WS-HASH-AMOUNT
WS-RECORD-COUNT
PERFORM UNTIL WS-EOF-INPUT
READ JOURNAL-INPUT-FILE
AT END SET WS-EOF-INPUT TO TRUE
END-READ
IF NOT WS-EOF-INPUT
ADD 1 TO WS-RECORD-COUNT
ADD FUNCTION NUMVAL(JE-LN-ACCOUNT)
TO WS-HASH-ACCOUNT
ADD JE-LN-AMOUNT TO WS-HASH-AMOUNT
END-IF
END-PERFORM
* COMPARE WITH BATCH CONTROL TOTALS
IF WS-RECORD-COUNT NOT = WS-EXPECTED-COUNT
PERFORM HASH-TOTAL-MISMATCH
END-IF
.
36.15 Summary
The General Ledger system is the financial heart of every organization, and COBOL has been the language of choice for implementing these systems for over fifty years. The core concepts -- double-entry bookkeeping, chart of accounts hierarchy, journal entry processing, period-end closing, and financial statement generation -- translate directly into COBOL's strengths: sequential file processing, precise decimal arithmetic, structured data records, and reliable batch processing.
Key points to remember:
- Every transaction must balance: Debits must equal credits at the entry, batch, and period level.
- The chart of accounts provides the classification framework; its design determines reporting flexibility.
- The GL master file stores period balances using the OCCURS clause (13 periods: 12 months plus adjustments).
- Journal entry processing follows a strict validate-approve-post workflow.
- Period-end processing is a carefully orchestrated sequence of accruals, adjustments, closings, and carry-forwards.
- Subledger reconciliation ensures that detail systems agree with GL control accounts.
- Audit trail requirements mandate complete traceability from financial statements to source documents.
- COBOL's fixed-point arithmetic (PIC S9(13)V99 COMP-3) provides the precision that financial calculations demand -- no floating-point rounding errors.
In the code examples that follow, you will implement each of these components as working COBOL programs, giving you hands-on experience with the data structures, validation logic, and processing patterns that power real-world General Ledger systems.