【COBOL】EVALUATE文で複雑な条件分岐を実装する|THRU・ALSO・EVALUATE TRUE・88レベル活用完全ガイド

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文の基本構文
       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 と同義)を使うと、値の範囲を一括指定できます。数値・文字コード双方に使えます。

WHEN THRU で範囲を指定する
       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 は「下限 THRU 上限」の順で書きます。下限が上限より大きいとコンパイルエラーまたは意図しない動作になります。文字列の範囲比較は照合順序(COLLATING SEQUENCE)に依存するため、環境定義を確認してください。

EVALUATE TRUE / EVALUATE FALSE:条件式で分岐

EVALUATE TRUE は主語に TRUE を指定し、WHEN 句に条件式を書きます。IF-ELSE IF-ELSE のネストを平坦化するのに最も効果的なパターンです。

EVALUATE TRUE で複合条件を整理する
       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
EVALUATE TRUE の評価は上から順番
最初にTRUEになった WHEN で処理が実行され、以降の WHEN は評価されません。条件の順序が重要です。広い条件を後ろに、狭い条件(より具体的・特殊なケース)を前に書いてください。
EVALUATE FALSE:条件の否定パターン
       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 で区切ることで、複数条件の組み合わせ(判定表・デシジョンテーブル)を表現できます。

ALSO による2変数の組み合わせ判定
       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 を使います。

WHEN 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 を使うと判定表がコードになる
システム設計書に「判定表(デシジョンテーブル)」が定義されている場合、ALSO を使った EVALUATE は設計書と1対1で対応させやすく、
レビューや保守のときに仕様と照合しやすくなります。

88レベル条件名との組み合わせ

COBOLの88レベル条件名は値に名前を付ける仕組みです。EVALUATE と組み合わせると、コードがより読みやすくなります。

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
88レベルを 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 で対応) ◎(どんな条件式も書ける)
IF文のネストを 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:ファイル処理のステータスコード分岐

ファイルSTATUSコードによるエラーハンドリング
       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 を使った「何もしない」処理

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
CONTINUE の使い方
WHEN 句の後に処理を書かないと、コンパイラによってはエラーや警告が出る場合があります。「何もしない」ことを明示したい場合は CONTINUE 文を書くことで意図が伝わりやすくなります。詳しくは EVALUATE文での「何もしない」処理 をご参照ください。

よくある質問

QEVALUATE でフォールスルー(fall-through)はできますか?
Aできません。COBOLの EVALUATE は C言語の switch と異なり、一致した WHEN の処理が終わると自動的に END-EVALUATE へ進みます。複数の WHEN に同じ処理を実行したい場合は、WHEN 句を連続して記述してください(WHEN "A" WHEN "B" PERFORM PROC)。
QEVALUATE の中に EVALUATE を入れることはできますか?
Aできます。WHEN 句の中に別の EVALUATE 文を書くことが可能です。ただし深いネストは可読性を下げます。ALSO を使った複数主語判定か、処理を別段落(PERFORM)に分離することを検討してください。
QEVALUATE と IF 文はどちらを優先すべきですか?
A分岐が3つ以上になる場合は EVALUATE の方が可読性が高くなります。2分岐の単純な条件は IF...ELSE の方が簡潔です。複数変数の組み合わせ判定(判定表)は ALSO を使った EVALUATE が圧倒的に読みやすくなります。IF文の詳細解説 も合わせてご参照ください。
QWHEN OTHER を省略しても問題ありませんか?
A省略可能ですが、省略するとどの WHEN にも一致しない値が来たとき何も処理されずに END-EVALUATE へ進みます。予期しないデータへの対応漏れを防ぐため、業務プログラムでは原則として WHEN OTHER を記述し、エラーログの出力や異常終了処理を入れることを推奨します。
QTHRU と ALSO は同じ WHEN 句で組み合わせられますか?
Aできます。例えば 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文でループ処理を行う