データ項目の評価 (組み込み関数)

いくつかの組み込み関数は、データ項目の評価に使用できます。

照合順序に関する単一文字の評価 (CHAR、ORD)

特定の文字の照合順序における順序位置を知りたい場合、 その文字を引き数にして ORD 関数を参照すると、ORD はその順序位置を示す整数を戻します。 これを行うための 1 つの便利な方法は、 データ項目のサブストリングを ORD の引き数として使用する方法です。

   IF FUNCTION ORD (CUSTOMER-RECORD(1:1)) IS > 194 THEN ...

一方、照合順序における順序位置は分かっているが、それに対応する文字が分からないという場合、 次のように整数の順序位置を引き数にして CHAR 関数を参照すれば、CHAR がその文字を戻します。

   INITIALIZE CUSTOMER-NAME REPLACING ALPHABETIC BY FUNCTION CHAR(65).

英数字関数によって可変長の結果を戻す

英数字関数の結果は、その長さや値が関数の引き数によって変わる場合があります。

次の例の場合、R3 に移動されたデータの量と COMPUTE ステートメントの結果は、R1 および R2 の値とサイズによって変わります。

    01 R1            PIC X(10) VALUE "e".
    01 R2            PIC X(05) VALUE "f".
    01 R3            PIC X(05) VALUE "g".
    01 R4            PIC X(20) VALUE SPACES.
    01 L             PIC 99.
    .
    .
    .
    MOVE FUNCTION MEAN(R1 R2 R3) TO R4.
    COMPUTE L = FUNCTION LENGTH(FUNCTION MEAN(R1 R2 R3)).

ここで R2 の評価結果は中間値となります。 したがって、記号   でブランク・スペースを表すとすると、 ストリング「f    」が R4 に移動され、(R4 のうち文字が入っていない桁にはスペースが入れられる)、L の評価結果は値 5 になります。 R1 が値「f」なら、R1 が中間値となり、 ストリング「f         」が R4 に移動され (R4 のうち文字が入っていない桁にはスペースが入れられる)、 値 10 が L に代入されます。

英数字関数からの可変長結果を処理する場合があります。 プログラム・コードをそれにしたがって計画してください。 たとえば次のように、書き込むレコードの長さが異なる可能性がある場合、 可変長レコード・ファイルの使用を考慮する必要があります。

   
   FILE SECTION.
FD OUTPUT-FILE.
01 CUSTOMER-RECORD     PIC X (80).
WORKING-STORAGE SECTION.
01 R1                     PIC X (50).
01 R2                     PIC X (70).
.
.
.
WRITE CUSTOMER-RECORD FROM FUNCTION MEAN(R1 R2 R3).

最大データ項目または最小データ項目の検索 (MAX、MIN、ORD-MAX、ORD-MIN)

複数の英数字データ項目があり、どのデータ項目が最大値 (照合シーケンスに従って 評価される) を含んでいるかを知りたい場合は、MAX 関数または ORD-MAX 関数を使用して、 そのデータ項目を引き数として提供します。どのデータ項目が最小値を含んでいるかを 知りたい場合は、MIN 関数または ORD-MIN 関数を使用します。

MAX および MIN

MAX 関数および MIN 関数は、単に、提供した変数のどれかの内容を戻すだけです。 たとえば、以下のデータ定義では、

05 Arg1 Pic x(10) Value "THOMASSON ".
05 Arg2 Pic x(10) Value "THOMAS ".
05 Arg3 Pic x(10) Value "VALLEJO ".

次のステートメント

Move Function Max(Arg1 Arg2 Arg3) To Customer-record(1:10)

は、「VALLEJO   」を、Customer-record の最初の 10 文字の位置に 割り当てます。

注:
ブランクは「 」で表しています。

代わりに MIN を使用すると、「THOMAS    」が戻されます。

ORD-MAX および ORD-MIN

ORD-MAX 関数および ORD-MIN 関数は、指定した引き数リスト内での、最大値または最小値 をもった引き数の (左から数えた) 順番を表す整数を戻します。上記の例で ORD-MAX 関数 を使用すると、コンパイル時に構文エラー・メッセージを受け取ります。 これは、正しくない場所で数字関数を参照しようとするためです (「WebSphere Development Studio: ILE COBOL 解説書」を参照)。 次の例は、ORD-MAX 関数の正しい例です。

Compute x = Function Ord-max(Arg1 Arg2 Arg3)

前の例と同じ引き数を使用した場合、 これによって、整数 3 が x に割り当てられます。ORD-MIN を使用すると、 整数 2 が戻されます。

注:
この関数グループは、 数値に対しても使用できます。この場合、引き数の代数値が比較されます。詳細については、演算式を参照してください。上記の例は、Arg1、Arg2、および Arg3 が、 配列テーブルの連続するエレメントである場合に、より現実的なものになります。 テーブル・エレメントを関数引き数として使用する場合の説明については、テーブル項目の処理を参照してください。
英数字関数によって可変長の結果を戻す

英数字関数の結果は、その長さや値が関数の引き数によって変わる場合があります。 次の例の場合、R3 に移動されたデータの量と COMPUTE ステートメントの結果は、R1 および R2 の値とサイズによって変わります。

01 R1 Pic x(10) value "e".
01 R2 Pic x(05) value "f".
01 R3 Pic x(20) value spaces.
01 L Pic 99.
.
.
Move Function Max(R1 R2) to R3
Compute L = Function Length(Function Max(R1 R2))

ここで、R2 は、R1 より大きい値と評価されます。したがって、 記号   がブランク・スペースを表すとすると、 ストリング「f    」が R3 に移動され (R3 のうち埋め込みのない文字位置 にはスペースが入れられる)、L の評価結果は値 5 になります。 R1 が値「g」の場合は、R1 は R2 より大きくなり、 ストリング「g         」が R3 に 移動され (R3 のうち埋め込みのない文字位置にはスペースが入れられる)、値 10 が L に代入されます。

英数字関数からの可変長結果を処理する場合があります。 プログラム・コードをそれにしたがって計画してください。 たとえば次のように、書き込むレコードの長さが異なる可能性がある場合、 可変長レコード・ファイルの使用を考慮する必要があります。

File Section.
FD Output-File.
01 Customer-Record Pic X(80).
Working-Storage Section.
01 R1 Pic x(50).
01 R2 Pic x(70).
.
.
Write Customer-Record from Function Max(R1 R2)

データ項目の長さを調べる (LENGTH)

LENGTH 関数は、多くのプログラミング・コンテキストでストリング項目の長さを調べるのに役立ちます。 次の ILE COBOL ステートメントは、得意先名などのデータ項目を、得意先名用レコードの特定のフィールドに移動します。

  
  MOVE CUSTOMER-NAME TO CUSTOMER-RECORD(1:FUNCTION LENGTH(CUSTOMER-NAME)).
注:
LENGTH 関数は、数字データ項目やテーブル項目でも使用できます。
LENGTH OF 特殊レジスター

LENGTH 関数のほかに、データ項目の長さを検出するための方法は、LENGTH OF 特殊レジスターを使用する方法です。

LENGTH OF 特殊レジスターと LENGTH 組み込み関数は、基本的に異なっています。 FUNCTION LENGTH はある項目の長さを文字位置数で戻すのに対して、LENGTH OF はバイト数で戻します。 大抵の場合、DBCS クラスの項目を別にすれば、結果は大差ありません。

たとえば、

77 CUSTOMER-NAME PIC X(30).
77 CUSTOMER-LOCATION-ASIA PIC G(50).
FUNCTION LENGTH(CUSTOMER-NAME)

とコーディングしても LENGTH OF CUSTOMER-NAME とコーディングしても 30 を戻しますが、FUNCTION LENGTH(CUSTOMER-LOCATION-ASIA) は 50 を戻し、LENGTH OF CUSTOMER-LOCATION-ASIA は 100 を戻します。

LENGTH 関数は演算式を指定できる場合しか使用できませんが、LENGTH OF 特殊レジスターはさまざまなコンテキストで使用できます。 たとえば、LENGTH OF 特殊レジスターを、整数引き数の可能な組み込み関数の引き数として使用することができます。 (組み込み関数は、LENGTH OF 特殊レジスターのオペランドとしては使用できません。) LENGTH OF 特殊レジスターは、CALL ステートメントのパラメーターとしても使用できます。

コンパイル日付を調べる (WHEN-COMPILED)

システムによって提供されるプログラムのコンパイル日時を知るには、WHEN-COMPILED 関数を使用できます。 戻される結果は 21 桁で、最初の 16 桁の形式は以下のとおりです。

    YYYYMMDDhhmmsshh

これは、コンパイル日時を 4 桁年、月、日、時刻 (時、分、秒、1/100 秒) で示したものです。

WHEN-COMPILED 特殊レジスター

WHEN-COMPILED 特殊レジスターは、コンパイル日時を調べるためのもう一つの方法です。 形式は次のとおりです。

    MM/DD/YYhh.mm.ss

WHEN-COMPILED 特殊レジスターがサポートする年は 2 桁だけで、時刻も秒までです。 この特殊レジスターは、MOVE ステートメントの送り出しフィールドとしてのみ使用できます。

日時データ項目についてテストする (TEST-DATE-TIME)

日時、英数字、数値パック、またはゾーン項目が有効な日付、時刻、またはタイム・スタンプであるかどうかを知りたい場合には、TEST-DATE-TIME 組み込み関数を使用できます。 ADD-DURATION、または SUBTRACT-DURATION など別の日時組み込み関数を使用して移動または計算を完了する前に有効な日時データ項目についてテストすることは有用です。 次の例は、日時データ項目についてのテスト方法を示しています。

IF FUNCTION TEST-DATE-TIME (date-3 DATE) = B'1'
   MOVE DATE-3 TO CUTOFF-DATE.

日付および時刻期間を処理する (ADD-DURATION、FIND-DURATION、SUBTRACT-DURATION)

組み込み関数を使用して、日付、時刻、およびタイム・スタンプの期間を処理することができます。 たとえば、日付が 2 つあり、その 2 つの日付の間が何カ月であるかを知りたい場合には、FIND-DURATION 関数を使用して、 これを計算することができます。 また、ADD-DURATION および SUBTRACT-DURATION 組み込み関数を使用して、満期日および失効日 (すでに経過した日付) を計算することもできます。

日時データ項目の使用法については 日時データ・タイプを処理するを参照してください。

2 つの日付間の期間を見つける例

次の例は、日時形式の 2 つの日付間の日数を計算する方法を示しています。

01 YYYYMMDD          FORMAT DATE "@Y%m%d".
01 EXPIRY-DATE       FORMAT DATE "%m/%d/@Y"  VALUE "10/31/1997".
01 DURATION          PIC S9(5).
   .
   .
   .
    MOVE FUNCTION CURRENT-DATE(1:8) TO YYYYMMDD.
    COMPUTE DURATION = FUNCTION FIND-DURATION (YYYYMMDD EXPIRY-DATE DAYS).
        IF DURATION <= 0 THEN
          DISPLAY 'Expiry date, ' EXPIRY-DATE ' has passed.'
    END-IF.

上記の FIND-DURATION 組み込み関数は、EXPIRY-DATE から YYYYMMDD を減じます。 YYYYMMDD の日付が 1997 年 10 月 31 日より後になった場合、期間は負の値として戻されます。 ゼロ日数または負の日数の期間は、満了を表します。

現在日付が 1997 年 11 月 1 日であるとすれば、上記プログラムの出力は、次のようになります。

Expiry date 10/31/1997 has passed.
満期日の計算の例

次の例は、日時形式の満期日の計算方法を示しています。

01 YYYYMMDD          FORMAT DATE "@Y%m%d".
01 DATE-TIME-FORM    FORMAT DATE "%m/%d/@Y".
   .
   .
   .
    MOVE FUNCTION CURRENT-DATE(1:8) TO YYYYMMDD.
    MOVE FUNCTION ADD-DURATION (YYYYMMDD DAYS 90) TO DATE-TIME-FORM.
    DISPLAY 'Due Date: ' DATE-TIME-FORM.

現在日付が 1997 年 10 月 8 日であるとすれば、上記プログラムの出力は、次のようになります。

Due Date: 01/06/1998
失効日の計算の例

日付が過ぎてしまったために、その日付の記載されているもの (たとえば、小切手) が失効したかどうかを計算するには、 次のように SUBTRACT-DURATION 組み込み関数を使用できます。

01 YYYYMMDD                    FORMAT DATE "@Y%m%d".
01 STALE-DATE                  FORMAT DATE "%m/%d/@Y".
01 cheque-date                 FORMAT DATE "%m/%d/@Y"  VALUE "03/09/1997".
   .
   .
   .
    MOVE FUNCTION CURRENT-DATE(1:8) TO YYYYMMDD.
    MOVE FUNCTION SUBTRACT-DURATION (YYYYMMDD DAYS 180) TO STALE-DATE.
    IF STALE-DATE > cheque-date THEN
       DISPLAY 'Cheque date, ' cheque-date ', is stale-dated.'
       DISPLAY 'The stale-date is: ' STALE-DATE
    END-IF.

現在日付が 1997 年 10 月 8 日であるとすれば、上記プログラムの出力は、次のようになります。

Cheque date, 03/09/1997, is stale-dated.
The stale date is: 04/11/1997