This document describes purpose and use of logical condition criteria that can be used in
the statements FIND
, READ
, HISTOGRAM
, ACCEPT
/REJECT
, IF
,
DECIDE FOR
, REPEAT
.
The following topics are covered:
BREAK Option - Compare Current Value with Value of Previous Loop Pass
IS Option - Check whether Content of Alphanumeric or Unicode Field can be Converted
MASK Option - Check Selected Positions of a Field for Specific Content
MODIFIED Option - Check whether Field Content has been Modified
SPECIFIED Option - Check whether a Value is Passed for an Optional Parameter
The basic criterion is a relational
expression. Multiple relational expressions may be combined with logical
operators (AND
, OR
) to form complex criteria.
Arithmetic expressions may also be used to form a relational expression.
Logical condition criteria can be used in the following statements:
Statement | Usage |
---|---|
FIND
|
A WHERE clause containing logical condition criteria may be used
to indicate criteria in addition to the basic selection criteria as specified in
the WITH clause. The logical condition criteria specified with the
WHERE clause are evaluated after the record has been selected and
read.
In a |
READ
|
A WHERE clause containing logical condition criteria may be used
to specify whether a record that has just been read is to be processed. The
logical condition criteria are evaluated after the record has been read.
|
HISTOGRAM
|
A WHERE clause containing logical condition criteria may be used
to specify whether the value that has just been read is to be processed. The
logical condition criteria are evaluated after the value has been read.
|
ACCEPT /REJECT
|
An IF clause may be used with an ACCEPT or
REJECT statement to specify logical condition criteria in addition
to that specified when the record was selected/read with a FIND ,
READ , or HISTOGRAM statement. The logical condition
criteria are evaluated after the record has been read and after record processing
has started.
|
IF
|
Logical condition criteria are used to control statement execution. |
DECIDE FOR
|
Logical condition criteria are used to control statement execution. |
REPEAT
|
The UNTIL or WHILE clause of a REPEAT
statement contain logical condition criteria which determine when a processing
loop is to be terminated.
|
Syntax:
operand1 |
|
operand2 |
Operand Definition Table:
Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
operand1
|
C | S | A | N | E | A | U | N | P | I | F | B | D | T | L | G | O | yes | yes | ||
operand2
|
C | S | A | N | E | A | U | N | P | I | F | B | D | T | L | G | O | yes | no |
For an explanation of the Operand Definition Table shown above, see Syntax Symbols and Operand Definition Tables in the Statements documentation.
In the "Possible Structure" column of the table above, "E"
stands for arithmetic expressions; that is, any arithmetic expression may be specified as
an operand within the relational expression. For further information on arithmetic
expressions, see arithmetic-expression
in the
COMPUTE
statement
description.
Explanation of the comparison operators:
Comparison Operator | Explanation |
---|---|
|
equal to |
|
not equal to |
|
less than |
|
greater than or equal to |
|
not less than |
|
greater than |
|
less than or equal to |
|
not greater than |
IF NAME = 'SMITH' IF LEAVE-DUE GT 40 IF NAME = #NAME
For information on comparing arrays in a relational expression, see Processing of Arrays.
Note:
If a floating-point operand is used, comparison is performed in floating point.
Floating-point numbers as such have only a
limited precision; therefore, rounding/truncation errors cannot be precluded when numbers
are converted to/from floating-point representation.
The following example shows how arithmetic expressions can be used in logical conditions:
IF #A + 3 GT #B - 5 AND #C * 3 LE #A + #B
If the operands in a relation expression are handles, only EQUAL
and
NOT EQUAL
operators may be used.
Syntax:
|
|
operand2 |
Operand Definition Table:
Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
operand1
|
C | S | A | N | A | U | B | yes | yes | ||||||||||||
operand2
|
C | S | A | N | A | U | B | yes | no | ||||||||||||
operand3 |
C | S | N | P | I | B | yes | no | |||||||||||||
operand4 |
C | S | N | P | I | yes | no | ||||||||||||||
operand5 |
C | S | N | P | I | yes | no | ||||||||||||||
operand6 |
C | S | N | P | I | yes | no |
With the SUBSTRING
option, you can compare a part of an
alphanumeric, a binary or a Unicode field. After the field name
(operand1
) you specify first the starting
position (operand3
) and then the length
(operand4
) of the field portion to be
compared.
Also, you can compare a field value with part of another field value. After the field
name (operand2
) you specify first the starting
position (operand5
) and then the length
(operand6
) of the field portion
operand1
is to be compared with.
You can also combine both forms, that is, you can specify a SUBSTRING
for
both operand1
and
operand2
.
The following expression compares the 5th to 12th position inclusive of the value in
field #A
with the value of field #B
:
SUBSTRING(#A,5,8) = #B
- where 5 is the starting position and 8 is the length.
The following expression compares the value of field #A
with the 3rd to 6th
position inclusive of the value in field #B
:
#A = SUBSTRING(#B,3,4)
Note:
If you omit
operand3/operand5
,
the starting position is assumed to be 1. If you omit
operand4/operand6
,
the length is assumed to be from the starting position to the end of the field.
Syntax:
operand1 |
|
operand2 | ||||||||
OR
|
|
operand3 | ||||||||
THRU
operand4 [BUT NOT
operand5 [THRU
operand6]]
|
Operand Definition Table:
Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
operand1
|
C | S | A | N* | E | A | U | N | P | I | F | B | D | T | G | O | yes | no | |||
operand2
|
C | S | A | N* | E | A | U | N | P | I | F | B | D | T | G | O | yes | no | |||
operand3 |
C | S | A | N* | E | A | U | N | P | I | F | B | D | T | G | O | yes | no | |||
operand4 |
C | S | A | N* | E | A | U | N | P | I | F | B | D | T | G | O | yes | no | |||
operand5 |
C | S | A | N* | E | A | U | N | P | I | F | B | D | T | G | O | yes | no | |||
operand6 |
C | S | A | N* | E | A | U | N | P | I | F | B | D | T | G | O | yes | no |
* Mathematical functions and system variables are permitted. Break functions are not permitted.
operand3
can also be specified using a
MASK
or SCAN
option; that is, it can be specified as:
MASK (mask-definition)
[operand]
|
MASK
operand
|
SCAN
operand |
For details on these options, see the sections MASK Option and SCAN Option.
IF #A = 2 OR = 4 OR = 7 IF #A = 5 THRU 11 BUT NOT 7 THRU 8
Syntax:
operand1 |
This option is used in conjunction with a logical variable (format L). A logical variable
may take the value TRUE
or FALSE
. As
operand1
you specify the name of the logical
variable to be used.
Operand Definition Table:
Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
operand1
|
C | S | A | L | no | no |
** 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
Output of Program 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
Database fields and user-defined variables may be used to construct logical condition criteria. A database field which is a multiple-value field or is contained in a periodic group can also be used. If a range of values for a multiple-value field or a range of occurrences for a periodic group is specified, the condition is true if the search value is found in any value/occurrence within the specified range.
Each value used must be compatible with the field used on the opposite side of the expression. Decimal notation may be specified only for values used with numeric fields, and the number of decimal positions of the value must agree with the number of decimal positions defined for the field.
If the operands are not of the same format, the second operand is converted to the format of the first operand.
The following table shows which operand formats can be used together in a logical condition:
operand1 | operand2 | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
A | U | Bn (n=<4) | Bn (n>=5) | D | T | I | F | L | N | P | GH | OH | |
A | Y | Y | Y | Y | |||||||||
U | Y | Y | [2] | [2] | |||||||||
Bn (n=<4) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | |||
Bn (n>=5) | Y | Y | Y | Y | |||||||||
D | Y | Y | Y | Y | Y | Y | Y | ||||||
T | Y | Y | Y | Y | Y | Y | Y | ||||||
I | Y | Y | Y | Y | Y | Y | Y | ||||||
F | Y | Y | Y | Y | Y | Y | Y | ||||||
L | |||||||||||||
N | Y | Y | Y | Y | Y | Y | Y | ||||||
P | Y | Y | Y | Y | Y | Y | Y | ||||||
GH [1] | Y | ||||||||||||
OH [1] | Y |
Notes:
If two values are compared as alphanumeric values, the shorter value is assumed to be extended with trailing blanks in order to get the same length as the longer value.
If two values are compared as binary values, the shorter value is assumed to be extended with leading binary zeroes in order to get the same length as the longer value.
If two values are compared as Unicode values, trailing blanks are removed from both values before the ICU collation algorithm is used to compare the two resulting values. See also Logical Condition Criteria in the Unicode and Code Page Support documentation.
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
If an array is compared with a scalar value, each element of the array will be compared
with the scalar value. The condition will be true if at least one of the array elements
meets the condition (OR
operation).
If an array is compared with an array, each element in the array is compared with the
corresponding element of the other array. The result is true only if all element
comparisons meet the condition (AND
operation).
See also Processing of Arrays.
Note:
An Adabas phonetic descriptor cannot be used within a logical condition.
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
Logical condition criteria may be combined using the Boolean operators AND
,
OR
, and NOT
. Parentheses may also be used to indicate logical
grouping.
The operators are evaluated in the following order:
Priority | Operator | Meaning |
---|---|---|
1 |
( )
|
Parentheses |
2 |
NOT
|
Negation |
3 |
AND
|
AND operation
|
4 |
OR
|
OR operation
|
The following logical-condition-criteria
may be
combined by logical operators to form a complex logical-expression:
The syntax for a logical-expression
is as
follows:
[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')
For information on comparing arrays in a logical expression, see Processing of Arrays.
Note:
If multiple logical-condition-criteria are connected with AND
, the
evaluation terminates as soon as the first of these criteria is not true. If multiple
logical-condition-criteria are connected with OR
, the evaluation terminates
as soon as the first of these criteria is true.
The BREAK
option allows the current value or a portion of a value of a field
to be compared with the value contained in the same field in the previous pass through the
processing loop.
Syntax:
BREAK [OF] operand1 [/n/]
|
Operand Definition Table:
Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
operand1
|
S | A | U | N | P | I | F | B | D | T | L | yes | no |
Syntax Element Description:
** 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
Output of Program 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
Syntax:
operand1 IS (format) |
This option is used to check whether the content of an alphanumeric or Unicode field
(operand1
) can be converted to a specific
other format.
Operand Definition Table:
Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
operand1
|
C | S | A | N | A | U | yes | no |
The format
for which the check is performed can
be:
Nll.ll | Numeric with length ll.ll. |
Fll | Floating point with length ll. |
D | Date. The following date formats are possible:
dd-mm-yy, dd-mm-yyyy,
ddmmyyyy (dd = day,
mm = month, yy or
yyyy = year). The sequence of the day, month and year
components as well as the characters between the components are determined by the
profile parameter DTFORM (which is described in the
Parameter Reference).
|
T | Time (according to the default time display format). |
Pll.ll | Packed numeric with length ll.ll. |
Ill | Integer with length ll. |
When the check is performed, leading and trailing blanks in
operand1
will be ignored.
The IS
option may, for example, be used to check the content of a field
before the mathematical function VAL
(extract numeric value from an alphanumeric field) is
used to ensure that it will not result in a runtime error.
Note:
The IS
option cannot be used to check if the value of an alphanumeric
field is in the specified "format", but if it can be converted to
that "format". To check if a value is in a specific format, you can use the
MASK
option. For further
information, see MASK Option Compared with
IS Option and Checking
Packed or Unpacked Numeric Data.
** 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
Output of Program LOGICX04
:
#DATE 150487 #FIELDA INPUT IS NOT IN DATE FORMAT (YY-MM-DD)
With the MASK
option, you can check selected positions of a field
for specific content.
The following topics are covered below:
Syntax:
operand1 |
|
MASK (mask-definition)
[operand2]
|
Operand Definition Table:
Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
operand1
|
C | S | A | N | A | U | N | P | yes | no | |||||||||||
operand2
|
C | S | A | U | N | P | B | yes | no |
operand2
can only be used if the
mask-definition
contains at least one
X
. operand1
and
operand2
must be format-compatible:
If operand1
is of format A,
operand2
must be of format A, B, N or
U.
If operand1
is of format U,
operand2
must be of format A, B, N or U.
If operand1
is of format N or P,
operand2
must be of format N or P.
An X
in the mask-definition
selects the corresponding positions of the content of
operand1
and
operand2
for comparison.
Apart from a constant mask-definition
(see
above), you may also specify a variable mask definition.
Syntax:
operand1 |
|
MASK
operand2 |
Operand Definition Table:
Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
operand1
|
C | S | A | N | A | U | N | P | yes | no | |||||||||||
operand2
|
S | A | U | yes | no |
The content of operand2
will be taken as the
mask definition. Trailing blanks in operand2
will be ignored.
If operand1
is of format A, N or P,
operand2
must be of format A.
If operand1
is of format U,
operand2
must be of format U.
The following characters may be used within a mask definition (the mask definition is
contained in mask-definition
for a constant mask and
operand2
for a variable mask):
Character | Meaning |
---|---|
. or ? or _ |
A period, question mark or underscore indicates a single position that is not to be checked. |
* or % |
An asterisk or percent mark is used to indicate any number of positions not to be checked. |
/ |
A slash (/) is used to check if a value ends with a specific character (or
string of characters).
For example, the following condition will be true if
there is either an IF #FIELD = MASK (*'E'/) |
A
|
The position is to be checked for an alphabetical character (upper or lower case). |
'c' |
One or more positions are to be checked for the characters bounded by apostrophes. Alphanumeric characters with hexadecimal numbers lower than H'40' (blank) are not allowed. The characters to be checked for are dependent on the TQMARK parameter:
If |
C
|
The position is to be checked for an alphabetical character (upper or lower case), a numeric character, or a blank. |
DD
|
The two positions are to be checked for a valid day notation (01 - 31;
dependent on the values of MM and YY/YYYY , if
specified; see also Checking
Dates).
|
H
|
The position is to be checked for hexadecimal content (A - F, 0 - 9). |
JJJ
|
The positions are to be checked for a valid Julian Day; that is, the day
number in the year (001-366, dependent on the value of YY/YYYY , if
specified. See also Checking
Dates.)
|
L
|
The position is to be checked for a lower-case alphabetical character (a - z). |
MM
|
The positions are to be checked for a valid month (01 - 12); see also Checking Dates. |
N
|
The position is to be checked for a numeric digit. |
n... |
One (or more) positions are to be checked for a numeric value in the range
0 - n .
|
n1-n2 or
n1:n2
|
The positions are checked for a numeric value in the range
n1-n2.
n1 and n2 must be of the same length. |
P
|
The position is to be checked for a displayable character (U, L, N or S). |
S
|
The position is to be checked for special characters. |
U
|
The position is to be checked for an upper-case alphabetical character (A - Z). |
X
|
The position is to be checked against the equivalent position in the value
(operand2 ) following the
mask-definition.
|
YY
|
The two positions are to be checked for a valid year (00 - 99). See also Checking Dates. |
YYYY
|
The four positions are checked for a valid year (0000 - 2699). Use
the COMPOPT option MASKCME=ON to restrict the range of
valid years to 1582 - 2699; see also Checking Dates. If the profile parameter
MAXYEAR is set to 9999, the upper year
limit is 9999.
|
Z
|
The position is to be checked for a character whose left half-byte is
hexadecimal A -
F, and whose right half-byte is hexadecimal 0 - 9.
This may be used
to correctly check for numeric digits in negative numbers. With Within a mask, use only one |
The definition of the character properties (for example, special character) may be
modified using the SCTAB
profile parameter.
If the CP
profile parameter is set to a value other than
OFF
, the character properties (such as upper or lower case alphabetical
character) derive from the character properties of the code page that is being used
for the Natural session. As a consequence, for example, the characters recognized as
alphabetical characters may be different from the default characters a - z and A - Z.
The length of the mask determines how many positions are to be checked.
DEFINE DATA LOCAL 1 #CODE (A15) END-DEFINE ... IF #CODE = MASK (NN'ABC'....NN) ...
In the above example, the first two positions of #CODE
are to be checked
for numeric content. The three following positions are checked for the contents
ABC
. The next four positions are not to be checked. Positions ten and
eleven are to be checked for numeric content. Positions twelve to fifteen are not to be
checked.
Only one date may be checked within a given mask. When the same date component
(JJJ
, DD
, MM
, YY
or
YYYY
) is specified more than once in the mask, only the value of the last
occurrence is checked for consistency with other date components.
When dates are checked for a day (DD
) and no month (MM
) is
specified in the mask, the current month will be assumed.
When dates are checked for a day (DD
) or a Julian day (JJJ
)
and no year (YY
or YYYY
) is specified in the mask, the current
year will be assumed.
When dates are checked for a 2-digit year (YY
), the current century will
be assumed if no Sliding or Fixed Window is set. For more details about Sliding or Fixed
Windows, refer to profile parameter YSLW
in the Parameter
Reference.
MOVE 1131 TO #DATE (N4) IF #DATE = MASK (MMDD)
In this example, month and day are checked for validity. The value for month (11) will be considered valid, whereas the value for day (31) will be invalid since the 11th month has only 30 days.
IF #DATE(A8) = MASK (MM'/'DD'/'YY)
In this example, the content of the field #DATE
is be checked for a valid
date with the format MM/DD/YY
(month/day/year).
IF #DATE (A8) = MASK (1950-2020MMDD)
In this example, the content of field #DATE
is checked for a four-digit
number in the range 1950 to 2020 followed by a valid month and day in the current year.
Note:
Although apparent, the above mask does not allow to check for a valid date in the
years 1950 through 2020, because the numeric value range 1950-2020 is checked
independent of the validation of month and day. The check will deliver the intended
results except for February, 29, where the result depends on whether the current year is
a leap year or not. To check for a specific year range in addition to the date
validation, code one check for the date validation and another for the range
validation:
IF #DATE (A8) = MASK (YYYYMMDD) AND #DATE = MASK (1950-2020)
IF #DATE (A4) = MASK (19-20YY)
In this example, the content of field #DATE
is checked for a two-digit
number in the range 19 to 20 followed by a valid two-digit year (00 through 99). The
century is supplied by Natural as described above.
Note:
Although apparent, the above mask does not allow to check for a valid year in the
range 1900 through 2099, because the numeric value range 19-20 is checked independent of
the year validation. To check for year ranges, code one check for the date validation
and another for the range validation:
IF #DATE (A10) = MASK (YYYY'-'MM'-'DD) AND #DATE = MASK (19-20)
If the value for the mask check is to be taken from either a constant or a variable,
this value (operand2
) must be specified
immediately following the mask-definition
.
operand2
must be at least as long as the
mask.
In the mask, you indicate each position to be checked with an X
, and each
position not to be checked with a period (.) or a question mark (?) or an underscore
(_).
DEFINE DATA LOCAL 1 #NAME (A15) END-DEFINE ... IF #NAME = MASK (..XX) 'ABCD' ...
In the above example, it is checked whether the field #NAME
contains
CD
in the third and fourth positions. Positions one and two are not
checked.
The length of the mask determines how many positions are to be checked. The mask is left-justified against any field or constant used in the mask operation. The format of the field (or constant) on the right side of the expression must be the same as the format of the field on the left side of the expression.
If the field to be checked (operand1
) is of
format A, any constant used (operand2
) must be
enclosed in apostrophes. If the field is numeric, the value used must be a numeric
constant or the content of a numeric database field or user-defined variable.
In either case, any characters/digits within the value specified whose positions do not
match the X
indicator within the mask are ignored.
The result of the MASK
operation is true when the indicated positions in
both values are identical.
** 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
In the above example, the record will be accepted if the fifth and sixth positions of
the field CITY
each contain the character N
.
When performing range checks, the number of positions verified in the supplied variable
is defined by the precision of the value supplied in the mask specification. For
example, a mask of (...193...)
will verify positions 4 to 6 for a
three-digit number in the range 000 to 193.
Additional Examples of Mask Definitions:
In this example, each character of #NAME
is checked for an
alphabetical character:
IF #NAME (A10) = MASK (AAAAAAAAAA)
In this example, positions 4 to 6 of #NUMBER
are checked for a numeric
value:
IF #NUMBER (A6) = MASK (...NNN)
In this example, positions 4 to 6 of #VALUE
are to be checked for the
value 123
:
IF #VALUE(A10) = MASK (...'123')
This example will check if #LICENSE
contains a license number which
begins with NY-
and whose last five characters are identical to the
last five positions of #VALUE
:
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
The following condition would be met by any value which contains NAT
and AL
no matter which and how many other characters are between
NAT
and AL
(this would include the values
NATURAL
and NATIONALITY
as well as NATAL
):
MASK('NAT'*'AL')
Legacy applications often have packed or unpacked numeric fields redefined with
alphanumeric or binary fields. Such redefinitions are not recommended, because using the
packed or unpacked field in an assignment or computation may lead to errors or
unpredictable results. To validate the contents of such a redefined field before the
field is used, enter an N
for each digit of the field (counting the digits
before and after the decimal point), minus one, followed by a Z
(see
Characters in a
Mask).
IF #P1 (P1) = MASK (Z) IF #N4 (N4) = MASK (NNNZ) IF #P5 (P5) = MASK (NNNNZ) IF #P32 (P3.2) = MASK (NNNNZ)
For further information about checking field contents, see MASK Option Compared with IS Option.
This section points out the difference between MASK
option and
IS
option and contains a sample program to illustrate the difference.
The IS
option can be used to check whether the content of an alphanumeric or
Unicode field can be converted to a specific other format, but it cannot be used to check
if the value of an alphanumeric field is in the specified format.
The MASK
option can be used to validate the contents of a redefined packed
or unpacked numeric variable.
** 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
Output of Program 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
Syntax:
operand1 [NOT ] MODIFIED
|
This option is used to determine whether the content of a field has been modified during
the execution of an INPUT
or
PROCESS PAGE
statement. As
a precondition, a control variable must have been assigned using the parameter CV
.
Operand Definition Table:
Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
operand1
|
S | A | C | no | no |
Attribute control variables referenced in an INPUT
or PROCESS
PAGE
statement are always assigned the status "not modified" when
the map is transmitted to the terminal.
Whenever the content of a field referencing an attribute control variable is modified, the attribute control variable has been assigned the status "modified". When multiple fields reference the same attribute control variable, the variable is marked "modified" if any of these fields is modified.
If operand1
is an array, the result will be true
if at least one of the array elements has been assigned the status "modified"
(OR
operation).
The Natural profile parameter CVMIN
may be used to determine if an attribute
control variable is also to be assigned the status "modified" if the value of
the corresponding field is overwritten by an identical value.
** 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
Output of Program LOGICX06
:
#A #B
After entering any value and pressing ENTER, the following output is displayed:
FIELD #A OR #B HAS BEEN MODIFIED
Syntax:
operand1 |
|
SCAN
|
operand2 |
Operand Definition Table:
Operand | Possible Structure | Possible Formats | Referencing Permitted | Dynamic Definition | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
operand1
|
C | S | A | N | A | U | N | P | yes | no | |||||||||||
operand2
|
C | S | A | U | B* | yes | no |
*
operand2
may only be binary if
operand1
is of format A or U. If
operand1
is of format U and
operand2 is of format B, then the length of
operand2
must be even.
The SCAN
option is used to scan for a specific value within a field.
The characters used in the SCAN
option
(operand2
) may be specified as an alphanumeric
or Unicode constant (a character string bounded by apostrophes) or the contents of an
alphanumeric or Unicode database field or user-defined variable.
Caution:
Trailing blanks are automatically eliminated from
operand1
and
operand2
. Therefore, the SCAN
option cannot be used to scan for values containing trailing blanks.
operand1
and
operand2
may contain leading or embedded
blanks. If operand2
consists of blanks only,
scanning will be assumed to be successful, regardless of the value of
operand1
; confer EXAMINE FULL
statement if
trailing blanks are not to be ignored in the scan operation.
The field to be scanned (operand1
) may be of
format A, N, P or U. The SCAN
operation may be specified with the equal
(EQ
) or not equal (NE
) operators.
The length of the character string for the SCAN
operation should be less
than the length of the field to be scanned. If the length of the character string
specified is identical to the length of the field to be scanned, then an
EQUAL
operator should be used instead of 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
Output of Program LOGICX02
:
ENTER SCAN VALUE:
A scan for example for LL
delivers three matches in 15 names:
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
Syntax:
parameter-name [NOT ] SPECIFIED
|
This option is used to check whether an optional parameter in an invoked object (subprogram or external subroutine) has received a value from the invoking object or not.
An optional parameter is a field defined with the keyword OPTIONAL
in the DEFINE DATA PARAMETER
statement of
the invoked object. If a field is defined as OPTIONAL
, a value can - but need
not - be passed from an invoking object to this field.
In the invoking statement, the notation nX
is
used to indicate parameters for which no values are passed.
If you process an optional parameter which has not received a value, this will cause a
runtime error. To avoid such an error, you use the SPECIFIED
option in the
invoked object to check whether an optional parameter has received a value or not, and
then only process it if it has.
parameter-name
is the name of the parameter as
specified in the DEFINE DATA PARAMETER
statement of the invoked object.
For a field not defined as OPTIONAL
, the SPECIFIED
condition is
always TRUE
.
Calling Programming:
** 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
Subprogram Called:
** 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
Output of Program LOGICX07
:
Page 1 14-01-14 11:25:41 #PARM1: ABC #PARM2 is not specified #PARM3 is specified #PARM3: 20