このドキュメントでは、ステートメント FIND
、READ
、HISTOGRAM
、ACCEPT
/REJECT
、IF
、DECIDE FOR
、REPEAT
で使用できる論理条件基準の目的および使用方法を説明します。
以下のトピックについて説明します。
基本の条件は、1 つの関係式です。複数の関係式を論理演算子(AND
、OR
)と組み合わせて、複合条件を構成することができます。
また、演算式を使用して、1 つの関係式を構成することもできます。
論理条件基準は、以下のステートメントで使用できます。
ステートメント | 使用方法 |
---|---|
FIND |
論理条件基準を持つ WHERE 節を使用して、WITH 節で指定されている基本選択条件に、さらに条件を追加します。WHERE 節で指定されている論理条件基準は、レコードの選択および読み込み後に評価されます。
|
READ |
論理条件基準を持つ WHERE 節を使用して、読み込んだレコードを処理するかどうかを指定します。論理条件基準は、レコードの読み込み後に評価されます。
|
HISTOGRAM |
論理条件基準を持つ WHERE 節を使用して、読み込んだ値を処理するかどうかを指定します。論理条件基準は、値の読み込み後に評価されます。
|
ACCEPT /REJECT |
FIND 、READ 、または HISTOGRAM ステートメントでレコードが選択され、読み込まれる場合、IF 節を ACCEPT または REJECT ステートメントで使用して、指定された条件に加えて論理条件の基準を指定することもできます。論理条件の基準は、レコードが読み込まれ、レコードの処理が開始した後に評価されます。
|
IF |
論理条件の基準を使用して、ステートメントの実行を制御します。 |
DECIDE
FOR |
論理条件の基準を使用して、ステートメントの実行を制御します。 |
REPEAT |
REPEAT ステートメントの UNTIL 節または WHILE 節に、いつ処理ループを終了するのかを決定する論理条件基準を指定します。
|
構文:
operand1 |
|
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
を参照してください。
比較演算子の説明:
比較演算子 | 説明 |
---|---|
|
等しい |
|
等しくない |
|
より小さい |
|
より大きいまたは等しい |
|
以上 |
|
より大きい |
|
より小さいまたは等しい |
|
以下 |
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
のみを使用できます。
構文:
|
|
operand2 |
オペランド定義テーブル:
オペランド | 構文要素 | フォーマット | オペランド参照 | ダイナミック定義 | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
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
)を指定します。
両方の形式を組み合わせることもできます。つまり、SUBSTRING
を operand1
と operand2
の両方に指定できます。
以下の式は、フィールド #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 |
|
operand2 | ||||||||
OR |
|
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]
|
MASK operand |
SCAN operand |
これらのオプションの詳細については、「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] | ○ |
注意:
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
論理条件基準は、ブール演算子 AND
、OR
、および NOT
を使用して組み合わせることができます。カッコを使用して論理グループを示すこともできます。
演算子は、以下の順序で評価されます。
優先順位 | 演算子 | 意味 |
---|---|---|
1 | ( ) |
カッコ |
2 | NOT |
否定 |
3 | AND |
AND オペレーション
|
4 | OR |
OR オペレーション
|
以下の logical-condition-criteria
を論理演算子で組み合わせることにより、複雑な論理式を作成できます。
logical-expression
の構文は次のようになります。
[NOT] |
logical-condition-criterion |
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 [OF] operand1 [/n/]
|
オペランド定義テーブル:
オペランド | 構文要素 | フォーマット | オペランド参照 | ダイナミック定義 | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
operand1 |
S | A | U | N | P | I | F | B | D | T | L | ○ | × |
構文要素の説明:
** 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
構文:
operand1 IS (format) |
このオプションは、英数字フィールドまたは Unicode フィールド(operand1
)の値を特定の別のフォーマットに変換できるかどうかをチェックするために使用します。
オペランド定義テーブル:
オペランド | 構文要素 | フォーマット | オペランド参照 | ダイナミック定義 | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
operand1 |
C | S | A | N | A | U | ○ | × |
チェックできる format
は、以下のとおりです。
Nll.ll | 長さが ll.ll の数値 |
Fll | 長さが ll の浮動小数点 |
D | 日付。以下の日付フォーマットが使用できます。dd-mm-yy、dd-mm-yyyy、ddmmyyyy(dd = 日、mm = 月、yy または yyyy = 年)年、月、日の各コンポーネントの順序、およびコンポーネント間のデリミタ文字は、プロファイルパラメータ DTFORM (『パラメータリファレンス』を参照)によって決まります。
|
T | 時刻(デフォルトの時刻表示フォーマットに依存) |
Pll.ll | 長さが ll.ll のパック型数値 |
Ill | 長さが ll の整数値 |
チェック時は、operand1
の先頭および末尾の空白は無視されます。
IS
オプションは、例えば、算術関数 VAL
(英数字フィールドから数値を抽出)を実行する前にフィールドの内容をチェックして、ランタイムエラーが発生しないようにするために使用できます。
注意:IS
オプションで可能なのは、英数字フィールドの値が特定の"フォーマット"かどうかのチェックではなく、その"フォーマット"に変換できるかどうかのチェックです。値が特定のフォーマットかどうかをチェックするには、MASK
オプションを使用します。詳細については、「IS オプションと MASK オプションの比較」および「パック型数値データまたはアンパック型数値データのチェック」を参照してください。
** 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
オプションを使用すると、フィールドの特定の位置を特定の内容に照らしてチェックできます。
以下では次のトピックについて説明します。
構文:
operand1 |
|
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 |
|
MASK operand2 |
オペランド定義テーブル:
オペランド | 構文要素 | フォーマット | オペランド参照 | ダイナミック定義 | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
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 桁をチェックしないことを示します。 |
* または % |
アスタリスクまたはパーセント記号は、任意の桁数をチェックしないことを示すために使用します。 |
/ |
スラッシュ(/)は、値が特定の文字(または文字列)で終わっているかどうかをチェックするために使用します。
例えば、フィールドの最後が IF #FIELD = MASK (*'E'/) |
A |
該当する桁が英字(大文字または小文字)かどうかをチェックします。 |
'c' |
1 つ以上の桁が、アポストロフィで囲まれている文字列かどうかをチェックします。 チェックする文字は TQMARK パラメータに依存しません。引用符(")は引用符(")に対してチェックされます。
|
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 )の同じ位置の値と同じかどうかをチェックします。
|
YY |
該当する 2 桁が有効な年(00~99)かどうかをチェックします。「日付チェック」も参照してください。 |
YYYY |
該当する 4 桁が有効な年(0000~2699)かどうかをチェックします。 |
Z |
該当する桁の左側のハーフバイトが 16 進数の 3 または 7 で、右側のハーフバイトが 16 進数の 0~9 かどうかをチェックします。
これは、負数の数値に対しても正しくチェックできます。数値の符号は最後の桁に格納されるため、その桁は 16 進数の非数値とみなされます。したがって、(該当する桁が数値かどうかをチェックする) マスク内では |
マスクの長さにより、チェックが必要な位置の数が決まります。
DEFINE DATA LOCAL 1 #CODE (A15) END-DEFINE ... IF #CODE = MASK (NN'ABC'....NN) ...
上記の例では、#CODE
の最初の 2 桁に対し、数値かどうかをチェックしています。その後の 3 桁は、定数 ABC
かどうかをチェックしています。その次の 4 桁はチェックしていません。10 桁目および 11 桁目は、数値かどうかをチェックしています。12~15 桁目はチェックしていません。
指定するマスク内でチェックできる日付は 1 つのみです。同じ日付コンポーネント(JJJ
、DD
、MM
、YY
、または YYYY
)がマスクで複数回指定されている場合、最後のオカレンスの値のみ、他の日付コンポーネントとの整合性がチェックされます。
日付に対するチェックでマスクに日(DD
)を指定して月(MM
)を指定しない場合、現在の月を想定してチェックが行われます。
日付に対するチェックでマスクに日(DD
)またはユリウス日(JJJ
)を指定して年(YY
または YYYY
)を指定しない場合、現在の年を想定してチェックが行われます。
日付を 2 桁の年(YY
)でチェックするときにスライディングウィンドウも固定ウィンドウも設定されていない場合、現在の世紀を想定してチェックが行われます。スライディングウィンドウまたは固定ウィンドウの詳細については、『パラメータリファレンス』に記載されている、プロファイルパラメータ YSLW
の説明を参照してください。
MOVE 1131 TO #DATE (N4) IF #DATE = MASK (MMDD)
この例では、月と日の有効性をチェックしています。月に対する値(11)は有効とみなされますが、11 月には 30 日しかないため、日に対する値(31)は無効とみなされます。
IF #DATE(A8) = MASK (MM'/'DD'/'YY)
この例では、フィールド #DATE
の内容がフォーマット MM/DD/YY
(月/日/年)の日付として有効かどうかをチェックしています。
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)
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')
以下の例では、#LICENSE
が NY-
で始まるライセンス番号で、最後の 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
で終わる値は、NAT
と AL
の間に他の文字が何文字あっても、すべて真になります。これには、NATAL
だけでなく、NATURAL
や NATIONALITY
などの値も含まれます。
MASK('NAT'*'AL')
レガシアプリケーションでは、英数字フィールドやバイナリフィールドを再定義したパック型またはアンパック型の数値変数を頻繁に使用しています。パック型変数またはアンパック型変数を割り当てや計算で使用すると、エラーや予測できない結果が生じる可能性があるため、このような再定義はしないことをお勧めします。再定義した変数を使用する前に内容を検証するには、桁数 - 1 個の N オプション(「マスク内の文字」を参照)を使用し、その後に一度だけ単一の Z オプションを指定します。
IF #P1 (P1) = MASK (Z) IF #N4 (N4) = MASK (NNNZ) IF #P5 (P5) = MASK (NNNNZ)
フィールドの内容の変更についての詳細は、「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
構文:
operand1 [NOT ] MODIFIED |
このオプションは、フィールドの内容が、INPUT
ステートメントまたは PROCESS PAGE
ステートメントの実行中に変更されているかどうかを判断するために使用します。前提条件として、制御変数がパラメータ CV
.を使用して割り当てられている必要があります。
オペランド定義テーブル:
オペランド | 構文要素 | フォーマット | オペランド参照 | ダイナミック定義 | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
operand1 |
S | A | C | × | × |
INPUT
ステートメントまたは PROCESS PAGE
ステートメント内で参照される属性制御変数には、端末にマップが転送される時点では常にステータス "未変更" が割り当てられています。
属性制御変数を参照しているフィールドの内容が変更されると、属性制御変数にステータス "変更済み" が割り当てられます。複数のフィールドが同じ属性制御変数を参照している場合、これらのフィールドのどれかが変更されると、この変数は "変更済み" に設定されます。
operand1
が配列の場合、配列要素の少なくとも 1 つにステータス "変更済み" が割り当てられていると、結果は真になります(OR
演算)。
** 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
構文:
operand1 |
|
SCAN |
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
演算子を使用する必要があります。
** 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
構文:
parameter-name [NOT ] SPECIFIED |
このオプションは、呼び出されたオブジェクト(サブプログラム、外部サブルーチン、または ActiveX コントロール)のオプションパラメータが、呼び出し元オブジェクトから値を受け取っているかどうかをチェックするために使用します。
オプションパラメータとは、呼び出されるオブジェクトの DEFINE DATA
PARAMETER
ステートメント内でキーワード OPTIONAL
を使用して定義されているフィールドのことです。フィールドが OPTIONAL
として定義されている場合、呼び出し元オブジェクトからこのフィールドに値を渡すことはできますが、必須ではありません。
呼び出し元ステートメントでは、表記 nX
を使用して、パラメータに値を渡さないことを示します。
値を受け取っていないオプションパラメータを処理しようとすると、ランタイムエラーが発生します。このようなエラーを回避するには、呼び出されたオブジェクト内で SPECIFIED
オプションを使用してオプションパラメータに値が渡されているかどうかを確認し、値が渡されている場合にのみ処理するようにします。
parameter-name
は、呼び出されたオブジェクトの DEFINE DATA PARAMETER
ステートメントで指定されているパラメータ名です。
フィールドが OPTIONAL
として定義されていない場合、SPECIFIED
条件は常に TRUE
になります。
呼び出し元プログラム:
** 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