論理条件基準

このドキュメントでは、ステートメント FINDREADHISTOGRAMACCEPT/REJECTIFDECIDE FORREPEAT で使用できる論理条件基準の目的および使用方法を説明します。

以下のトピックについて説明します。


はじめに

基本の条件は、1 つの関係式です。複数の関係式を論理演算子(ANDOR)と組み合わせて、複合条件を構成することができます。

また、演算式を使用して、1 つの関係式を構成することもできます。

論理条件基準は、以下のステートメントで使用できます。

ステートメント 使用方法
FIND 論理条件基準を持つ WHERE 節を使用して、WITH 節で指定されている基本選択条件に、さらに条件を追加します。WHERE 節で指定されている論理条件基準は、レコードの選択および読み込み後に評価されます。

WITH 節では、論理条件基準ではなく、(FIND ステートメントで記述されている)"基本検索条件" が使用されます。

READ 論理条件基準を持つ WHERE 節を使用して、読み込んだレコードを処理するかどうかを指定します。論理条件基準は、レコードの読み込み後に評価されます。
HISTOGRAM 論理条件基準を持つ WHERE 節を使用して、読み込んだ値を処理するかどうかを指定します。論理条件基準は、値の読み込み後に評価されます。
ACCEPT/REJECT FINDREAD、または HISTOGRAM ステートメントでレコードが選択され、読み込まれる場合、IF 節を ACCEPT または REJECT ステートメントで使用して、指定された条件に加えて論理条件の基準を指定することもできます。論理条件の基準は、レコードが読み込まれ、レコードの処理が開始した後に評価されます。
IF 論理条件の基準を使用して、ステートメントの実行を制御します。
DECIDE FOR 論理条件の基準を使用して、ステートメントの実行を制御します。
REPEAT REPEAT ステートメントの UNTIL 節または WHILE 節に、いつ処理ループを終了するのかを決定する論理条件基準を指定します。

関係式

構文:

operand1

EQ
=
EQUAL
EQUAL TO
NE
^=
<>
NOT =
NOT EQ
NOTEQUAL
NOT EQUAL
NOT EQUAL TO
LT
LESS THAN
<
GE
GREATER EQUAL
>=
NOT <
NOT LT
GT
GREATER THAN
>
LE
LESS EQUAL
<=
NOT >
NOT GT

operand2

オペランド定義テーブル:

オペランド 構文要素 フォーマット オペランド参照 ダイナミック定義
operand1 C S A   N E A U N P I F B D T L   G O
operand2 C S A   N E A U N P I F B D T L   G O ×

上記オペランド定義テーブルの詳細については、『ステートメント』ドキュメントの「構文記号およびオペランド定義テーブル」を参照してください。

上記の表の "構文要素" の "E" は、算術式を表します。つまり、関係式のオペランドとして算術式を指定できることを意味します。算術式の詳細については、COMPUTE ステートメントの説明にある arithmetic-expression を参照してください。

比較演算子の説明:

比較演算子 説明

EQ
=
EQUAL
EQUAL TO

等しい

NE
^=
<>
NOT =
NOT EQ
NOTEQUAL
NOT EQUAL
NOT EQUAL TO

等しくない

LT
LESS THAN
<

より小さい

GE
GREATER EQUAL
>=

より大きいまたは等しい

NOT <
NOT LT

以上

GT
GREATER THAN
>

より大きい

LE
LESS EQUAL
<=

より小さいまたは等しい

NOT >
NOT GT

以下

関係式の例:

IF NAME = 'SMITH'
IF LEAVE-DUE GT 40
IF NAME = #NAME

関係式における配列の比較については、「配列の処理」を参照してください。

注意:
浮動小数点のオペランドを使用すると、浮動小数点で比較が実行されます。浮動小数点数自体の精度に制限があるため、数値と浮動小数点形式との変換を行うときに、切り上げ/切り捨てエラーを回避することはできません。

論理条件における算術式

以下の例は、論理条件で算術式をどのように使用するかを示しています。

IF #A + 3 GT #B - 5 AND #C * 3 LE #A + #B

論理条件におけるハンドル

関係式のオペランドがハンドルの場合、演算子 EQUAL および NOT EQUAL のみを使用できます。

関係式における SUBSTRING オプション

構文:

SUBSTRING (operand1,operand3,operand4)
operand1

=
EQ
EQUAL [TO]
<>
NE
NOT =
NOT EQ
NOT EQUAL
NOT EQUAL TO
<
LT
LESS THAN
<=
LE
LESS EQUAL
>
GT
GREATER THAN
>=
GE
GREATER EQUAL

operand2
SUBSTRING (operand2,operand5,operand6)

オペランド定義テーブル:

オペランド 構文要素 フォーマット オペランド参照 ダイナミック定義
operand1 C S A   N   A U         B            
operand2 C S A   N   A U         B             ×
operand3 C S             N P I   B             ×
operand4 C S             N P I                 ×
operand5 C S             N P I                 ×
operand6 C S             N P I                 ×

SUBSTRING オプションを使用すると、英数字、バイナリ、または Unicode の各フィールドの一部を比較できます。フィールド名(operand1)の後にまず開始位置(operand3)を指定し、次に、フィールドの比較する部分の長さoperand4)を指定します。

また、フィールド値を別のフィールド値の一部と比較することもできます。フィールド名(operand2)の後にまず開始位置(operand5)を指定し、次に、フィールド operand1 の比較する部分の長さ(operand6)を指定します。

両方の形式を組み合わせることもできます。つまり、SUBSTRINGoperand1operand2の両方に指定できます。

例:

以下の式は、フィールド #A の値の 5~12 桁目とフィールド #B の値を比較しています。

SUBSTRING(#A,5,8) = #B

- 5 が開始位置で、8 が長さです。

以下の式は、フィールド #A の値とフィールド #B の値の 3~6 桁目を比較しています。

#A = SUBSTRING(#B,3,4)

注意:
operand3/operand5 を省略すると、開始位置は 1 とみなされます。operand4/operand6 を省略すると、長さはフィールドの開始位置から終わりまでとみなされます。

拡張関係式

構文:

operand1

=
EQ
EQUAL [TO]

operand2
 

OR

=
EQ
EQUAL [TO]

operand3

THRU operand4 [BUT NOT operand5 [THRU operand6]]

オペランド定義テーブル:

オペランド 構文要素 フォーマット オペランド参照 ダイナミック定義
operand1 C S A   N* E A U N P I F B D T     G O ×
operand2 C S A   N* E A U N P I F B D T     G O ×
operand3 C S A   N* E A U N P I F B D T     G O ×
operand4 C S A   N* E A U N P I F B D T     G O ×
operand5 C S A   N* E A U N P I F B D T     G O ×
operand6 C S A   N* E A U N P I F B D T     G O ×

* 算術関数およびシステム変数は使用できますが、ブレイク関数は使用できません。

operand3 は、以下のように、MASK オプションまたは SCAN オプションを使用して指定することもできます。

MASK (mask-definition) [operand]
MASKoperand
SCANoperand

これらのオプションの詳細については、「MASK オプション」および「SCAN オプション」を参照してください。

例:

IF #A = 2 OR = 4 OR = 7
IF #A = 5 THRU 11 BUT NOT 7 THRU 8

論理変数の評価

構文:

operand1

このオプションは、論理変数(フォーマット L)はとともに使用します。論理変数の値は、TRUE または FALSE になります。operand1 には、使用する論理変数名を指定します。

オペランド定義テーブル:

オペランド 構文要素 フォーマット オペランド参照 ダイナミック定義
operand1 C S A                         L       × ×

論理変数の例:

** Example 'LOGICX05': Logical variable in logical condition
************************************************************************
DEFINE DATA LOCAL
1 #SWITCH (L)  INIT <true>
1 #INDEX  (I1)
END-DEFINE
*
FOR #INDEX 1 5
  WRITE NOTITLE #SWITCH (EM=FALSE/TRUE) 5X 'INDEX =' #INDEX
  WRITE NOTITLE #SWITCH (EM=OFF/ON) 7X 'INDEX =' #INDEX
  IF #SWITCH
    MOVE FALSE TO #SWITCH
  ELSE
    MOVE TRUE TO #SWITCH
  END-IF
  /*
  SKIP 1
END-FOR
END

プログラム LOGICX05 の出力:

TRUE     INDEX =    1
ON       INDEX =    1
 
FALSE    INDEX =    2
OFF      INDEX =    2
 
TRUE     INDEX =    3
ON       INDEX =    3
 
FALSE    INDEX =    4
OFF      INDEX =    4
 
TRUE     INDEX =    5
ON       INDEX =    5

論理条件基準内で使用するフィールド

データベースフィールドおよびユーザー定義変数は、論理条件基準を構成するために使用できます。マルチプルバリューフィールドであるデータベースフィールド、またはピリオディックグループに含まれているデータベースフィールドも使用できます。マルチプルバリューフィールドに値の範囲が指定されている、またはピリオディックグループにオカレンスの範囲が指定されている場合、検索値がその範囲の値/オカレンス内で検出されると、条件は真になります。

使用する値はそれぞれ、式の反対側で使用されているフィールドと互換性がある必要があります。10 進数表記は、数値フィールドに対する値にのみ指定します。また、値の小数部の桁数は、フィールドに定義されている小数部の桁数と一致させる必要があります。

オペランドのフォーマットが異なる場合、2 番目のオペランドが最初のオペランドのフォーマットに変換されます。

注意:
小数点表記のない数値定数は、値が -2147483648+2147483647 の場合はフォーマット I で格納されます。「数値定数」を参照してください。したがって、このような整数定数を operand1 とする比較は、operand2 を整数値に変換することにより実行されます。これは、operand2 の小数点以下の値は切り捨てられるため、比較の対象とみなされないことを意味します。

例:

 IF 0 = 0.5  	 /* is true because 0.5 (operand2) is converted to 0 (format I of operand1)
 IF 0.0 = 0.5  /* is false 
 IF 0.5 = 0  	 /* is false 
 IF 0.5 = 0.0  /* is false 

以下の表に、論理条件で一緒に使用できるオペランドのフォーマットを示します。

operand1 operand2
A U Bn (n=<4) Bn (n>=5) D T I F L N P GH OH
A                  
U [2] [2]                  
Bn (n=<4)      
Bn (n>=5)                  
D            
T            
I       ○       
F            
L                          
N            
P            
GH [1]                        
OH [1]                        

注意:

  1. 1) ここで、GH は GUI ハンドルを表し、OH はオブジェクトハンドルを表します。
  2. 2) バイナリ値には Unicode コードポイントが格納されているものとします。また、比較は、2 つの Unicode 値の比較として実行されます。バイナリフィールドの長さは偶数である必要があります。

2 つの値を英数字値として比較する場合、長い方の値と同じ長さにするために、末尾に空白を追加して短い方の値を拡張するものとします。

2 つの値をバイナリ値として比較する場合、長い方の値と同じ長さにするために、先頭にバイナリゼロを挿入して短い方の値を拡張するものとします。

2 つの値を Unicode 値として比較する場合、両方の値の末尾の空白を削除してから、ICU 照合アルゴリズムを使用して 2 つの値を比較します。『Unicode とコードページのサポート』ドキュメントの「論理条件の基準」も参照してください。

比較の例:

A1(A1) := 'A'            
A5(A5) := 'A    '        
B1(B1) := H'FF'          
B5(B5) := H'00000000FF'  
U1(U1) := UH'00E4'       
U2(U2) := UH'00610308'   
IF A1 = A5 THEN ...                 /* TRUE 
IF B1 = B5 THEN ...                 /* TRUE
IF U1 = U2 THEN ...                 /* TRUE 

配列とスカラ値を比較する場合、配列の各要素がスカラ値と比較されます。少なくとも 1 つの配列要素が条件を満たしていると、結果は真になります(OR 演算)。

配列と配列を比較する場合、配列の各要素が、もう一方の配列の対応する要素と比較されます。すべての要素の比較が条件を満たしている場合にのみ、結果は真になります(AND 演算)。

配列の処理」も参照してください。

注意:
Adabas フォネティックディスクリプタは、論理条件には使用できません。

論理条件基準の例:

FIND EMPLOYEES-VIEW WITH CITY = 'BOSTON' WHERE SEX = 'M'
READ EMPLOYEES-VIEW BY NAME WHERE SEX = 'M'
ACCEPT IF LEAVE-DUE GT 45
IF #A GT #B THEN COMPUTE #C = #A + #B
REPEAT UNTIL #X = 500

複雑な論理式における論理演算子

論理条件基準は、ブール演算子 ANDOR、および NOT を使用して組み合わせることができます。カッコを使用して論理グループを示すこともできます。

演算子は、以下の順序で評価されます。

優先順位 演算子 意味
1 ( ) カッコ
2 NOT 否定
3 AND AND オペレーション
4 OR OR オペレーション

以下の logical-condition-criteria を論理演算子で組み合わせることにより、複雑な論理式を作成できます。

logical-expression の構文は次のようになります。

[NOT]

logical-condition-criterion
(logical-expression)

OR

logical-expression

AND

論理式の例:

FIND STAFF-VIEW WITH CITY = 'TOKYO'
     WHERE BIRTH GT 19610101 AND SEX = 'F'
IF NOT (#CITY = 'A' THRU 'E')

論理式における配列の比較については、「配列の処理」を参照してください。

注意:
複数の論理条件基準が AND で組み合わされている場合、それらの条件のいずれかが偽になると即座に評価は終了します。

BREAK オプション - 現在の値を前回のループパス値と比較します

BREAK オプションでは、フィールドの現在の値または値の一部と、処理ループで前回通過した、同じフィールドの値とを比較できます。

構文:

BREAK [OF] operand1 [/n/]

オペランド定義テーブル:

オペランド 構文要素 フォーマット オペランド参照 ダイナミック定義
operand1   S         A U N P I F B D T L       ×

構文要素の説明:

operand1 チェックするコントロールフィールドを指定します。配列の特定のオカレンスをコントロールフィールドとして使用することもできます。
/n/

表記 /n/ を使用すると、値の変化を調べるためにチェックされるのは、コントロールフィールドの(左から右へ数えて)最初の n 個の位置だけであることを示すことができます。この表記は、フォーマット A、B、N、または P のオペランドに対してのみ使用できます。

指定した位置のフィールドの値が変わると、BREAK 操作の結果は真になります。AT END OF DATA 条件が発生すると、BREAK 操作の結果は偽になります。

例:

以下の例では、フィールド FIRST-NAME の最初の文字が変わっているかどうかがチェックされます。

BREAK FIRST-NAME /1/

このオプションには、Natural システム関数を使用できません(AT BREAK ステートメントでは使用可能)。

BREAK オプションの例:

** Example 'LOGICX03': BREAK option in logical condition
************************************************************************
DEFINE DATA LOCAL
1 EMPLOY-VIEW VIEW OF EMPLOYEES
  2 NAME
  2 FIRST-NAME
  2 BIRTH
*
1 #BIRTH (A8)
END-DEFINE
*
LIMIT 10
READ EMPLOY-VIEW BY BIRTH
  MOVE EDITED BIRTH (EM=YYYYMMDD) TO #BIRTH
  /*
  IF BREAK OF #BIRTH /6/
    NEWPAGE IF LESS THAN 5 LINES LEFT
    WRITE / '-' (50) /
  END-IF
  /*
  DISPLAY NOTITLE BIRTH (EM=YYYY-MM-DD) NAME FIRST-NAME 
END-READ 
END

プログラム LOGICX03 の出力:

  DATE            NAME              FIRST-NAME
   OF
 BIRTH
---------- -------------------- --------------------
  
1940-01-01 GARRET               WILLIAM
1940-01-09 TAILOR               ROBERT
1940-01-09 PIETSCH              VENUS
1940-01-31 LYTTLETON            BETTY
 
--------------------------------------------------
  
1940-02-02 WINTRICH             MARIA
1940-02-13 KUNEY                MARY
1940-02-14 KOLENCE              MARSHA
1940-02-24 DILWORTH             TOM
 
--------------------------------------------------
 
1940-03-03 DEKKER               SYLVIA
1940-03-06 STEFFERUD            BILL

IS オプション - 英数字フィールドまたは Unicode フィールドの内容を変換できるかどうかをチェックする

構文:

operand1 IS (format)

このオプションは、英数字フィールドまたは Unicode フィールド(operand1)の値を特定の別のフォーマットに変換できるかどうかをチェックするために使用します。

オペランド定義テーブル:

オペランド 構文要素 フォーマット オペランド参照 ダイナミック定義
operand1 C S A   N   A U                       ×

チェックできる format は、以下のとおりです。

Nll.ll 長さが ll.ll の数値
Fll 長さが ll の浮動小数点
D 日付。以下の日付フォーマットが使用できます。dd-mm-yydd-mm-yyyyddmmyyyydd = 日、mm = 月、yy または yyyy = 年)年、月、日の各コンポーネントの順序、およびコンポーネント間のデリミタ文字は、プロファイルパラメータ DTFORM(『パラメータリファレンス』を参照)によって決まります。
T 時刻(デフォルトの時刻表示フォーマットに依存)
Pll.ll 長さが ll.ll のパック型数値
Ill 長さが ll の整数値

チェック時は、operand1 の先頭および末尾の空白は無視されます。

IS オプションは、例えば、算術関数 VAL(英数字フィールドから数値を抽出)を実行する前にフィールドの内容をチェックして、ランタイムエラーが発生しないようにするために使用できます。

注意:
IS オプションで可能なのは、英数字フィールドの値が特定の"フォーマット"かどうかのチェックではなく、その"フォーマット"に変換できるかどうかのチェックです。値が特定のフォーマットかどうかをチェックするには、MASK オプションを使用します。詳細については、「IS オプションと MASK オプションの比較」および「パック型数値データまたはアンパック型数値データのチェック」を参照してください。

IS オプションの例:

** Example 'LOGICX04': IS option as format/length check
************************************************************************
DEFINE DATA LOCAL
1 #FIELDA (A10)          /* INPUT FIELD TO BE CHECKED
1 #FIELDB (N5)           /* RECEIVING FIELD OF VAL FUNCTION
1 #DATE   (A10)          /* INPUT FIELD FOR DATE
END-DEFINE
*
INPUT #DATE #FIELDA
IF #DATE IS(D)
  IF #FIELDA IS (N5)
    COMPUTE #FIELDB = VAL(#FIELDA)
    WRITE NOTITLE 'VAL FUNCTION OK' //  '=' #FIELDA '=' #FIELDB
  ELSE
    REINPUT 'FIELD DOES NOT FIT INTO N5 FORMAT'
            MARK *#FIELDA
  END-IF
ELSE
  REINPUT 'INPUT IS NOT IN DATE FORMAT (YY-MM-DD) '
          MARK *#DATE
END-IF
*
END

プログラム LOGICX04 の出力:

#DATE 150487    #FIELDA
 
 
 
 
 
 
 
 
 
INPUT IS NOT IN DATE FORMAT (YY-MM-DD)

MASK オプション - フィールドの指定の位置を特定の内容に照らしてチェックする

MASK オプションを使用すると、フィールドの特定の位置を特定の内容に照らしてチェックできます。

以下では次のトピックについて説明します。

定数マスク

構文:

operand1

=
EQ
EQUAL TO
NE
NOT EQUAL

MASK (mask-definition) [operand2]

オペランド定義テーブル:

オペランド 構文要素 フォーマット オペランド参照 ダイナミック定義
operand1 C S A   N   A U N P                   ×
operand2 C S         A U N P     B             ×

operand2 は、mask-definition に少なくとも 1 つの X が指定されている場合にのみ使用できます。operand1 および operand2 は、互換性のあるフォーマットである必要があります。

  • operand1 がフォーマット A の場合、operand2 はフォーマット A、B、N、または U である必要があります。

  • operand1 がフォーマット U の場合、operand2 はフォーマット A、B、N、または U である必要があります。

  • operand1 がフォーマット N または P の場合、operand2 はフォーマット N または P である必要があります。

mask-definition 内の X は、operand1 および operand2 の対応する位置を選択して比較します。

変数マスク

定数 mask-definition(上記参照)の他に、変数マスク定義を使用することもできます。

構文:

operand1

=
EQ
EQUAL TO
NE
NOT EQUAL

MASKoperand2

オペランド定義テーブル:

オペランド 構文要素 フォーマット オペランド参照 ダイナミック定義
operand1 C S A   N   A U N P                   ×
operand2   S         A U                       ×

operand2 の内容はマスク定義とみなされます。operand2 内の末尾の空白は無視されます。

  • operand1 がフォーマット A、N、または P の場合、operand2 はフォーマット A である必要があります。

  • operand1 がフォーマット U の場合、operand2 はフォーマット U である必要があります。

マスク内の文字

マスク定義(定数マスクのマスク定義、および変数マスクの operand2)には、以下の文字を使用できます。

文字 意味
. または ? または _ ピリオド、疑問符、または下線は、該当する 1 桁をチェックしないことを示します。
* または % アスタリスクまたはパーセント記号は、任意の桁数をチェックしないことを示すために使用します。
/ スラッシュ(/)は、値が特定の文字(または文字列)で終わっているかどうかをチェックするために使用します。

例えば、フィールドの最後が E であるか、または最後の E の後が空白以外に何もない場合、以下の条件は真になります。

IF #FIELD = MASK (*'E'/)
A 該当する桁が英字(大文字または小文字)かどうかをチェックします。
'c'

1 つ以上の桁が、アポストロフィで囲まれている文字列かどうかをチェックします。

チェックする文字は TQMARK パラメータに依存しません。引用符(")は引用符(")に対してチェックされます。

operand1 が Unicode フォーマットの場合、'c' に Unicode 文字が含まれている必要があります。

C 該当する桁が英字(大文字または小文字)、数字、または空白かどうかをチェックします。
DD 該当する 2 桁が有効な日の表記(01~31。MM および YY/YYYY が指定されていれば、その値に依存。「日付チェック」も参照)かどうかをチェックします。
H 該当する桁が 16 進数表記(A~F、0~9)かどうかをチェックします。
JJJ 該当する桁が有効なユリウス日、つまり年における日数(001~366。YY/YYYY が指定されていれば、その値に依存します。「日付チェック」も参照してください)。
L 該当する桁が小文字の英字(a~z)かどうかをチェックします。
MM 該当する桁が有効な月(01~12)かどうかをチェックします。「日付チェック」も参照してください。
N 該当する桁が数値かどうかをチェックします。
n... 1 つ(以上)の桁が 0 - n の範囲内の数値かどうかをチェックします。
n1-n2 または n1:n2 該当する桁が n1~n2 の範囲内の数値かどうかをチェックします。

n1 および n2 は同じ長さである必要があります。

P 該当する桁が表示可能な文字(U、L、N、または S)かどうかをチェックします。
S 該当する桁が特殊文字かどうかをチェックします。『オペレーション』ドキュメントの「NATCONV.INI での異なる文字セットのサポート」も参照してください。
U 該当する桁が大文字の英字(A~Z)かどうかをチェックします。
X 該当する桁が、マスク定義に続く値(operand2)の同じ位置の値と同じかどうかをチェックします。

X は、変数マスク定義では意味も持たないため、使用できません。

YY 該当する 2 桁が有効な年(00~99)かどうかをチェックします。「日付チェック」も参照してください。
YYYY 該当する 4 桁が有効な年(0000~2699)かどうかをチェックします。
Z 該当する桁の左側のハーフバイトが 16 進数の 3 または 7 で、右側のハーフバイトが 16 進数の 0~9 かどうかをチェックします。

これは、負数の数値に対しても正しくチェックできます。数値の符号は最後の桁に格納されるため、その桁は 16 進数の非数値とみなされます。したがって、(該当する桁が数値かどうかをチェックする)N では、負数の数値を正しくチェックできません。

マスク内では Z は、チェック対象の一連の数字ごとに一度だけ使用します。

マスク長

マスクの長さにより、チェックが必要な位置の数が決まります。

例:

DEFINE DATA LOCAL
1 #CODE (A15)
END-DEFINE
...
IF #CODE = MASK (NN'ABC'....NN)
...

上記の例では、#CODE の最初の 2 桁に対し、数値かどうかをチェックしています。その後の 3 桁は、定数 ABC かどうかをチェックしています。その次の 4 桁はチェックしていません。10 桁目および 11 桁目は、数値かどうかをチェックしています。12~15 桁目はチェックしていません。

日付チェック

指定するマスク内でチェックできる日付は 1 つのみです。同じ日付コンポーネント(JJJDDMMYY、または YYYY)がマスクで複数回指定されている場合、最後のオカレンスの値のみ、他の日付コンポーネントとの整合性がチェックされます。

日付に対するチェックでマスクに日(DD)を指定して月(MM)を指定しない場合、現在の月を想定してチェックが行われます。

日付に対するチェックでマスクに日(DD)またはユリウス日(JJJ)を指定して年(YY または YYYY)を指定しない場合、現在の年を想定してチェックが行われます。

日付を 2 桁の年(YY)でチェックするときにスライディングウィンドウも固定ウィンドウも設定されていない場合、現在の世紀を想定してチェックが行われます。スライディングウィンドウまたは固定ウィンドウの詳細については、『パラメータリファレンス』に記載されている、プロファイルパラメータ YSLW の説明を参照してください。

例 1

MOVE 1131 TO #DATE (N4)
IF #DATE = MASK (MMDD)

この例では、月と日の有効性をチェックしています。月に対する値(11)は有効とみなされますが、11 月には 30 日しかないため、日に対する値(31)は無効とみなされます。

例 2:

IF #DATE(A8) = MASK (MM'/'DD'/'YY)

この例では、フィールド #DATE の内容がフォーマット MM/DD/YY(月/日/年)の日付として有効かどうかをチェックしています。

例 3:

IF #DATE (A8) = MASK (1950-2020MMDD)

この例では、フィールド #DATE の内容が 1950~2020 の範囲内の 4 桁の数字とそれに続く有効な現在の年の月および日付かどうかをチェックしています。

注意:
当然ながら、上記のマスクでは、月と日付の整合性とは関係なく数値範囲 1950~2020 をチェックしているため、1950~2020 の範囲内で有効な年をチェックすることはできません。このチェックでは、2 月 29 日を除いて意図した結果が得られます。2 月 29 日の結果は、現在の年がうるう年かどうかによって異なります。日付の整合性に加えて指定の年の範囲をチェックするには、日付の整合性をチェックするコードと範囲の有効性をチェックするコードを別個に記述します。

IF #DATE (A8) = MASK (YYYYMMDD) AND #DATE = MASK (1950-2020)

例 4:

IF #DATE (A4) = MASK (19-20YY)

この例では、フィールド #DATE の内容が 19~20 の範囲内の 2 桁の数字とそれに続く有効な 2 桁の年(00~99)かどうかをチェックしています。Natural では、上記の方法で世紀を割り当てています。

注意:
明白なことですが、上記のマスクでは、年の整合性とは関係なく数値範囲 19~20 をチェックしているため、1900~2099 の範囲内で有効な年をチェックすることはできません。年の範囲をチェックするには、日付の整合性をチェックするコードと範囲の有効性をチェックするコードを別個に記述します。

IF #DATE (A10) = MASK (YYYY'-'MM'-'DD) AND #DATE = MASK (19-20)

定数または変数の内容に対するチェック

マスクチェックに対する値として定数または変数を使用する場合、この値(operand2)は mask-definition の直後に指定する必要があります。

operand2 は、少なくともマスクと同じ長さである必要があります。

マスクでは、チェックする桁には X、チェックしない桁にはピリオド(.)、疑問符(?)、または下線(_)を指定します。

例:

DEFINE DATA LOCAL
1 #NAME (A15)
END-DEFINE
...
IF #NAME = MASK (..XX) 'ABCD'
...

上記の例では、フィールド #NAME の 3~4 桁目が CD かどうかをチェックしていいます。1 桁目および 2 桁目はチェックされません。

マスクの長さにより、チェックが必要な位置の数が決まります。マスク操作で使用する任意のフィールドまたは定数に対し、マスクは左詰めで適用されます。式の右側のフィールド(または定数)のフォーマットは、式の左側のフィールドのフォーマットと同じである必要があります。

チェックするフィールド(operand1)がフォーマット A の場合、使用する定数(operand2)はアポストロフィで囲む必要があります。フィールドが数値の場合、使用する値は数値定数、数値データベースフィールドの値、またはユーザー定義変数である必要があります。

どちらの場合でも、マスク内の X インジケータが示す位置に該当しない文字/数値は無視されます。

指定された位置の値が両方とも同じ場合、MASK 操作の結果は真になります。

例:

** Example 'LOGICX01': MASK option in logical condition
************************************************************************
DEFINE DATA LOCAL
1 EMPLOY-VIEW VIEW OF EMPLOYEES
  2 CITY
END-DEFINE
*
HISTOGRAM EMPLOY-VIEW CITY
  IF CITY = 
MASK (....XX) '....NN'


    DISPLAY NOTITLE CITY *NUMBER
  END-IF
END-HISTOGRAM
*
END

上記の例では、フィールド CITY の 5~6 桁目が両方とも文字 N の場合、当該レコードは受け入れられます。

範囲チェック

範囲チェックを実行する場合、指定した変数を検証する桁数は、マスクに指定する値の精度で定義します。例えば、(...193...) というマスクを指定すると、4~6 桁目が 000~193 の範囲内の 3 桁の数値かどうかが検証されます。

マスク定義の他の例

  • 以下の例では、#NAME の各文字が英字かどうかがチェックされます。

    IF #NAME (A10) = MASK (AAAAAAAAAA)
  • 以下の例では、#NUMBER の 4~6 桁目が数値かどうかがチェックされます。

    IF #NUMBER (A6) = MASK (...NNN)
  • 以下の例では、#VALUE の 4~6 桁目が値 123 かどうかがチェックされます。

    IF #VALUE(A10) = MASK (...'123')
  • 以下の例では、#LICENSENY- で始まるライセンス番号で、最後の 5 文字が #VALUE の最後の 5 文字と同じかどうかがチェックされます。

    DEFINE DATA LOCAL
    1 #VALUE(A8)
    1 #LICENSE(A8)
    END-DEFINE
    INPUT 'ENTER KNOWN POSITIONS OF LICENSE PLATE:' #VALUE
    IF #LICENSE = MASK ('NY-'XXXXX) #VALUE
  • 以下の条件は、NAT で始まり AL で終わる値は、NATAL の間に他の文字が何文字あっても、すべて真になります。これには、NATAL だけでなく、NATURALNATIONALITY などの値も含まれます。

    MASK('NAT'*'AL')

パック型数値データまたはアンパック型数値データのチェック

レガシアプリケーションでは、英数字フィールドやバイナリフィールドを再定義したパック型またはアンパック型の数値変数を頻繁に使用しています。パック型変数またはアンパック型変数を割り当てや計算で使用すると、エラーや予測できない結果が生じる可能性があるため、このような再定義はしないことをお勧めします。再定義した変数を使用する前に内容を検証するには、桁数 - 1 個の N オプション(「マスク内の文字」を参照)を使用し、その後に一度だけ単一の Z オプションを指定します。

例:

IF #P1 (P1) = MASK (Z)
IF #N4 (N4) = MASK (NNNZ)
IF #P5 (P5) = MASK (NNNNZ)

フィールドの内容の変更についての詳細は、「IS オプションと比較した MASK オプション」を参照してください。

IS オプションと比較した MASK オプション

このセクションでは、MASK オプションと IS オプションの違いを示します。また、この違いを説明するサンプルプログラムも示します。

IS オプションを使用して、英数字フィールドまたは Unicode フィールドの内容を特定の他の形式に変換できるかどうかをチェックできますが、このオプションを使用して英数字フィールドの値が指定した形式であるかどうかをチェックすることはできません。

MASK オプションを使用して、再定義されたパック型またはアンパック型の数値変数の内容を検証できます。

相違を示す例:

** Example 'LOGICX09': MASK versus IS option in logical condition       
************************************************************************
DEFINE DATA LOCAL                                                       
1 #A2   (A2)                                                            
1 REDEFINE #A2                                                          
  2 #N2 (N2)                                                            
1 REDEFINE #A2                                                          
  2 #P3 (P3)                                                            
1 #CONV-N2 (N2)                                                         
1 #CONV-P3 (P3)                                                         
END-DEFINE                                                              
*                                                                       
#A2 := '12'                                         
WRITE NOTITLE   'Assignment #A2 := "12" results in:'
PERFORM SUBTEST                                     
#A2 := '-1'                                         
WRITE NOTITLE / 'Assignment #A2 := "-1" results in:'
PERFORM SUBTEST                                     
#N2 :=  12                                          
WRITE NOTITLE / 'Assignment #N2 :=  12  results in:'
PERFORM SUBTEST                                     
#N2 :=  -1                                          
WRITE NOTITLE / 'Assignment #N2 :=  -1  results in:'
PERFORM SUBTEST                                     
#P3 :=  12                                          
WRITE NOTITLE / 'Assignment #P3 :=  12  results in:'
PERFORM SUBTEST                                     
#P3 :=  -1                                          
WRITE NOTITLE / 'Assignment #P3 :=  -1  results in:'
PERFORM SUBTEST                                     
*                                                                                                                                
DEFINE SUBROUTINE SUBTEST                                       
IF #A2 IS (N2) THEN                                             
  #CONV-N2 := VAL(#A2)                                          
  WRITE NOTITLE 12T '#A2 can be converted to' #CONV-N2 '(N2)'   
END-IF                                                          
IF #A2 IS (P3) THEN                                             
  #CONV-P3 := VAL(#A2)                                          
  WRITE NOTITLE 12T '#A2 can be converted to' #CONV-P3 '(P3)'   
END-IF                                                          
IF #N2 = MASK(NZ) THEN                                          
  WRITE NOTITLE 12T '#N2 contains the valid unpacked number' #N2
END-IF                                                          
IF #P3 = MASK(NNZ) THEN                                         
  WRITE NOTITLE 12T '#P3 contains the valid packed number' #P3  
END-IF                                                          
END-SUBROUTINE                                                  
*                                                               
END                                                             

プログラム LOGICX09 の出力:

Assignment #A2 := '12' results in:                   
           #A2 can be converted to  12 (N2)          
           #A2 can be converted to   12 (P3)         
           #N2 contains the valid unpacked number  12
                                                     
Assignment #A2 := '-1' results in:                   
           #A2 can be converted to  -1 (N2)          
           #A2 can be converted to   -1 (P3)         
                                                     
Assignment #N2 :=  12  results in:                   
           #A2 can be converted to  12 (N2)          
           #A2 can be converted to   12 (P3)         
           #N2 contains the valid unpacked number  12
                                                     
Assignment #N2 :=  -1  results in:                   
           #N2 contains the valid unpacked number  -1
                                                     
Assignment #P3 :=  12  results in:                   
           #P3 contains the valid packed number   12 
                                                     
Assignment #P3 :=  -1  results in:                   
           #P3 contains the valid packed number   -1

MODIFIED オプション - フィールドの内容が変更されているかどうかのチェック

構文:

operand1 [NOT] MODIFIED

このオプションは、フィールドの内容が、INPUT ステートメントまたは PROCESS PAGE ステートメントの実行中に変更されているかどうかを判断するために使用します。前提条件として、制御変数がパラメータ CV.を使用して割り当てられている必要があります。

オペランド定義テーブル:

オペランド 構文要素 フォーマット オペランド参照 ダイナミック定義
operand1   S A                            C     × ×

INPUT ステートメントまたは PROCESS PAGE ステートメント内で参照される属性制御変数には、端末にマップが転送される時点では常にステータス "未変更" が割り当てられています。

属性制御変数を参照しているフィールドの内容が変更されると、属性制御変数にステータス "変更済み" が割り当てられます。複数のフィールドが同じ属性制御変数を参照している場合、これらのフィールドのどれかが変更されると、この変数は "変更済み" に設定されます。

operand1 が配列の場合、配列要素の少なくとも 1 つにステータス "変更済み" が割り当てられていると、結果は真になります(OR 演算)。

MODIFIED オプションの例:

** Example 'LOGICX06': MODIFIED option in logical condition
************************************************************************
DEFINE DATA LOCAL
1 #ATTR (C)
1 #A    (A1)
1 #B    (A1)
END-DEFINE
*
MOVE (AD=I) TO #ATTR
*
INPUT (CV=#ATTR) #A #B
IF #ATTR NOT MODIFIED
  WRITE NOTITLE 'FIELD #A OR #B HAS NOT BEEN MODIFIED'
END-IF
*
IF #ATTR MODIFIED
  WRITE NOTITLE 'FIELD #A OR #B HAS BEEN MODIFIED'
END-IF
*
END

プログラム LOGICX06 の出力:

#A   #B 

任意の値を入力して ENTER キーを押すと、以下のような出力が表示されます。

FIELD #A OR #B HAS BEEN MODIFIED

SCAN オプション - フィールド内の値をスキャンする

構文:

operand1

=
EQ
EQUAL TO
NE
NOT EQUAL

SCAN

operand2
(operand2)

オペランド定義テーブル:

オペランド 構文要素 フォーマット オペランド参照 ダイナミック定義
operand1 C S A   N   A U N P                   ×
operand2 C S         A U         B *             ×

* operand1 がフォーマット A または U の場合にのみ、operand2 にバイナリを使用できます。operand1 がフォーマット U で operand2 がフォーマット B の場合、operand2 の長さは偶数である必要があります。

SCAN オプションは、フィールド内の特定の値をスキャンするために使用します。

SCAN オプション(operand2)に使用する文字は、英数字定数または Unicode 定数(アポストロフィで区切られた文字列)、英数字データベースフィールドまたは Unicode データベースフィールドの値、あるいはユーザー定義変数として指定する必要があります。

注意:
operand1 および operand2 の末尾の空白は、自動的に除去されますしたがって、SCAN オプションは、末尾に空白のある値のスキャンには使用できません。operand1 および operand2 の先頭または途中の空白は保持されます。operand2 がすべて空白の場合、operand1 の値に関係なく、スキャンは成功とみなされます。スキャン操作で末尾の空白をスキャン対象とする場合は、EXAMINE FULL ステートメントの使用を検討してください。

スキャンするフィールド(operand1)のフォーマットは、A、N、P、または U です。SCAN 操作は、EQUAL(EQ)演算子または NOT EQUAL(NE)演算子で指定できます。

SCAN 操作に使用する文字列の長さは、スキャンされるフィールドの長さ未満である必要があります。指定した文字列の長さが、スキャンするフィールドの長さと同じ場合、SCAN ではなく EQUAL 演算子を使用する必要があります。

SCAN オプションの例:

** Example 'LOGICX02': SCAN option in logical condition
************************************************************************
DEFINE DATA
LOCAL
1 EMPLOY-VIEW VIEW OF EMPLOYEES
  2 NAME
*
1 #VALUE   (A4)
1 #COMMENT (A10)
END-DEFINE
*
INPUT 'ENTER SCAN VALUE:' #VALUE
LIMIT 15
*
HISTOGRAM EMPLOY-VIEW FOR NAME
  RESET #COMMENT
  IF NAME = SCAN #VALUE
    MOVE 'MATCH' TO #COMMENT
  END-IF
  DISPLAY NOTITLE NAME *NUMBER #COMMENT
END-HISTOGRAM
*
END

プログラム LOGICX02 の出力:

ENTER SCAN VALUE:  

15 件の名前を LL でスキャンした結果、3 件一致した例:

        NAME          NMBR      #COMMENT
-------------------- --------- ----------
 
ABELLAN                      1 MATCH
ACHIESON                     1 
ADAM                         1
ADKINSON                     8
AECKERLE                     1
AFANASSIEV                   2
AHL                          1
AKROYD                       1
ALEMAN                       1
ALESTIA                      1
ALEXANDER                    5
ALLEGRE                      1 MATCH
ALLSOP                       1 MATCH
ALTINOK                      1
ALVAREZ                      1

SPECIFIED オプション - オプションのパラメータに値が渡されるかどうかをチェックする

構文:

parameter-name [NOT] SPECIFIED

このオプションは、呼び出されたオブジェクト(サブプログラム、外部サブルーチン、または ActiveX コントロール)のオプションパラメータが、呼び出し元オブジェクトから値を受け取っているかどうかをチェックするために使用します。

オプションパラメータとは、呼び出されるオブジェクトの DEFINE DATA PARAMETER ステートメント内でキーワード OPTIONAL を使用して定義されているフィールドのことです。フィールドが OPTIONAL として定義されている場合、呼び出し元オブジェクトからこのフィールドに値を渡すことはできますが、必須ではありません。

呼び出し元ステートメントでは、表記 nX を使用して、パラメータに値を渡さないことを示します。

値を受け取っていないオプションパラメータを処理しようとすると、ランタイムエラーが発生します。このようなエラーを回避するには、呼び出されたオブジェクト内で SPECIFIED オプションを使用してオプションパラメータに値が渡されているかどうかを確認し、値が渡されている場合にのみ処理するようにします。

parameter-name は、呼び出されたオブジェクトの DEFINE DATA PARAMETER ステートメントで指定されているパラメータ名です。

フィールドが OPTIONAL として定義されていない場合、SPECIFIED 条件は常に TRUE になります。

SPECIFIED オプションの例:

呼び出し元プログラム:

** Example 'LOGICX07': SPECIFIED option in logical condition            
************************************************************************
DEFINE DATA LOCAL                                                       
1 #PARM1 (A3)                                                           
1 #PARM3 (N2)                                                           
END-DEFINE                                                              
*                                                                       
#PARM1 := 'ABC'                                                         
#PARM3 := 20                                                            
*                                                                       
CALLNAT 'LOGICX08' #PARM1 1X #PARM3                                     
*                                                                       
END

呼び出されたサブプログラム:

** Example 'LOGICX08': SPECIFIED option in logical condition            
************************************************************************
DEFINE DATA PARAMETER                                                   
1 #PARM1 (A3)                                                           
1 #PARM2 (N2) OPTIONAL                                                  
1 #PARM3 (N2) OPTIONAL                                                  
END-DEFINE                                                              
*                                                                       
WRITE '=' #PARM1                                                        
*                                                                       
IF #PARM2 SPECIFIED                                                     
  WRITE '#PARM2 is specified'                                           
  WRITE '=' #PARM2                                                      
ELSE                                                                    
  WRITE '#PARM2 is not specified'                                       
* WRITE '=' #PARM2                /* would cause runtime error NAT1322  
END-IF                                                                  
*                                                                       
IF #PARM3 NOT SPECIFIED
  WRITE '#PARM3 is not specified'
ELSE                             
  WRITE '#PARM3 is specified'    
  WRITE '=' #PARM3               
END-IF                           
END

プログラム LOGICX07 の出力:

Page      1                                                  14-01-14  11:25:41
                                                                               
#PARM1: ABC                                                                    
#PARM2 is not specified                                                        
#PARM3 is specified                                                            
#PARM3:  20