CTS-KB
COBOL 3 / 5

COBOL 業務ロジック実装

#COBOL #業務ロジック #バッチ処理

対象: 銀行入出金処理、受注システムなど業務システムの設計パターン 基本文法は COBOL 文法基礎、運用は COBOL 本番運用 を参照


目次

  1. 銀行の入出金処理
  2. 受注システム
  3. マスタメンテナンス
  4. バッチ連携パターン集

1. 銀行の入出金処理

1.1 業務の全体像

1.1 業務の全体像

顧客

ATM / 窓口

トランザクション入力

オンライン(CICS等)

残高照会・入金・出金

トランザクション

ファイル

口座マスタ

ファイル

取引履歴

ファイル

夜間バッチ

日計表作成・利息計算・帳票出力

帳票 / 報告

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 日次バッチ処理の流れ

1.5 日次バッチ処理の流れ

JOB010: トランザクション取込

・取引データ受信

・入力フォーマットチェック

JOB020: 入出金処理(メイン)

・1件ずつ処理

・口座マスタ更新

・取引履歴書込

・エラー出力

JOB030: 日計表作成

・支店別集計

・口座種別集計

・コントロールブレイク

JOB040: 帳票出力

・日計表

・取引明細一覧

・エラー一覧

JOB050: バックアップ


2. 受注システム

2.1 業務の全体像

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            *> 削除
命令前提条件対象
WRITEOPEN OUTPUT or EXTEND新規レコード追加
REWRITEOPEN I-O + 直前にREAD既存レコード更新
DELETEOPEN I-O + 直前にREAD既存レコード削除
READOPEN 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ファイルをキーで突き合わせマスタ × トランザクション
ソートキーで並べ替え顧客コード順にソート
帳票印刷用の整形出力請求書、日計表
マスタ更新追加/更新/削除商品マスタメンテナンス
コントロールブレイクグループ変化時に小計出力顧客別受注集計

関連記事