Chapter 6:  Conditional Clauses & Expressions

This chapter describes two important capabilities within ACCENT R: Conditional Clauses and Expressions.  Conditional Clauses, which limit or restricts execution the scope of a command or statement, are made up of an introductory preposition (e.g., IF or ; WHEN) followed by an expression.  Conditional Clauses must always contain expressions.

ACCENT R provides a particularly valuable set of capabilities for manipulating dates, and these are discussed in the last part of this chapter.

Since Conditional Clauses and Expressions are language elements and allowed in most commands and statements, they are presented first.

CONDITIONAL CLAUSES

Many ACCENT R commands and statements enable execution to be controlled through the use of conditional clauses.  A conditional clause specifies the criteria that must be met for the specified action to take place.  For example, the command:

EXTRACT IF DIST='DENVER' AND QTY GT 100

Specifies that each record in the Data Set (DS) is to be tested, and only those records are to be extracted in which the field DIST contains the value DENVER and the field QTY contains a value greater than 100.  Similarly, the clause

UNLESS ONHAND<QTY

Specifies that the current ACCENT R command is to execute unless the field ONHAND contains a value less than the field QTY.

Most conditional clauses begin with the word IF or the word UNLESS, and contain one or more relational expressions separated by AND or OR.

Some valid conditional clauses follow:

UNLESS AGE GE 21
IF LNAME BEGINS WITH 'SE' OR 'SI'
IF (DIST=1 OR 4) AND WAREHOUSE=9 IF
ONHAND+ONORDER<200 AND >0
UNLESS QTY*PRICE LT 2000-DISCOUNT
IF DIV=5 AND (SALESMAN=41 OR 42 OR 93)

There are two additional kinds of conditional clauses; each used in a special processing situation.  Each is introduced by a unique word that alerts ACCENT R to the special processing wanted.

The STOP/END conditional clause terminates processing of a Data Set (DS) when the conditions are met.  Since this clause does not examine all records in the DS, it uses fewer computer resources than the IF/UNLESS clause.

EXAMPLE

If you have a data set with 100,000 records and you are looking for the record with the name “ADAM”, it might be record 841 and the following command would prevent you from reading the 99159 records.

EXTRACT END IF NAME = “ADAM” IF NAME = “ADAM” SHOW ADDRI, ADDR2

The END clause will process no other record after this record is found and the if clause instructs the EXTRACT command to only display the records containing “ADAM”.

The difference between STOP and END is that with STOP record processing terminates when the condition is satisfied and the record meeting the criteria is not considered for processing.  On the other hand, with the END clause, this record is processed.

The WHEN conditional clause is used only when access to a DS is through a DI.  It can only test fields that are key fields in the domain used, but it is very efficient, because it examines the index rather than the DS.  See Chapter 9 on Interactive Commands for a complete description.

RELATIONAL OPERATORS

A relational expression consists of an operand and a relational operator, usually followed by another operand.  The operands can be arithmetic expressions, constants, string expressions, fields, functions, or date expressions.  Note that processing of a Data Set (DS) can be preceded by the clarity word IS or DOES.  Any relational operator can be negated by preceding it with NOT.  If a clarity word and NOT are used together, the IS or DOES must precede the NOT:

EXAMPLE

 "IF FLD DOES NOT BEGIN WITH 'A'".

The valid relational operators are shown in the following two tables.

When alpha or character data are compared, two ENABLE; DISABLE options will affect the result: FIELDTRIM and SEQUENCE LOWER.

The general relational operators, in Table 6-1, can be used with expressions of any data type.

RELATIONAL OPERATOR MEANING EXAMPLE
 > or GT  Greater Than  QTY>50
 = or EQ  Equal To  DIST='DENVER'
 < or LT  Less Than  AGE<21
 #, <>, ><, or NE  Not Equal To  MODEL#4
 >=, =>, or GE  Greater Than or Equal To  PAY GE 300
 <=, =<, or LE  Less Than or Equal To  PAY LE 300
 BETWEEN...AND

 Between...and, inclusive.

 Same as > = x AND < = y.

 The AND is not a logical

 operator in this context.

 QTY BETWEEN 5 AND 10

Table 6-1 General Relational Operators

The relational string operators, in Table 6-2, are valid only with character or alpha data or expressions.  If ENABLE FIELDTRIM is in effect, or if the system function @RTRIM is applied to the value, trailing blanks are trimmed when the string value in a field or literal is tested.  Leading blanks can be trimmed with the system function @LTRIM.

Four of the string operators are unary: that is, they take only one operand.  They are ALPHA, CALENDRICAL, INTEGRAL, and NUMERIC.

 RELATIONAL

 OPERATOR

 MEANING  EXAMPLE
 ALPHA

Contain(s) only letters and spaces.

 NAME ALPHA
 BEGIN/S/

All characters of first operand match beginning characters of second operand.

 FLDA BEGINS "YES", "NO"
 BEGIN/S/ WITH

Beginning characters of first operand match all characters of second operand.

 CITY BEGINS WITH 'SAN'
 CALENDRICAL

Resembles a date and could be converted to one with the @CAL function.

Note:  CALENDRICAL does not work with strings that can be processed with @DTVAL.

 INV.DATE CALENDRICAL
 DESCRIBE/S/

Represents a value defined by the quoted mask.  See mask description that follows this table.

 '###-####'

 DESCRIBES PHONE

 END/S/

All characters of first operand match ending characters of second operand.

 'SON' ENDS LNAME
 END/S/ WITH

Ending characters of first operand match all characters of second operand.

 LNAME ENDS WITH 'SON'
 HAS, HAVE

First operand contains second operand.

 DESC HAS 'ELEC'
 IN

First operand is contained in second operand.

 'BIN' IN LICENSES
 INTEGRAL

Contain(s) only digits, plus sigh (+), minus sign (-), and blanks.  Resembles an integer and could be converted to one with the @IVAL function.

 PCODE INTEGRAL
 LOOK/S/ LIKE

Conforms to the specified description.  See mask description that follow this table.

 FIELD LOOKS LIKE

 ###=####

 NUMERIC

Contain(s) only digits, periods (.), plus (+), or minus (-) signs, and leading or trailing blanks; must contain at least one digit.  Resembles a real or numeric value and could be converted to one using the @RVAL or @NVAL function.

 PRICE NUMERIC

Table 6-2 Relational String Operators Continued

The relational operators that are made up of letters must be preceded and followed with blanks, e.g., QTY GT 25.  The operators made up of signs need not, but can, be preceded and followed with blanks, e.g., QTY>25.

The masks for LOOK/S/LIKE and DESCRIBE/S/ contain wildcard characters that are used in a one-to-one positional comparison as follows:

 MASK CHARACTER  CORRESPONDING CHARACTER
*  Can be anything
C  Must be a letter, digit, or space
A  Must be a letter or space
#  Must be a digit
.  Must be a space
=  Must match the next character in the mask

STRING COMPARISONS

There are three types of string comparisons (or tests) and each has its own rules.

  1. Basic Equality Tests

 OPERATOR  EXAMPLE
= or EQ "A" = "A"
# or NE "A" # "Z"
> or GT "W" > "M"
>= or GE "B" >= "A"
< or LT "A" < "B"
<= or LE "A" <= "B"

Rules

  1. Containment, position, or pattern tests: The operators in this group are:

 OPERATOR  EXAMPLE
 BEGINS  "A" BEGINS "ABCDE"
 BEGINS WITH  "ABCDE" BEGINS WITH "A"
 ENDS  "E" ENDS "ABCDE"
 ENDS WITH  "ABCDE" ENDS WITH "E"
 IN  "C" IN "ABCDE"
 HAS  "ABCDE" HAS "C"
 DESCRIBES  "C###" DESCRIBES "A123"
 LOOKS LIKE  "A123" LOOKS LIKE "C###"

Rules

FIELD LOOKS LIKE "CCC"

is evaluated as

FIELD LOOKS LIKE "CCC*****"
  1. Data Type Tests

OPERATOR

EXAMPLE

ALPHA

"AB XYZ" ALPHA

CALENDRICAL

"12-25-86" CALENDRICAL

INTEGRAL

"12345" INTEGRAL

NUMERIC

"12.34" NUMERIC

Rules

SPECIAL MODIFIERS FOR USE WITH OCCURS FIELDS

The special modifiers ANY and ALL allow all occurrences of an array to be tested with a single expression.  The form "{ANY; ALL} field_name" can be the first operand in a relational expression. ANY evaluates to true if any of the occurrences meets the condition set. ALL evaluates to true if all occurrences meet the condition set.  The field name used with ANY or ALL must be that of an array field, and it must be expressed without a subscript.  No arithmetic operation may be performed on the ANY/ALL field.

The first expression below is valid; the second is not, since the ANY/ALL modifiers can only be used to the left of the operator.

IF ANY FLDA = 1
IF 1 = ANY FLDA

All 12 occurrences of the field

MO_SALES,FLOAT,10,2, OCCURS 12

Are checked by the IF;UNLESS clauses

IF ANY MO_SALES LE 10000
UNLESS ALL MO_SALES > 0

Arithmetic Operators

Arithmetic Operators are used in conditional expressions, function arguments, assignment statements, and other locations where a value is needed.  An arithmetic expression represents an arithmetic value, which is integer, numeric, or real.

Numerical fields or constants of any type (INT, FLOAT, REAL, BIT, and SIGNEDBIT) can be intermixed in the same expression; INT values are converted to FLOAT values as necessary when they are encountered in an expression.  Calculations are performed as either integer or numeric (double precision) unless all values are REAL.  BIT and SIGNEDBIT data are treated as binary INT.  Division operations on integer fields or constants produce truncated integer results.  For example

5/2 = 2, not 2.5

If one of the values in this example is integer and the other is numeric, ACCENT R converts all values to numeric.  Thus

5./2 = 2.5
5/2. = 2.5

Note, however, that

1/2 + 1./2. = .5, not 1.0

Since the result of the first division is truncated to zero before, the second division and addition are performed.

The functions @NUM, @REAL, and @INT can be used to alter values to get the arithmetic precision needed.  For example,

*TYPE @INT 5.1/2
2
*TYPE @NUM 5/2
2.5
*TYPE @REAL 5/2
2.5

Table 6-3 lists the valid arithmetic operators.  It also groups together those operators that have the same precedence in an expression that contains several operators, and lists the groups in the order of precedence.

Operators of equal precedence are listed in the same group, and the groups are listed in the order of precedence.

OPERATOR

MEANING

** or ^

Exponentiation; a value raised to a power.  The form is value ** power.

-

Unary minus; negates the value following it. 

For example:  -7.1

+

Unary plus; can be used but is ignored.

BNOT

Binary bit-wise NOT; one's complement.  For INT, SIGNEDBIT, or BIT data only.

*

Multiplication

/

Division.  Dividing an integer by an integer produces a truncated integer result. 

For example:  5/2 = 2.

MOD

Modulo.  Produces the remainder of a division operation. 

For example:  5 MOD 2 = 1/

+

Addition

-

Subtraction

BEQV

Binary bit-wise equivalence.

BAND, BOR

Binary bit-wise AND and OR

BXOR

Binary bit-wise exclusive OR.

BLSH, BRSH

Binary left and right shift.

BALSH, BARSH

Binary arithmetic left and right shift.

BLCY, BRCY

Binary left and right rotation.

Table 6-3 Arithmetic Operators and Their Order of Evaluation

Arithmetic expressions can appear on both sides of a relational operator; for example,

QTY*PRICE GT 2000-DISCOUNT

The binary operators are used with INT, SIGNEDBIT, or BIT data only.

Results of AND, OR, and equivalence bit-wise operation, where a and b are individual bits, are as follows:

a b a BAND b a BOR b a BXOR b a BEQV b
0 0 0 0 0 1
0 1 0 1 1 0
1 0 0 1 1 0
1 1 1 1 0 1

Shift and rotate binary operations produce the following results:

OPERATOR OPERATION IF N IS POSITIVE IF N IS NEGATIVE
X BLSH N Left Shift

X shifted left

N bits,

zero fill

X shifted right

@ABS(N) bits,

zero fill

X BRSH N

Right Shift

X shifted right

N bits,

zero fill

X shifted left

@ABS(N) bits,

zero fill

X BALSH N

Arithmetic

Left Shift

X shifted left

N bits, sign bit

preserved if possible

X shifted to the right

@ABS(N) bits,

sign bit unchanged

X BARSH N

Arithmetic

Right Shift

X shifted right

N bits,

sign bit fill

X shifted to the left

@ABS(N) bits,

sign bit unchanged

X BLCY N

Left Cycle

X Cycled Left

N bits

X Cycled Right

@ABS(N) bits,

X BRCY N

Right Cycle

X Cycled Right

N bits

X Cycled Left

@ABS(N) bits,

STRING OPERATOR

The string operator + can be used to concatenate literals, functions, or fields, as long as the values are strings.

EXAMPLE

*SET "A" + "B" + "C" TO @STRING
*TYPE @STRING
ABC

LOGICAL OPERATORS

An IF/UNLESS clause can contain one or more relational expressions connected by one of the logical operators AND or OR.  A third logical operator, NOT, is used to reverse the value of a relational operator.

The AND operator means that the relational expressions on both sides must be true for the conditional clause to be satisfied.  For example, the conditional clause requires that both the DIST field must equal the character string DENVER and the QTY field must contain a value greater than 100.

IF DIST='DENVER' AND QTY GT 100

The OR operator means that at least one of the relational expressions on either side of the OR operator must be true for the conditional clause to be satisfied.  For example, the conditional clause can be satisfied in three ways: when the value of the DIST field is DENVER, when the value of the QTY field is greater than 100, or when both these conditions exist.

IF DIST='DENVER' OR QTY GT 100

The AND operator has precedence over the OR operator.  For example, the conditional clause;

IF DIST='DENVER' OR QTY GT 100 AND BAL LT 200

is equivalent to:

IF DIST='DENVER' OR (QTY GT 100 AND BAL LT 200)

Similarly, the conditional clause;

UNLESS DIST='DENVER' AND QTY GT 100 OR BAL LT 200

Is equivalent to:

UNLESS (DIST='DENVER' AND QTY GT 100) OR BAL LT 200

The logical operator NOT can precede any of the relational operators to negate the condition.  For example, the conditional clause;

IF 'BIN' NOT IN LICENSES

Is satisfied when the LICENSES field does not contain the character string BIN.

Care must be used when combining a negative relational operator with one or more logical operators.  For example, the expression;

IF 2 NE 1 OR 2 OR 3

Will always evaluate to true, since two is not equal to one.  However,

IF 2 NE 1 AND 2 AND 3

Always evaluate to false, since 2 is equal to 2.

CONTROLLING THE ORDER OF EVALUATION
    IN EXPRESSIONS &AND IF/UNLESS CLAUSES

In ACCENT R, parentheses ( ) can be used to change the normal order of evaluation or simply to improve readability.  ACCENT R evaluates expressions enclosed in parentheses first, following the usual order of evaluation within the parentheses.  When several sets of parentheses appear, ACCENT R proceeds from left to right, evaluating expressions enclosed in parentheses first.  If parentheses appear within parentheses, the innermost parenthetical expression is evaluated first.

For example, the desired result could not  be obtained in the following conditional clause without parentheses.

IF (BAL+QTY*PRICE)*1.18>350

If the parentheses were omitted, ACCENT R would evaluate it according to the usual order, specifically:  First do QTY * PRICE, then results * 1.18, then + BAL.

Similarly, parentheses can be used to alter the normal order of evaluation of logical operators.  For example, the following conditional clause could not  be easily specified without parentheses.

IF (AREA='MATH' OR JOB=17) AND DEPT=5

If the parentheses were omitted, ACCENT R would evaluate it according to the usual order discussed in “Logical Operators” above, that is:

IF AREA='MATH' OR (JOB=17 AND DEPT=5)

The same uses of parentheses also apply in the evaluation of arithmetic expressions.

EXAMPLE

(A+B) * C TO D

Mean:  add A and B then multiple by C

ABBREVIATING IF/UNLESS CLAUSES

The rules for abbreviating IF/UNLESS clauses are as follows:

  1. When the left side of a relational expression and the relational operator are to be repeated in succession, they can be omitted after the initial specification if there are no intervening parentheses.

  2. When the left side of a relational expression is to be repeated in succession, it can be omitted after the initial specification if there are no intervening parentheses.

  3. When a series of expressions would normally be separated by OR operators, the word OR can be replaced with a comma (,).

  4. The relational operator BETWEEN…AND cannot be included in abbreviated clauses.

The following three examples illustrate these rules.

IF A=1 OR 2 OR 3   means   IF A=1 OR A=2 OR A=3
IF B>1 AND <10 OR =77   means   IF B>1 AND B<10 OR B=77
IF C=2,4,6 OR 8    means   IF C=2 OR C=4 OR C=6 OR C=8

Since a comma and OR are synonymous, a comma cannot be followed immediately by the word OR.  Thus, the following is an invalid clause:

IF X=1,2,3, OR 4

The correct form is:

IF X=1,2,3 OR 4   or   IF X=1,2,3,4

Several of the relational string operators have reverse forms, as shown in the table earlier, to facilitate abbreviating.  For example, the conditional clause;

IF 'ELEC' IN DESC OR NAME

Could not be abbreviated using the reverse HAS operator.  The conditional clause "IF DESC OR NAME HAS 'ELEC'" is invalid because the first expression DESC must be followed  by a relational operator.  To use the HAS operator, enter:

IF DESC HAS 'ELEC' OR NAME HAS 'ELEC'

Consider the abbreviated conditional clause:

IF PROJECT ENDS WITH 'RDD' OR 'DOC'

This could not be abbreviated with the reverse ENDS operator.  Similarly, the abbreviated conditional clause;

UNLESS 'DOC' ENDS PROJECT OR EFFORT

Could not be abbreviated with the reverse ENDS WITH operator.  Using the ENDS WITH operator, enter:

UNLESS PROJECT ENDS WITH 'DOC' OR EFFORT ENDS WITH 'DOC'

DATE AND TIME ARITHMETIC

ACCENT R provides a powerful capability for manipulating dates.  It is possible to add and subtract dates with special integer expressions, or subtract one date from another.  Any of the general relational operators shown in the subsection "Relational Operators" can also be used to compare dates.

The ENABLE DATE command affects the format in which ACCENT R accepts date input and in which dates are output.  Default date format is AMERICAN (see ENABLE DATE command in Chapter 8).

A date field of any valid type can be used in an expression with a date field of any other valid type. ACCENT R takes care of conversion.

Dates that are stored in alpha or character fields or literal dates must be converted with the @CAL  or @DVAL function before being used in date arithmetic or comparison.  Integer values can be converted to dates with the @MAKDAT function.

There are two general forms for date arithmetic-one for integers and one for dates.

SYNTAX

FORM 1:

date + ae DAYS + ae MONTHS + ae EMONTHS + ae YEARS

date + ae HOURS + ae MINUTES + ae SECONDS

date

is a date field, function, or expression.

ae

is an integer-valued expression, function, field, or constant.  It is used to indicate the quantity of SECONDS, MINUTES, HOURS, DAYS, MONTHS, EMONTHS, and YEARS to add or subtract from date.

DAYS

indicates days to be added to or subtracted from date

MONTHS

indicates months to be added to or subtracted from date

EMONTHS

adds or subtracts the given number of months, and rounds up to the last day of the month

YEARS

indicates years to be added to or subtracted from date

HOURS

indicates hours to be added to or subtracted from date

MINUTES

indicates minutes to be added to or subtracted from date

SECONDS

indicates seconds to be added to or subtracted from date

FORM 2:

date1 - date2

date1, date2

can be any date field, function, or expression

FORM 1:

If the result of the expression exceeds the last day of the month, the last valid day of the appropriate month will be returned.

*TYPE @CAL "01/31/1993" + 1 MONTHS
02/28/1993

Rounding to the end of the month with EMONTHS.

*TYPE @CAL "02/15/1993" + 1 EMONTHS
03/31/1993

In general, any combination and any number of operations that make sense are allowed, so long as one of the first two operands is a date expression.  Thus, both of the following are valid:

date + ae DAYS + ae YEARS - ae DAYS + ae MONTHS + ae YEARS
ae DAYS + date
*SET @CAL "12/31/92" TO %DAT
*TYPE %DAT+2 DAYS
01/02/1993
@CAL "01/12/93" - 13 DAYS   = 12/30/1993
@CAL "10/22/93" + 2 MONTHS   = 12/22/1993
@CAL "10/22/93" + 2 EMONTHS   = 12/31/1993
@CAL "10/22/90" - 15 YEARS   = 10/22/1975
@CAL "10/22/90" - 15 YEARS + 3 MONTHS = 1/22/1976
@CAL "10/22/90" + 15 YEARS   = 10/22/2005

GIVEN:

@DTSTR (@DATE) = "05/04/1993 00:00:00.000"

THEN:

@DTSTR (@DATE -  1 HOURS)   = "05/03/1993 23:00:00.000"
@DTSTR (@DATE - 23 MINUTES)   = "05/03/1993 23:37:00.000"
@DTSTR (@DATE +  8 SECONDS)   = "05/04/1993 00:00:08.000"

FORM 2:

The value of Form 2 is always an integer representing the number of days between the two dates.  Only the minus operator can be used.

@CAL "04/30/93" - @CAL "-04/01/93" = 29
@CAL "04/30/93" - @CAL "-03/01/93" = 60

NOTES:  The two general forms can be combined in one expression: for example, date1 + (date2 - date3) DAYS.

ACCENT R handles leap years and centuries correctly.

Excessive values as arguments to HOURS, MINUTES, and SECONDS will trigger a floating-point rounding error, which causes variances in the expected time value for the seconds-of-the-day.

DATE CONSTANTS

Date constants can be used in any ACCENT R date function or in date arithmetic where a date value needs to be specified.

\dYYYYMMDD or \DYYYYMMDD
\dYYMMDD or \DYYMMDD

WHERE:

*TYPE \D19880121
01/21/1988
*TYPE \D880121
01/21/1988
*TYPE \D19880121 + 2 DAYS
01/23/1988
*TYPE @DATSTR(\D19880121, "WWW, MMM DD, YYYY")
Thu, Jan 21, 1988

OCTAL AND HEXADECIMAL CONSTANTS

Octal and hexadecimal constants can be used at any place in ACCENT R where an integer value can be specified.

Octal constants

\o <integer> or \O <integer>

Hexadecimal constants

\h <integer> or \H <integer>

EXAMPLE

*TYPE \O1000
512
*TYPE\Habc1
43969