【COBOL学習|豆知識】ORD-MAX/ORD-MINの罠:戻り値は「値」ではなく「順序」である!

導入

COBOLの組込関数の中でも、データの大小を比較する際に重宝するのが「ORD-MAX」や「ORD-MIN」です。しかし、ベテランの私でも若手がよく勘違いしてバグを生むのが「戻り値の正体」です。これらは最大値や最小値そのものを返すのではなく、リストの「何番目か」を返す関数です。この仕様を理解していないと、計算結果が全く別の意味を持ってしまい、システム障害の原因となります。今回は、この「序数」という概念を正しく扱い、安全に実装する方法を解説します。

基礎知識

COBOLの組込関数「FUNCTION ORD-MAX(引数1, 引数2, …)」および「FUNCTION ORD-MIN」は、引数として指定されたリストの中で、辞書順(文字コード順)で最大または最小となるものが、リストの「何番目(1番目からカウント)」に位置しているかを返します。
重要なのは、戻り値の型です。これは数値(Integer)として返されるため、受け取るデータ項目は必ず「PIC 9」などの数字項目で定義しなければなりません。文字列項目で受け取ろうとすると、予期せぬ桁落ちやデータ変換エラーが発生するリスクがあります。

実装/解決策

この関数の正しい使い方は、得られた「序数」を使って、実際の値を再度参照することです。つまり、以下の二段階の処理を行うのが鉄則です。
1. ORD-MAX/MINで「位置(インデックス)」を取得する。
2. 取得した位置を使って、配列(テーブル)から実データを取得する。

サンプルプログラム

以下のコードは、3つの文字列の中から辞書順で最も大きいものが何番目にあるかを特定し、その値を表示する例です。

IDENTIFICATION DIVISION.
PROGRAM-ID. ORD-TEST.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-DATA-TABLE.
05 FILLER PIC X(5) VALUE “APPLE”.
05 FILLER PIC X(5) VALUE “ZEBRA”.
05 FILLER PIC X(5) VALUE “BETA “.
01 REDEFINES WS-DATA-TABLE.
05 TBL-ITEM OCCURS 3 TIMES PIC X(5).

01 WS-INDEX PIC 9(02).

PROCEDURE DIVISION.
> 引数の中で最大のものが何番目かを取得 (ここではZEBRAが2番目なので2が返る)
COMPUTE WS-INDEX = FUNCTION ORD-MAX(TBL-ITEM(1)
TBL-ITEM(2)
TBL-ITEM(3)).

DISPLAY “最大値のインデックスは: ” WS-INDEX.

> 序数を使って実際の値を取り出す
DISPLAY “その値は: ” TBL-ITEM(WS-INDEX).

GOBACK.

応用・注意点

現場でこの関数を使う際に最も注意すべき点は、「引数に指定した項目の数と、テーブルのインデックスがずれる可能性」です。例えば、引数にハードコーディングで項目を羅列すると、保守の際に項目が増減したときにFUNCTIONの引数を書き直す必要があり、非常に危険です。
可能であれば、上記サンプルコードのようにテーブル(OCCURS句)を使用し、動的に制御できる設計にすることをお勧めします。また、比較対象が全角文字(漢字など)の場合、システム環境の文字コードセット(EBCDICやUTF-8など)によって「辞書順」の定義が異なる場合があるため、ソート順序に依存したロジックを組む際は、必ず実行環境のコード表を確認するようにしてください。

コメント

タイトルとURLをコピーしました