*AND、*OR、および *NOT 演算子

論理演算子 *AND および *OR は、 論理式のオペランド相互間の関係を指定します。論理演算子 *NOT は、 論理変数や定数を否定するために使用されます。

*AND および *OR は、 論理式のオペランド相互間の関係を指定するために使用する予約値です。 予約値 *AND の代わりにアンパーサンド (&) を、 *OR の代わりに縦線 (|) を使用することもできます。 予約値の前後にはブランクがなければなりません。 論理式の中のオペランドは、関係式で構成されるか、 あるいは論理演算子で区切った論理変数または定数によって構成されます。 *AND 演算子は、 結果が真であるためには、両方のオペランド (演算子の両側の) が真でなければならないことを意味します。 *OR 演算子は、 結果が真であるためにはオペランドの一方または両方が真でなければならないことを意味します。

注: コード・ページによって記号とコード・ポイントの対応が異なるため、 アンパーサンドや縦線 (|) を使用すると問題が生じる場合があります。 この問題を回避するためには、記号の代わりに *AND や *OR を使用します。

論理演算子以外の演算子は、 式の中のオペランドに実行される処置、 またはオペランド相互間の関係を示すために式の中で使用します。 論理演算子以外の演算子には次の 3 種類があります。

  • 算術演算子 (+、-、*、/)
  • 文字 (*CAT、||、*BCAT、|>、*TCAT、|<)
  • 関係演算子 (*EQ、=、*GT、>、*LT、<、*GE、>=、*LE、<=、*NE、 ¬=、*NG、¬>、*NL、¬<)

以下の例は論理式について示しています。

((&C *LT 1) *AND (&TIME *GT 1430))
(&C *LT 1 *AND &TIME *GT 1430)
((&C < 1) & (&TIME>1430))
((&C< 1) & (&TIME>1430))

上記のどの場合も、論理式は 2 つのオペランドと 1 つの演算子 (*AND、*OR、またはそれを表す記号) の 3 つの部分で構成されています。 式が論理式であるかどうかを決めるのはオペランドのタイプではなく、 演算子のタイプ (*AND または *OR) です。 論理式のオペランドとして使用できるのは、 論理変数または他の式 (関係式など) です。 (関係式とは、>、<、または =、 あるいはそれに対応する予約値が含まれている式のことです。) 例えば、次の例では、論理式全体が括弧で囲まれており、また両方のオペランドが関係式で、それぞれが別個に括弧で囲まれています。

((&C *LT 1) *AND (&TIME *GT 1430))

前の例の 2 番目の論理式のように、 各オペランドをそれぞれ独立して括弧で囲む必要はありませんが、 意味を明確にするために括弧で囲むことをお勧めします。 また、*AND と *OR とは優先順位が異なるので括弧は不要です。 *AND は常に *OR より先に評価されます。 同じ優先順位の演算子をいくつか使用する場合には、 演算を行う順序を制御するために括弧を使用することができます。

コマンドの中の条件として単純な関係式を使用することができます。

IF (&A=&B) THEN(DO)
              .
              .
              .
              ENDDO

この関係式のオペランドは定数にすることもできます。

複数の条件を指定したい場合には、 オペランドとして関係式を用いた論理式を使用することができます。

IF ((&A=&B) *AND (&C=&D)) THEN(DO)
                             .
                             .
                             .
                             ENDDO

CL プログラムまたはプロシージャー内の組み込み IF コマンドの項で例として示した一連の IF コマンドは、 次のようにコーディングすることができます。

PGM
DCL &RESP *DEC 1
DCL &A *DEC 1
DCL &B *CHAR 2
IF ((&RESP=1) *AND (&A=5) *AND (&B=NO)) THEN(DO)
                                           .
                                           .
                                           .
                                           ENDDO
CHGVAR &A VALUE(8)
CALLPRC PROC(DAILY)
ENDPGM

ここでも、関係式と関係式との間で論理演算子が使用されています。

論理式は他の論理式をオペランドとして使用することができるので、 複雑なロジックを組み立てることも可能です。

IF (((&A=&B) *OR (&A=&C)) *AND ((&C=1) *OR (&D='0'))) THEN(DO)

この例では、&D は論理変数として定義されます。

関係式または論理式の評価の結果は、'1' または '0' (真または偽) のどちらかです。 従属するコマンドが処理されるのは、 式全体が真 ('1') として評価された場合だけです。 次のコマンドは、真および偽の用語を用いて説明しています。

IF   ((&A = &B) *AND (&C = &D)) THEN(DO)
 
     ((真 '1') *AND (偽 '0'))
          (偽 '0')

この式は最終的には真でない ('0') と評価され、したがって DO は処理されません。 どのようにしてこの評価に達するかの説明については、 この項に示す行列を参照してください。

これと同じプロセスが、次の例のように、論理変数を使った論理式の評価に使用されます。

PGM
DCL &A *LGL
DCL &B *LGL
IF (&A *OR &B) THEN(CALL PGM(PGMA))
.
.
.
ENDPGM

この例では、&A または &B の値が '1' (真) であるかどうかを調べるために、 条件式が評価されます。 どちらかの値が真であれば、式全体が真となり、PGMA が呼び出されます。

これまでのすべての論理式の例において、最終的に到達した評価の結果は、 *OR または *AND 演算子での 2 つの値 (ここでは &A と &B) を比較する標準的な行列に基づいています。

論理変数または定数と *OR を使用する場合には、次の行列を使用します。

&A の値:
'0' '0' '1' '1'
&B の値:
'0' '1' '0' '1'
OR 式の結果:
'0' '1' '1' '1'

要約すると、論理変数または定数と複数の OR 演算子が存在する場合には、 すべての値が偽 ('0') であればその式は偽になります。 そして、値のいずれかが真 ('1') であればその式は真になります。

PGM
DCL &A *LGL VALUE('0')
DCL &B *LGL VALUE('1')
DCL &C *LGL VALUE('1')
IF (&A *OR &B *OR &C) THEN(CALL PGMA)
.
.
.
ENDPGM

この例では、すべての値が偽ではないので式も真になり、したがって PGMA は呼び出されません。

論理変数または定数を *AND で結んだ論理式を評価する場合には、次の行列を使用します。

&A の値:
'0' '0' '1' '1'
&B の値:
'0' '1' '0' '1'
ANDed 式の結果:
'0' '0' '0' '1'

論理変数または定数と AND 演算子からなる論理式の評価は、 値のいずれかが偽 ('0') であれば式は偽であり、 すべての値が真であれば式も真になります。

PGM
DCL &A *LGL VALUE('0')
DCL &B *LGL VALUE('1')
DCL &C *LGL VALUE('1')
IF (&A *AND &B *AND &C) THEN(CALL PGMA)
.
.
.
ENDPGM

この例では、すべての値が真ではないので式は偽になり、したがって PGMA は呼び出されません。

これらの論理演算子を式の中で使用できるのは、 これまでの例のように、オペランドが論理値を表している場合だけです。 論理変数以外の変数に対して OR または AND を使用するのは誤りです。次の例をご覧ください。

PGM
DCL &A *CHAR 3
DCL &B *CHAR 3
DCL &C *CHAR 3
 
誤り:   IF (&A *OR &B *OR &C = YES) THEN...

この場合の正しいコーディングは、次のようになります。

IF ((&A=YES) *OR (&B=YES) *OR (&C=YES)) THEN...

このようにすれば、関係式間の OR 関係が生じます。

論理演算子 *NOT (または ¬) は、論理変数や定数を否定するために使用されます。*NOT 演算子は、*AND または *OR 演算子の評価の前に評価されます。 また *NOT 演算子に続く値は、 オペランド相互間の論理関係の評価より前に評価されます。

PGM
DCL &A *LGL '1'
DCL &B *LGL '0'
IF (&A *AND *NOT &B) THEN(CALL PGMA)

この例では、値がすべて真であるので式も真になり、したがって PGMA が呼び出されます。

PGM
DCL &A *LGL
DCL &B *CHAR 3 VALUE('ABC')
DCL &C *CHAR 3 VALUE('XYZ')
CHGVAR &A VALUE(&B *EQ &C)
IF (&A) THEN(CALLPRC PROCA)

この例では、値が偽であるので PROCA は呼び出されません。