COBOLの EVALUATE 文は、他言語の switch/case に似た多方向条件分岐命令です。単純な値の一致判定だけでなく、範囲指定(THRU)・複数主語の組み合わせ判定(ALSO)・条件式評価(EVALUATE TRUE)など、IF文の複雑なネストを整理するための強力な機能を備えています。
本記事では基本構文から、業務コードの分類・エラーコード処理・判定表(デシジョンテーブル)といった実践パターンまで、EVALUATE文のすべてを解説します。
- EVALUATE文の基本構文と WHEN / WHEN OTHER / END-EVALUATE の使い方
- WHEN THRU で数値・文字の範囲を指定する方法
- EVALUATE TRUE で条件式をそのまま評価する方法
- ALSO キーワードで複数主語・複数客体の組み合わせ判定(判定表)を実装する方法
- 88レベル条件名と EVALUATE の組み合わせパターン
- EVALUATE vs IF文 の使い分け基準
- 業務コード分類・成績判定・エラーコード処理などの実践パターン
EVALUATE文の基本構文
EVALUATE文は「評価対象(主語)」を指定し、WHEN句で一致するパターンごとに処理を記述します。
EVALUATE 主語
WHEN 値-1
処理-1
WHEN 値-2
処理-2
WHEN 値-3
WHEN 値-4
処理-3 *> 値-3 と 値-4 が共通の処理
WHEN OTHER
処理-else
END-EVALUATE
いくつかの重要な特徴があります。
- フォールスルーなし:C言語の switch と異なり、一致した WHEN の処理が終わると自動的に END-EVALUATE へ進みます(break 不要)
- WHEN OTHER:いずれの WHEN にも一致しない場合に実行されます(省略可能)
- WHEN の連続記述:複数の WHEN を連続して書くと OR 条件になります
01 WS-TRANS-CODE PIC X(2).
EVALUATE WS-TRANS-CODE
WHEN "01"
PERFORM INSERT-PROC
WHEN "02"
PERFORM UPDATE-PROC
WHEN "03"
PERFORM DELETE-PROC
WHEN "04"
WHEN "05"
PERFORM INQUIRY-PROC *> "04","05" 共通
WHEN OTHER
PERFORM ERROR-PROC
END-EVALUATE
WHEN THRU:範囲指定
THRU(THROUGH と同義)を使うと、値の範囲を一括指定できます。数値・文字コード双方に使えます。
01 WS-SCORE PIC 9(3).
EVALUATE WS-SCORE
WHEN 90 THRU 100
MOVE "S" TO WS-GRADE
DISPLAY "優秀"
WHEN 80 THRU 89
MOVE "A" TO WS-GRADE
DISPLAY "良好"
WHEN 70 THRU 79
MOVE "B" TO WS-GRADE
DISPLAY "普通"
WHEN 60 THRU 69
MOVE "C" TO WS-GRADE
DISPLAY "不可"
WHEN 0 THRU 59
MOVE "D" TO WS-GRADE
DISPLAY "不合格"
WHEN OTHER
DISPLAY "無効なスコア: " WS-SCORE
END-EVALUATE
01 WS-ITEM-CODE PIC X(3).
EVALUATE WS-ITEM-CODE
WHEN "A00" THRU "A99"
MOVE "電子機器" TO WS-CATEGORY
WHEN "B00" THRU "B99"
MOVE "家具" TO WS-CATEGORY
WHEN "C00" THRU "C99"
MOVE "衣料品" TO WS-CATEGORY
WHEN OTHER
MOVE "その他" TO WS-CATEGORY
END-EVALUATE
THRU は「下限 THRU 上限」の順で書きます。下限が上限より大きいとコンパイルエラーまたは意図しない動作になります。文字列の範囲比較は照合順序(COLLATING SEQUENCE)に依存するため、環境定義を確認してください。
EVALUATE TRUE / EVALUATE FALSE:条件式で分岐
EVALUATE TRUE は主語に TRUE を指定し、WHEN 句に条件式を書きます。IF-ELSE IF-ELSE のネストを平坦化するのに最も効果的なパターンです。
01 WS-AGE PIC 9(3).
01 WS-INCOME PIC 9(8).
01 WS-RANK PIC X(10).
*> IF-ELSE IFのネストをEVALUATE TRUEで整理
EVALUATE TRUE
WHEN WS-AGE < 18
MOVE "未成年" TO WS-RANK
WHEN WS-INCOME >= 10000000
MOVE "VIPプレミアム" TO WS-RANK
WHEN WS-INCOME >= 5000000
MOVE "VIP" TO WS-RANK
WHEN WS-INCOME >= 1000000
MOVE "一般" TO WS-RANK
WHEN OTHER
MOVE "新規" TO WS-RANK
END-EVALUATE
最初にTRUEになった WHEN で処理が実行され、以降の WHEN は評価されません。条件の順序が重要です。広い条件を後ろに、狭い条件(より具体的・特殊なケース)を前に書いてください。
01 WS-IS-VALID PIC X(1).
88 WS-VALID VALUE "Y".
88 WS-INVALID VALUE "N".
01 WS-IS-ACTIVE PIC X(1).
88 WS-ACTIVE VALUE "Y".
88 WS-INACTIVE VALUE "N".
*> FALSE のときに一致する条件で分岐
EVALUATE FALSE
WHEN WS-VALID
DISPLAY "バリデーションエラー"
WHEN WS-ACTIVE
DISPLAY "非アクティブアカウント"
WHEN OTHER
PERFORM MAIN-PROC
END-EVALUATE
ALSO キーワード:複数主語の組み合わせ判定(判定表)
EVALUATE の最も強力な機能の一つが ALSO です。複数の主語を ALSO で区切り、WHEN 句にも同数のオブジェクトを ALSO で区切ることで、複数条件の組み合わせ(判定表・デシジョンテーブル)を表現できます。
01 WS-ORDER-TYPE PIC X(1). *> N:新規 C:変更 D:削除
01 WS-AUTH-LEVEL PIC 9(1). *> 1:一般 2:リーダー 3:管理者
01 WS-PERMIT PIC X(1).
EVALUATE WS-ORDER-TYPE ALSO WS-AUTH-LEVEL
WHEN "N" ALSO 1
MOVE "Y" TO WS-PERMIT *> 新規×一般: 可
WHEN "N" ALSO 2
WHEN "N" ALSO 3
MOVE "Y" TO WS-PERMIT *> 新規×リーダー/管理者: 可
WHEN "C" ALSO 1
MOVE "N" TO WS-PERMIT *> 変更×一般: 不可
WHEN "C" ALSO 2
WHEN "C" ALSO 3
MOVE "Y" TO WS-PERMIT *> 変更×リーダー/管理者: 可
WHEN "D" ALSO 1
WHEN "D" ALSO 2
MOVE "N" TO WS-PERMIT *> 削除×一般/リーダー: 不可
WHEN "D" ALSO 3
MOVE "Y" TO WS-PERMIT *> 削除×管理者のみ: 可
WHEN OTHER
MOVE "N" TO WS-PERMIT
END-EVALUATE
WHEN ANY:対応する主語をワイルドカードにする
ALSO を使った複数主語判定で、特定の主語の値を問わない場合に ANY を使います。
01 WS-STATUS PIC X(2). *> 処理ステータス
01 WS-ERR-FLG PIC X(1). *> エラーフラグ
EVALUATE WS-STATUS ALSO WS-ERR-FLG
WHEN "OK" ALSO "N"
PERFORM NORMAL-END-PROC
WHEN "OK" ALSO "Y"
PERFORM PARTIAL-ERROR-PROC
WHEN "NG" ALSO ANY
*> ステータスNGはエラーフラグ問わず共通処理
PERFORM ABNORMAL-END-PROC
WHEN OTHER
PERFORM UNKNOWN-STATUS-PROC
END-EVALUATE
システム設計書に「判定表(デシジョンテーブル)」が定義されている場合、
ALSO を使った EVALUATE は設計書と1対1で対応させやすく、レビューや保守のときに仕様と照合しやすくなります。
88レベル条件名との組み合わせ
COBOLの88レベル条件名は値に名前を付ける仕組みです。EVALUATE と組み合わせると、コードがより読みやすくなります。
01 WS-PAYMENT-METHOD PIC 9(1).
88 PM-CASH VALUE 1.
88 PM-CREDIT VALUE 2.
88 PM-DEBIT VALUE 3.
88 PM-QR-PAY VALUE 4.
88 PM-BANK-TRANS VALUE 5.
01 WS-AMOUNT PIC S9(7)V99 COMP-3.
EVALUATE TRUE
WHEN PM-CASH
PERFORM CASH-PAYMENT-PROC
WHEN PM-CREDIT
PERFORM CREDIT-AUTH-PROC
WHEN PM-DEBIT
PERFORM DEBIT-CHECK-PROC
WHEN PM-QR-PAY
PERFORM QR-PAYMENT-PROC
WHEN PM-BANK-TRANS
PERFORM BANK-TRANSFER-PROC
WHEN OTHER
MOVE "不明な支払方法" TO WS-ERR-MSG
PERFORM ERROR-PROC
END-EVALUATE
01 WS-DAY-OF-WEEK PIC 9(1).
88 IS-MONDAY VALUE 1.
88 IS-TUESDAY VALUE 2.
88 IS-WEDNESDAY VALUE 3.
88 IS-THURSDAY VALUE 4.
88 IS-FRIDAY VALUE 5.
88 IS-SATURDAY VALUE 6.
88 IS-SUNDAY VALUE 7.
88 IS-WEEKDAY VALUE 1 THRU 5.
88 IS-WEEKEND VALUE 6 7.
EVALUATE TRUE
WHEN IS-WEEKEND
MOVE "Y" TO WS-HOLIDAY-FLG
DISPLAY "休日処理"
WHEN IS-MONDAY
DISPLAY "週次バッチ実行"
PERFORM WEEKLY-BATCH
WHEN IS-WEEKDAY
DISPLAY "通常営業日処理"
PERFORM DAILY-PROC
END-EVALUATE
EVALUATE vs IF文 の使い分け
| 観点 | EVALUATE | IF文 |
|---|---|---|
| 分岐の多さ | ◎(3分岐以上に最適) | △(多いとネストが深くなる) |
| 単純な2分岐 | △(記述が冗長になる) | ◎(IF…ELSE が簡潔) |
| 範囲指定 | ◎(THRU で簡潔に書ける) | ○(>= AND <= で書ける) |
| 複数変数の組み合わせ | ◎(ALSO で判定表を実装) | △(AND/OR の複雑なネストが必要) |
| 可読性 | ◎(縦に整列で一覧性が高い) | △(条件が増えると読みにくい) |
| 条件式の柔軟さ | ○(EVALUATE TRUE で対応) | ◎(どんな条件式も書ける) |
*> ---- Before: IF文ネスト ----
IF WS-CODE = "A"
IF WS-AMOUNT > 100000
PERFORM HIGH-A-PROC
ELSE
PERFORM LOW-A-PROC
END-IF
ELSE IF WS-CODE = "B"
PERFORM B-PROC
ELSE
PERFORM OTHER-PROC
END-IF
*> ---- After: EVALUATE TRUE で整理 ----
EVALUATE TRUE
WHEN WS-CODE = "A" AND WS-AMOUNT > 100000
PERFORM HIGH-A-PROC
WHEN WS-CODE = "A" AND WS-AMOUNT <= 100000
PERFORM LOW-A-PROC
WHEN WS-CODE = "B"
PERFORM B-PROC
WHEN OTHER
PERFORM OTHER-PROC
END-EVALUATE
実践パターン集
パターン1:ファイル処理のステータスコード分岐
01 WS-FILE-STATUS PIC X(2).
EVALUATE WS-FILE-STATUS
WHEN "00"
CONTINUE *> 正常
WHEN "10"
SET END-OF-FILE TO TRUE *> ファイル終端
WHEN "22"
DISPLAY "重複キーエラー: " WS-FILE-STATUS
PERFORM DUPLICATE-KEY-PROC
WHEN "23"
DISPLAY "レコードなし: " WS-FILE-STATUS
PERFORM NOT-FOUND-PROC
WHEN "34"
WHEN "35"
DISPLAY "ファイル未存在: " WS-FILE-STATUS
PERFORM FILE-NOT-EXIST-PROC
WHEN "90" THRU "99"
DISPLAY "システムエラー: " WS-FILE-STATUS
PERFORM SYSTEM-ERROR-PROC
WHEN OTHER
DISPLAY "未定義ステータス: " WS-FILE-STATUS
PERFORM UNKNOWN-ERROR-PROC
END-EVALUATE
パターン2:月次バッチ処理の実行制御
01 WS-PROC-DATE.
05 WS-YEAR PIC 9(4).
05 WS-MONTH PIC 9(2).
05 WS-DAY PIC 9(2).
01 WS-DOW PIC 9(1). *> 1:月 〜 7:日
01 WS-MONTH-END PIC X(1). *> Y:月末日
88 IS-WEEKDAY VALUE 1 THRU 5.
88 IS-WEEKEND VALUE 6 7.
EVALUATE WS-DOW ALSO WS-MONTH-END
WHEN 1 ALSO "Y"
*> 月末かつ月曜日: 月次+週次バッチ
PERFORM MONTHLY-BATCH
PERFORM WEEKLY-BATCH
PERFORM DAILY-BATCH
WHEN 1 ALSO "N"
*> 月曜日(月末以外): 週次+日次バッチ
PERFORM WEEKLY-BATCH
PERFORM DAILY-BATCH
WHEN 2 THRU 5 ALSO "Y"
*> 月末(月曜以外): 月次+日次バッチ
PERFORM MONTHLY-BATCH
PERFORM DAILY-BATCH
WHEN 2 THRU 5 ALSO "N"
*> 通常営業日: 日次バッチのみ
PERFORM DAILY-BATCH
WHEN 6 THRU 7 ALSO ANY
*> 土日は全バッチスキップ
DISPLAY "休日: バッチスキップ"
END-EVALUATE
パターン3:金融取引の審査判定
01 WS-CREDIT-RANK PIC X(1). *> A/B/C/D
01 WS-TRANS-AMOUNT PIC S9(9)V99 COMP-3.
01 WS-APPROVAL PIC X(2).
EVALUATE TRUE
*> Aランク: 金額問わず自動承認
WHEN WS-CREDIT-RANK = "A"
MOVE "OK" TO WS-APPROVAL
*> Bランク: 100万円以下なら自動承認
WHEN WS-CREDIT-RANK = "B"
AND WS-TRANS-AMOUNT <= 1000000
MOVE "OK" TO WS-APPROVAL
*> Bランク: 100万円超は目視審査
WHEN WS-CREDIT-RANK = "B"
AND WS-TRANS-AMOUNT > 1000000
MOVE "MN" TO WS-APPROVAL *> Manual
*> Cランク: 10万円以下のみ自動承認
WHEN WS-CREDIT-RANK = "C"
AND WS-TRANS-AMOUNT <= 100000
MOVE "OK" TO WS-APPROVAL
*> C/Dランク: その他は否決
WHEN WS-CREDIT-RANK = "C"
WHEN WS-CREDIT-RANK = "D"
MOVE "NG" TO WS-APPROVAL
WHEN OTHER
MOVE "ER" TO WS-APPROVAL
END-EVALUATE
パターン4:CONTINUE を使った「何もしない」処理
*> 特定のステータスは処理をスキップしたい場合
EVALUATE WS-PROC-STATUS
WHEN "SKIP"
WHEN "VOID"
CONTINUE *> 明示的に何もしない
WHEN "ACTIVE"
PERFORM ACTIVE-PROC
WHEN "PENDING"
PERFORM PENDING-PROC
WHEN OTHER
PERFORM DEFAULT-PROC
END-EVALUATE
WHEN 句の後に処理を書かないと、コンパイラによってはエラーや警告が出る場合があります。「何もしない」ことを明示したい場合は
CONTINUE 文を書くことで意図が伝わりやすくなります。詳しくは EVALUATE文での「何もしない」処理 をご参照ください。よくある質問
WHEN "A" WHEN "B" PERFORM PROC)。IF...ELSE の方が簡潔です。複数変数の組み合わせ判定(判定表)は ALSO を使った EVALUATE が圧倒的に読みやすくなります。IF文の詳細解説 も合わせてご参照ください。WHEN OTHER を記述し、エラーログの出力や異常終了処理を入れることを推奨します。EVALUATE WS-CODE ALSO WS-LEVEL に対して WHEN "A" THRU "C" ALSO 1 THRU 3 のように範囲指定と複数主語を組み合わせることが可能です。ただし組み合わせが複雑になりすぎると保守性が下がるため、PERFORM で処理を分割することも検討してください。まとめ
EVALUATE文のポイントをまとめます。
- 基本:WHEN で値を一致判定。フォールスルーなし。WHEN OTHER で未定義値をカバー
- THRU:数値・文字コードの範囲を簡潔に指定。成績判定・コード区分に最適
- EVALUATE TRUE:IF-ELSE IFのネストを平坦化。条件式をそのまま WHEN に書ける
- ALSO:複数主語・複数客体の組み合わせ判定。判定表をコードに直接対応させられる
- WHEN ANY:ALSO 使用時に特定の主語をワイルドカード化
- 88レベル:条件名と EVALUATE を組み合わせると可読性が大幅に向上
- 使い分け:3分岐以上・範囲・組み合わせは EVALUATE、2分岐は IF で十分
関連記事:IF文を使った条件分岐の基本テクニック、EVALUATE文での「何もしない」処理(CONTINUE)、COMPUTEで計算を行う、PERFORM文でループ処理を行う
