対象: 銀行入出金処理、受注システムなど業務システムの設計パターン 基本文法は COBOL 文法基礎、運用は COBOL 本番運用 を参照
目次
1. 銀行の入出金処理
1.1 業務の全体像
1.2 データ構造
*> ============================================================
*> copybooks/account-record.cpy
*> 口座マスタ — 銀行口座エンティティ
*> ============================================================
01 ACCOUNT-RECORD.
05 AC-ACCOUNT-NO PIC X(10). *> 口座番号(一意キー)
05 AC-BRANCH-CD PIC X(3). *> 支店コード
05 AC-ACCOUNT-TYPE PIC X(1). *> 口座種別
88 AC-IS-ORDINARY VALUE "1". *> 普通預金
88 AC-IS-CURRENT VALUE "2". *> 当座預金
88 AC-IS-SAVINGS VALUE "3". *> 定期預金
05 AC-CUSTOMER-NAME PIC X(30). *> 顧客名
05 AC-BALANCE PIC S9(13)V99. *> 残高(符号付き)
05 AC-LAST-TXN-DATE PIC 9(8). *> 最終取引日
05 AC-STATUS PIC X(1). *> 口座状態
88 AC-IS-ACTIVE VALUE "A". *> 有効
88 AC-IS-FROZEN VALUE "F". *> 凍結
88 AC-IS-CLOSED VALUE "C". *> 解約済み
*> ============================================================
*> copybooks/transaction-record.cpy
*> 取引トランザクション — 入出金イベント
*> ============================================================
01 TRANSACTION-RECORD.
05 TX-TXN-ID PIC X(15). *> 取引ID
05 TX-ACCOUNT-NO PIC X(10). *> 口座番号
05 TX-TXN-DATE PIC 9(8). *> 取引日(YYYYMMDD)
05 TX-TXN-TIME PIC 9(6). *> 取引時刻(HHMMSS)
05 TX-TXN-TYPE PIC X(1). *> 取引種別
88 TX-IS-DEPOSIT VALUE "D". *> 入金
88 TX-IS-WITHDRAW VALUE "W". *> 出金
88 TX-IS-TRANSFER VALUE "T". *> 振込
05 TX-AMOUNT PIC 9(11)V99. *> 取引金額
05 TX-BALANCE-AFTER PIC S9(13)V99. *> 取引後残高
05 TX-DESCRIPTION PIC X(30). *> 摘要
05 TX-RESULT PIC X(1). *> 処理結果
88 TX-SUCCESS VALUE "S".
88 TX-FAILED VALUE "F".
05 TX-ERROR-CD PIC X(4). *> エラーコード
設計のポイント:
PIC S9(13)V99— 残高は符号付き(当座預金でマイナスの可能性)- 88条件名で口座状態・取引種別を定義 → IF文が業務用語で読める
- 取引後残高(
TX-BALANCE-AFTER)を記録 → 監査証跡になる
1.3 入出金処理のロジック
*> ============================================================
*> 入出金処理サブプログラム
*> ============================================================
PROCEDURE DIVISION
USING TRANSACTION-RECORD ACCOUNT-RECORD.
PROCESS-TXN.
*> 1. 口座の状態チェック
PERFORM CHECK-ACCOUNT-PARA
IF TX-FAILED
GOBACK
END-IF
*> 2. 取引種別に応じた処理
EVALUATE TRUE
WHEN TX-IS-DEPOSIT
PERFORM PROCESS-DEPOSIT
WHEN TX-IS-WITHDRAW
PERFORM PROCESS-WITHDRAW
WHEN TX-IS-TRANSFER
PERFORM PROCESS-TRANSFER
WHEN OTHER
MOVE "E001" TO TX-ERROR-CD
SET TX-FAILED TO TRUE
END-EVALUATE
GOBACK.
*> --- 口座状態チェック ---
CHECK-ACCOUNT-PARA.
IF AC-IS-FROZEN
MOVE "E010" TO TX-ERROR-CD
SET TX-FAILED TO TRUE
EXIT PARAGRAPH
END-IF
IF AC-IS-CLOSED
MOVE "E011" TO TX-ERROR-CD
SET TX-FAILED TO TRUE
END-IF.
*> --- 入金処理 ---
*> 業務ルール: 入金は金額が正であれば常に成功
PROCESS-DEPOSIT.
IF TX-AMOUNT <= 0
MOVE "E020" TO TX-ERROR-CD
SET TX-FAILED TO TRUE
EXIT PARAGRAPH
END-IF
*> 残高加算
ADD TX-AMOUNT TO AC-BALANCE
MOVE AC-BALANCE TO TX-BALANCE-AFTER
SET TX-SUCCESS TO TRUE.
*> --- 出金処理 ---
*> 業務ルール: 残高不足は許可しない(当座預金を除く)
PROCESS-WITHDRAW.
IF TX-AMOUNT <= 0
MOVE "E020" TO TX-ERROR-CD
SET TX-FAILED TO TRUE
EXIT PARAGRAPH
END-IF
*> 残高チェック(普通預金の場合)
IF AC-IS-ORDINARY AND TX-AMOUNT > AC-BALANCE
MOVE "E030" TO TX-ERROR-CD
SET TX-FAILED TO TRUE
EXIT PARAGRAPH
END-IF
*> 残高減算
SUBTRACT TX-AMOUNT FROM AC-BALANCE
MOVE AC-BALANCE TO TX-BALANCE-AFTER
SET TX-SUCCESS TO TRUE.
*> --- 振込処理 ---
*> 業務ルール: 出金 + 相手口座への入金(別途実装)
PROCESS-TRANSFER.
*> まず送金元の出金処理
PERFORM PROCESS-WITHDRAW
IF TX-FAILED
EXIT PARAGRAPH
END-IF
*> 受取側の入金は別のプログラムで処理
*> (2フェーズコミット or メッセージキュー)
SET TX-SUCCESS TO TRUE.
1.4 エラーコード体系
エラーコード設計:
E001: 不明な取引種別
E010: 口座凍結中
E011: 口座解約済み
E020: 取引金額が0以下
E030: 残高不足
E040: 1日の出金限度額超過
E050: 振込先口座が存在しない
E090: システムエラー
*> copybooks/error-codes.cpy
01 ERROR-TABLE.
05 FILLER PIC X(34) VALUE "E001Unknown transaction type ".
05 FILLER PIC X(34) VALUE "E010Account is frozen ".
05 FILLER PIC X(34) VALUE "E011Account is closed ".
05 FILLER PIC X(34) VALUE "E020Invalid amount ".
05 FILLER PIC X(34) VALUE "E030Insufficient balance ".
05 FILLER PIC X(34) VALUE "E040Daily withdrawal limit exceeded".
05 FILLER PIC X(34) VALUE "E050Transfer target not found ".
05 FILLER PIC X(34) VALUE "E090System error ".
01 ERROR-TABLE-R REDEFINES ERROR-TABLE.
05 ERROR-ENTRY OCCURS 8 TIMES.
10 ERR-CODE PIC X(4).
10 ERR-MESSAGE PIC X(30).
1.5 日次バッチ処理の流れ
2. 受注システム
2.1 業務の全体像
2.2 データ構造
*> ============================================================
*> 受注ヘッダ(注文の基本情報)
*> ============================================================
01 ORDER-HEADER.
05 OH-ORDER-NO PIC X(10). *> 受注番号(一意キー)
05 OH-ORDER-DATE PIC 9(8). *> 受注日
05 OH-CUSTOMER-ID PIC X(8). *> 顧客コード
05 OH-CUSTOMER-NAME PIC X(30). *> 顧客名
05 OH-ORDER-STATUS PIC X(1). *> 受注ステータス
88 OH-PENDING VALUE "P". *> 受付中
88 OH-CONFIRMED VALUE "C". *> 確定
88 OH-SHIPPED VALUE "S". *> 出荷済
88 OH-CANCELLED VALUE "X". *> 取消
05 OH-TOTAL-AMOUNT PIC 9(9)V99. *> 受注合計金額
05 OH-TAX-AMOUNT PIC 9(8)V99. *> 消費税額
05 OH-LINE-COUNT PIC 9(3). *> 明細行数
*> ============================================================
*> 受注明細(注文の内訳)
*> ============================================================
01 ORDER-DETAIL.
05 OD-ORDER-NO PIC X(10). *> 受注番号(FK)
05 OD-LINE-NO PIC 9(3). *> 明細行番号
05 OD-PRODUCT-ID PIC X(8). *> 商品コード
05 OD-PRODUCT-NAME PIC X(30). *> 商品名
05 OD-QUANTITY PIC 9(5). *> 数量
05 OD-UNIT-PRICE PIC 9(7)V99. *> 単価
05 OD-LINE-AMOUNT PIC 9(9)V99. *> 行金額
05 OD-STOCK-STATUS PIC X(1). *> 在庫引当状態
88 OD-NOT-ALLOCATED VALUE "N". *> 未引当
88 OD-ALLOCATED VALUE "A". *> 引当済
88 OD-BACK-ORDER VALUE "B". *> 入荷待ち
*> ============================================================
*> 商品マスタ
*> ============================================================
01 PRODUCT-MASTER.
05 PM-PRODUCT-ID PIC X(8). *> 商品コード
05 PM-PRODUCT-NAME PIC X(30). *> 商品名
05 PM-UNIT-PRICE PIC 9(7)V99. *> 単価
05 PM-STOCK-QTY PIC 9(7). *> 在庫数量
05 PM-MIN-STOCK PIC 9(5). *> 最低在庫数
05 PM-DISCONTINUED PIC X(1). *> 廃番フラグ
88 PM-IS-ACTIVE VALUE "N".
88 PM-IS-DISCONTINUED VALUE "Y".
2.3 受注処理のロジック
*> ============================================================
*> 受注確定処理
*> 受付中(P) → 確定(C) へのステータス遷移
*> ============================================================
CONFIRM-ORDER-PARA.
*> ステータスチェック
IF NOT OH-PENDING
MOVE "Already processed" TO WS-ERR-MSG
SET WS-ERROR TO TRUE
EXIT PARAGRAPH
END-IF
*> 明細行を1件ずつチェック
PERFORM VARYING WS-LINE FROM 1 BY 1
UNTIL WS-LINE > OH-LINE-COUNT
*> 商品マスタの存在チェック
PERFORM READ-PRODUCT-MASTER
IF PM-IS-DISCONTINUED
STRING "Product " OD-PRODUCT-ID " discontinued"
DELIMITED BY SIZE INTO WS-ERR-MSG
END-STRING
SET WS-ERROR TO TRUE
EXIT PERFORM
END-IF
*> 在庫引当
PERFORM ALLOCATE-STOCK-PARA
IF OD-BACK-ORDER
ADD 1 TO WS-BACKORDER-COUNT
END-IF
END-PERFORM
*> エラーがなければ確定
IF NOT WS-ERROR
SET OH-CONFIRMED TO TRUE
MOVE FUNCTION CURRENT-DATE(1:8) TO OH-ORDER-DATE
END-IF.
*> --- 在庫引当 ---
*> 業務ルール: 在庫があれば引当、なければ入荷待ち
ALLOCATE-STOCK-PARA.
IF PM-STOCK-QTY >= OD-QUANTITY
*> 在庫あり → 引当
SUBTRACT OD-QUANTITY FROM PM-STOCK-QTY
SET OD-ALLOCATED TO TRUE
ELSE
*> 在庫不足 → 入荷待ち
SET OD-BACK-ORDER TO TRUE
END-IF.
2.4 コントロールブレイク処理(集計帳票の定石)
COBOLの集計処理で最もよく使われるパターン。 グループが変わったときに小計を出力する。
*> ============================================================
*> 顧客別受注集計(コントロールブレイク)
*>
*> 入力: 顧客コード順にソート済みの受注データ
*> 出力: 顧客ごとの小計 + 全体合計
*> ============================================================
77 WS-PREV-CUSTOMER PIC X(8) VALUE SPACES.
77 WS-CUST-TOTAL PIC 9(11)V99 VALUE 0.
77 WS-GRAND-TOTAL PIC 9(13)V99 VALUE 0.
77 WS-CUST-COUNT PIC 9(5) VALUE 0.
REPORT-PARA.
OPEN INPUT ORDER-FILE
OPEN OUTPUT PRINT-FILE
PERFORM PRINT-HEADER-PARA
MOVE "N" TO WS-EOF-FLAG
MOVE SPACES TO WS-PREV-CUSTOMER
PERFORM UNTIL WS-EOF
READ ORDER-FILE
AT END
SET WS-EOF TO TRUE
*> 最後のグループの小計を出力
IF WS-PREV-CUSTOMER NOT = SPACES
PERFORM PRINT-SUBTOTAL-PARA
END-IF
NOT AT END
*> --- コントロールブレイク判定 ---
IF OH-CUSTOMER-ID NOT = WS-PREV-CUSTOMER
AND WS-PREV-CUSTOMER NOT = SPACES
*> 顧客が変わった → 前の顧客の小計を出力
PERFORM PRINT-SUBTOTAL-PARA
END-IF
*> 現在のレコードを処理
MOVE OH-CUSTOMER-ID TO WS-PREV-CUSTOMER
ADD OH-TOTAL-AMOUNT TO WS-CUST-TOTAL
ADD 1 TO WS-CUST-COUNT
PERFORM PRINT-DETAIL-PARA
END-READ
END-PERFORM
PERFORM PRINT-GRAND-TOTAL-PARA
CLOSE ORDER-FILE PRINT-FILE.
*> --- 顧客小計の出力 ---
PRINT-SUBTOTAL-PARA.
MOVE WS-CUST-TOTAL TO WD-SUBTOTAL
MOVE WS-CUST-COUNT TO WD-SUB-COUNT
WRITE PRINT-LINE FROM WS-SUBTOTAL-LINE
AFTER ADVANCING 1 LINE
END-WRITE
*> 全体合計に加算してリセット
ADD WS-CUST-TOTAL TO WS-GRAND-TOTAL
MOVE 0 TO WS-CUST-TOTAL
MOVE 0 TO WS-CUST-COUNT.
出力イメージ:
顧客: C001 田中商事
ORD-001 2026-03-01 150,000
ORD-005 2026-03-15 80,000
--- 小計: 2件 230,000 ---
顧客: C002 鈴木工業
ORD-002 2026-03-03 320,000
ORD-003 2026-03-10 45,000
ORD-007 2026-03-20 180,000
--- 小計: 3件 545,000 ---
========= 合計: 5件 775,000 =========
3. マスタメンテナンス
3.1 マスタ更新の基本パターン
*> ============================================================
*> マスタ更新バッチ
*>
*> トランザクションファイルの指示に従って
*> マスタファイルを追加(A)/更新(U)/削除(D)する
*> ============================================================
01 TXN-RECORD.
05 TXN-ACTION PIC X(1).
88 TXN-ADD VALUE "A".
88 TXN-UPDATE VALUE "U".
88 TXN-DELETE VALUE "D".
05 TXN-KEY PIC X(10).
05 TXN-DATA PIC X(80).
PROCESS-TXN-PARA.
EVALUATE TRUE
WHEN TXN-ADD
PERFORM MASTER-ADD-PARA
WHEN TXN-UPDATE
PERFORM MASTER-UPDATE-PARA
WHEN TXN-DELETE
PERFORM MASTER-DELETE-PARA
WHEN OTHER
PERFORM WRITE-ERROR-PARA
END-EVALUATE.
*> --- 追加処理 ---
MASTER-ADD-PARA.
*> キーの重複チェック
READ MASTER-FILE KEY IS TXN-KEY
IF WS-FILE-STATUS = "00"
*> 既に存在する → エラー
MOVE "Duplicate key" TO WS-ERR-MSG
PERFORM WRITE-ERROR-PARA
EXIT PARAGRAPH
END-IF
*> 新規レコードの書き込み
MOVE TXN-KEY TO MASTER-KEY
MOVE TXN-DATA TO MASTER-DATA
WRITE MASTER-RECORD
ADD 1 TO WS-ADD-COUNT.
*> --- 更新処理 ---
MASTER-UPDATE-PARA.
READ MASTER-FILE KEY IS TXN-KEY
IF WS-FILE-STATUS NOT = "00"
MOVE "Record not found" TO WS-ERR-MSG
PERFORM WRITE-ERROR-PARA
EXIT PARAGRAPH
END-IF
MOVE TXN-DATA TO MASTER-DATA
REWRITE MASTER-RECORD
ADD 1 TO WS-UPDATE-COUNT.
*> --- 削除処理 ---
MASTER-DELETE-PARA.
READ MASTER-FILE KEY IS TXN-KEY
IF WS-FILE-STATUS NOT = "00"
MOVE "Record not found" TO WS-ERR-MSG
PERFORM WRITE-ERROR-PARA
EXIT PARAGRAPH
END-IF
DELETE MASTER-FILE
ADD 1 TO WS-DELETE-COUNT.
3.2 REWRITE と DELETE
*> REWRITE: 直前に READ したレコードを上書き更新
READ MASTER-FILE KEY IS WS-SEARCH-KEY
*> (レコードの内容を変更)
MOVE NEW-VALUE TO MASTER-FIELD
REWRITE MASTER-RECORD *> 上書き
*> DELETE: 直前に READ したレコードを削除
READ MASTER-FILE KEY IS WS-SEARCH-KEY
DELETE MASTER-FILE *> 削除
| 命令 | 前提条件 | 対象 |
|---|---|---|
WRITE | OPEN OUTPUT or EXTEND | 新規レコード追加 |
REWRITE | OPEN I-O + 直前にREAD | 既存レコード更新 |
DELETE | OPEN I-O + 直前にREAD | 既存レコード削除 |
READ | OPEN INPUT or I-O | レコード読み込み |
4. バッチ連携パターン集
4.1 マッチング処理(突き合わせ)
2つのファイルをキーで突き合わせる。 入力は両方ともキー順にソートされていることが前提。
*> ============================================================
*> マスタ × トランザクション マッチング
*>
*> パターン:
*> マスタにある + トランザクションにある → 更新
*> マスタにない + トランザクションにある → 追加
*> マスタにある + トランザクションにない → 変更なし
*> ============================================================
MATCH-PARA.
READ MASTER-FILE AT END SET WS-MASTER-EOF TO TRUE
READ TXN-FILE AT END SET WS-TXN-EOF TO TRUE
PERFORM UNTIL WS-MASTER-EOF AND WS-TXN-EOF
EVALUATE TRUE
WHEN MASTER-KEY < TXN-KEY
*> マスタのみ → そのまま出力
WRITE OUT-RECORD FROM MASTER-RECORD
READ MASTER-FILE
AT END SET WS-MASTER-EOF TO TRUE
END-READ
WHEN MASTER-KEY = TXN-KEY
*> 一致 → 更新して出力
PERFORM UPDATE-RECORD-PARA
WRITE OUT-RECORD FROM MASTER-RECORD
READ MASTER-FILE
AT END SET WS-MASTER-EOF TO TRUE
END-READ
READ TXN-FILE
AT END SET WS-TXN-EOF TO TRUE
END-READ
WHEN MASTER-KEY > TXN-KEY
*> トランザクションのみ → 新規追加
PERFORM CREATE-RECORD-PARA
WRITE OUT-RECORD FROM NEW-RECORD
READ TXN-FILE
AT END SET WS-TXN-EOF TO TRUE
END-READ
END-EVALUATE
END-PERFORM
4.2 ソートマージ
*> COBOL の SORT 文でファイルをソートする
SORT SORT-FILE
ON ASCENDING KEY SORT-CUSTOMER-ID
ON ASCENDING KEY SORT-ORDER-DATE
USING INPUT-FILE
GIVING OUTPUT-FILE
*> MERGE: 複数のソート済みファイルを統合
MERGE MERGE-FILE
ON ASCENDING KEY MERGE-KEY
USING FILE-A FILE-B FILE-C
GIVING OUTPUT-FILE
4.3 よくあるバッチ処理のパターン
| パターン | 説明 | 例 |
|---|---|---|
| 抽出 | 条件に合うレコードを選別 | 未処理の受注だけ抽出 |
| 変換 | 形式を変えて出力 | 社内形式 → 銀行振込形式 |
| 集計 | グループごとに合計 | 支店別売上集計 |
| マッチング | 2ファイルをキーで突き合わせ | マスタ × トランザクション |
| ソート | キーで並べ替え | 顧客コード順にソート |
| 帳票 | 印刷用の整形出力 | 請求書、日計表 |
| マスタ更新 | 追加/更新/削除 | 商品マスタメンテナンス |
| コントロールブレイク | グループ変化時に小計出力 | 顧客別受注集計 |
関連記事
- RPG 業務ロジック実装 — RPG IV の対応する業務ロジック実装例
- COBOL 文法基礎 — COBOL の基本文法リファレンス
- COBOL モジュール設計 — サブルーチンとモジュール化
- COBOL × SQL 連携 — 埋め込み SQL によるデータベースアクセス
- COBOL 本番運用 — 帳票出力・ジョブ管理・運用環境