Back to Contents


Basic Syntax Elements

Summary:

See also: Variables, Data Types, Expressions, Literals.


Summary

This section describes basic syntax elements that can appear in Expressions. There are different sort of basic syntax elements such as classic arithmetic, string and comparison operators, pre-defined variables and registers like SQLSTATE, and predefined functions like SFMT() or TODAY.

Elements of an expressions are evaluated according to their precedence, from highest to lowest, as described in the Order of Precedence List. Use parentheses to instruct the runtime system to evaluate the expression in a different way than the default order of precedence.


List of Basic Syntax Elements

Comparison Operators

Logical Operators

Arithmetic Operators

Character String Handling

Associative Syntax Elements

Predefined SQL Registers

Data Type related

Assignment Operators

Date and Time Manipulation

Form Field and Dialog Handling


Order of Precedence List

The following list describes the precedence order of the basic syntax elements. For example, the MOD operator has a higher precedence as the * operator. When computing an expression like ( 33 MOD 2 * 5 ), the runtime system first evaluates (33 MOD 2) = 1 and then evaluates (1 * 5) = 5. You can change this by using parentheses: ( 33 MOD ( 2 * 5 ) ) = 3. The P column defines the precedence, from highest(14) to lowest(1). Note that some operators have the same precedence (i.e. are equivalent in evaluation order). The A column defines the direction of association (L=Left, R=Right, N=None).

Syntax Element  Description  Example 
14 CAST(v AS type) N Type casting CAST(var AS fgl.FglRecord)
14 INSTANCEOF L Type checking var INSTANCEOF java.lang.Boolean
13 UNITS L Single-qualifier interval (integer) UNITS DAY
12 + R Unary plus + number
12 - R Unary minus - number
11 ** L Exponentiation x ** 5
11 MOD L Modulus x MOD 2
10 * L Multiplication x * y
10 / L Division x / y
9 + L Addition x + y
9 - L Subtraction x - y
8 || L Concatenation "Amount:" || amount
7 LIKE R String comparison mystring LIKE "A%"
7 MATCHES R String comparison mystring MATCHES "A*"
6 < L Less than var < 100
6 <= L Less then or equal to var <= 100
6 > L Greater than var > 100
6 >= L Greater than or equal to var >= 100
6 == L Equals var == 100
6 <> or != L Not equal to var <> 100
5 IS NULL L Test for NULL var IS NULL
5 IS NOT NULL L Test for NOT NULL var IS NOT NULL
4 NOT L Logical inverse NOT ( a = b )
3 AND L Logical intersection expr1 AND expr2
2 OR L Logical union expr1 OR expr2
1 ASCII( ) R ASCII Character ASCII(32)
1 CLIPPED R Delete trailing blanks DISPLAY string CLIPPED
1 COLUMN (reports) R Begin line mode display PRINT COLUMN 32, "a"
1 (integer) SPACES R Insert blank spaces DISPLAY "a" (5) SPACES
1 SQLSTATE R SQL State Code IF SQLSTATE="IX000"
1 SQLERRMESSAGE R SQL Error Message DISPLAY SQLERRMESSAGE
1 USING R Format character string TODAY USING "yy/mm/dd"
1 := L Assignment var := "abc"

General Warnings

Pure SQL Synax Elements

The following are related to SQL syntax and not part of the language:

Report Routine Syntax Elements

The following are only available in the FORMAT section of report routines:

See Report Definition for more details.


PARENTHESES

Purpose:

Parentheses are typically used to associate a set of values or expressions to override the default order of precedence.

Syntax:

( expr [...] )

Notes:

  1. expr is a language expression.

Usage:

Parentheses can be used to change the precedence of operators.

Example:

01 MAIN
02   DEFINE n INTEGER
03   LET n = ( ( 3 + 2 ) * 2 )
04   IF n=10 AND ( n<=0 OR n>=20 ) THEN
05     DISPLAY "OK"
06   END IF
07 END MAIN

MEMBERSHIP

Purpose:

The period membership specifies that its right-hand operand is a member of the set whose name is its left-hand operand.

Syntax:

setname.element

Usage:

The dot notation is used to reference record members.

Example:

01 MAIN
02   DEFINE rec RECORD
03      n INTEGER,
04      c CHAR(10)
05   END RECORD
06   LET rec.n = 12345
06   LET rec.c = "abcdef"
07 END MAIN

ASSIGNMENT

Purpose:

Assigns a value to a variable and evaluates the expression.

Syntax:

variable := value

Usage:

The := assignment operator puts a value in the left-hand variable and the resulting value can again be used in an expression.

Do not confuse with the LET instruction. 

The := assignment operator has the lowest precedence.

Example:

In the next example, the := assignment operator will first evaluate (2*5), then set the var2 variable to 10 and finally set the var1 variable to 10.

01 MAIN
02   DEFINE var1, var2 INTEGER
03   LET var1 = var2 := 2*5
04 END MAIN

CAST

Purpose:

The CAST operator converts a value or object to the type or class specified.

Syntax:

CAST( expr AS type )

Notes:

  1. expr can be any expression supported by the language.
  2. type is a structured user defined type or a Java class.

Usage:

The CAST() operator is required when you want to assign a value or object reference to variable defined with a type or class which requires narrowing reference conversion. The example below shows code using the Java Interface facility of Genero BDL. When assigning a java.lang.StringBuffer reference to a java.lang.Object variable, widening reference conversion occurs and no CAST() operator is needed, but when assigning an java.lang.Object reference to a java.lang.StringBuffer variable, you must cast the object reference to a java.lang. StringBuffer.

Example:

01 IMPORNT JAVA java.lang.Object
02 IMPORNT JAVA java.lang.StringBuffer
03 MAIN
04   DEFINE sb1, sb2 java.lang.StringBuffer
05   DEFINE o java.lang.Object
06   LET sb1 = StringBuffer.create()
07   LET o = sb1 -- Widening Reference Conversion does not need CAST()
08   LET sb2 = CAST( o AS java.lang.StringBuffer ) -- Narrowing Reference Conversion needs CAST()
09 END MAIN

INSTANCEOF

Purpose:

The INSTANCEOF operator evaluates to TRUE if the object reference is of the type or class specified.

Syntax:

expr INSTANCEOF type

Notes:

  1. expr can be any expression supported by the language.
  2. type is a structured user defined type or a Java class.

Usage:

The INSTANCEOF operator is used to check if an expression (usually, an object reference) is one of the type or class specified by type.

Example:

01 IMPORNT JAVA java.lang.Object
02 IMPORNT JAVA java.lang.StringBuffer
03 IMPORNT JAVA java.lang.Number
04 MAIN
05   DEFINE o java.lang.Object
06   DEFINE sb java.lang.StringBuffer
07   LET sb = StringBuffer.create()
08   LET o = sb
09   DISPLAY sb INSTANCEOF java.lang.StringBuffer  -- shows 1
10   DISPLAY o INSTANCEOF java.lang.StringBuffer   -- shows 1
11   DISPLAY o INSTANCEOF java.lang.Number         -- shows 0
12 END MAIN

IS NULL

Purpose:

Checks for NULL expressions.

Syntax:

expr IS NULL

Notes:

  1. expr can be any expression supported by the language.

Usage:

The IS NULL operator can be used to test whether the left-hand expression is NULL.

This operator applies to most Data Types, except complex types like BYTE and TEXT.

Example:

01 MAIN
02   DEFINE n INTEGER
03   LET n = 257
04   IF n IS NULL THEN
05      DISPLAY "Something is wrong here"
06   END IF
07 END MAIN

See also: NVL().


EQUAL

Purpose:

Checks for equality of two expressions or for two record variables.

Syntax 1: Expression comparison

expr == expr

Syntax 2: Record comparison

record1.* == record2.*

Notes:

  1. expr can be any expression supported by the language.
  2. record1 and record2 are records with the same structure. 

Usage:

The == operator evaluates whether two expressions or two records are identical.

Note that a single equal sign (=) can be used as an alias for the == operator.

When comparing expressions using the first syntax, the result of the operator is FALSE when one of the operands is NULL. This first syntax applies to most Data Types, except complex types like BYTE and TEXT.

When comparing two records using the second syntax, the runtime system compares all corresponding members of the records. If a pair of members are different, the result of the operator is FALSE. When two corresponding members are NULL, they are considered as equal. This second syntax allows you to compare all members of records, but records must have the same structure.

Example:

01 MAIN
02   IF 256==257 THEN
03      DISPLAY "Something is wrong here"
04   END IF
05 END MAIN

DIFFERENT

Purpose:

Checks for non-equality of two expressions or for two record variables.

Syntax 1: Expression comparison

expr != expr

Syntax 2: Record comparison

record1.* != record2.*

Notes:

  1. expr can be any expression supported by the language.
  2. record1 and record2 are records with the same structure.

Usage:

The != operator evaluates whether two expressions or two records are different.

Note that a less-than sign followed by a greater-than sign (<>) can be used as an alias for the != operator.

When comparing expressions with the first syntax, the result of the operator is FALSE when one of the operands is NULL. This syntax applies to most Data Types, except complex types like BYTE and TEXT.

When comparing two records with the second syntax, the runtime system compares all corresponding members of the records. If one pair of members are different, the result of the operator is TRUE. When two corresponding members are NULL, they are considered as equal. This second syntax allows you to compare all members of records, but records must have the same structure.

Example:

01 MAIN
02   IF 256 != 257 THEN
03      DISPLAY "This seems to be true"
04   END IF
05 END MAIN

LOWER

Purpose:

The < operator is provided to test whether a value or expression is lower than another.

Syntax:

expr < expr

Usage:

Applies to most Data Types, except complex types like BYTE and TEXT.

LOWER OR EQUAL

Purpose:

The <= operator is provided to test whether a value or expression is lower than or equal to another.

Syntax:

expr <= expr

Usage:

Applies to most Data Types, except complex types like BYTE and TEXT.

GREATER

Purpose:

The > operator is provided to test whether a value or expression is greater than another.

Syntax:

expr > expr

Usage:

Applies to most Data Types, except complex types like BYTE and TEXT.

GREATER OR EQUAL

Purpose:

The >= operator is provided to test whether a value or expression is greater than or equal to another.

Syntax:

expr >= expr

Usage:

Applies to most Data Types, except complex types like BYTE and TEXT.

NULL VALUE SUBSTITUTION

Purpose:

The NVL() operator returns the second parameter if the first argument evaluates to NULL.

Syntax:

NVL( main-expr, subst-expr )

Notes:

  1. main-expr and subst-expr are language expressions.

Usage:

The NVL() operator evaluates the first argument, and returns the result if the value is not null, otherwise it returns the second argument. This allows you to write the equivalent of the following IF statement, in a simple scalar expression:

IF main-expr IS NOT NULL THEN
   LET variable = main-expr
ELSE
   LET variable = subst-expr
END IF

Example:

01 MAIN
02   DEFINE var VARCHAR(100)
03   LET var = arg_val(1)
04   DISPLAY "The argument value is: ", NVL(var, "NULL")
05 END MAIN

IMMEDIATE IF

Purpose:

The IIF() operator returns the second or third parameter according to the boolean expression given as first argument.

Syntax:

IIF( bool-expr, true-expr, false-expr )

Notes:

  1. bool-expr is a boolean expression.
  2. true-expr and false-expr are language expressions.

Usage:

The IIF() operator evaluates the first argument, the returns the second argument if the first argument is true, otherwise it returns the third argument. This allows you to write the equivalent of the following IF statement, in a simple scalar expression:

IF bool-expr THEN
   LET variable = true-expr
ELSE
   LET variable = false-expr
END IF

Example:

01   ...
02   MESSAGE IIF(userCanEdit(), "You can modify this record", "Modification is denied")
03   ...

NOT

Purpose:

The NOT operator is a typical logical NOT used to invert a Boolean expression.

Notes:

  1. bool-expr is a boolean expression.

Syntax:

NOT bool-expr

Example:

01 MAIN
02   IF NOT ( 256 != 257 ) THEN
03      DISPLAY "Something is wrong here"
04   END IF
05 END MAIN

AND

Purpose:

The AND operator is the logical intersection operator.

Syntax:

bool-expr AND bool-expr

Notes:

  1. bool-expr is a boolean expression.

Usage:

By default, the runtime system evaluates both operands on the left and right side of the AND keyword. This is the traditional behavior of the Genero language, but in fact the right operand does not need to be evaluated if the first operand evaluates to FALSE. This method is called short-circuit evalution, and can be enabled by adding the OPTIONS SHORT CIRCUIT clause at the beginning of the module.

Example:

01 MAIN
02   IF 256!=257 AND 256=257 THEN
03      DISPLAY "Sure?"
04   END IF
05 END MAIN

OR

Purpose:

The OR operator is the logical union operator.

Syntax:

bool-expr OR bool-expr

Notes:

  1. bool-expr is a boolean expression.

Usage:

By default, the runtime system evaluates both operands on the left and right side of the OR keyword. This is the traditional behavior of the Genero language, but in fact the right operand does not need to be evaluated if the first operand evaluates to TRUE. This method is called short-circuit evalution, and can be enabled by adding the OPTIONS SHORT CIRCUIT clause at the beginning of the module.

Example:

01 MAIN
02   IF TRUE OR FALSE THEN
03      DISPLAY "Must be true!"
04   END IF
05 END MAIN

SQLSTATE

Purpose:

The SQLSTATE predefined variable returns the ANSI/ISO SQLSTATE code when an SQL error occurred.

Syntax:

SQLSTATE

Usage:

Note that the SQLSTATE error code is a standard ANSI specification, but not all database engines support this feature. Check the database server documentation for more details.

Example:

01 MAIN
02   DATABASE stores
03   WHENEVER ERROR CONTINUE
04   SELECT foo FROM bar
05   DISPLAY SQLSTATE
06 END MAIN

SQLERRMESSAGE

Purpose:

The SQLERRMESSAGE predefined variable returns the error message if an SQL error occurred.

Syntax:

SQLERRMESSAGE

Example:

01 MAIN
02   DATABASE stores
03   WHENEVER ERROR CONTINUE
04   SELECT foo FROM bar
05   DISPLAY SQLERRMESSAGE
06 END MAIN

ASCII

Purpose:

The ASCII predefined function returns the character corresponding to the ASCII code passed as a parameter.

Syntax:

ASCII int-expr

Notes:

  1. int-expr is an integer expression.

Usage:

ASCII is typically used to generate a non-printable character such as NewLine or Escape.

In a default (U.S. English) locale, this is the logical inverse of the ORD operator.

This is not a function, but a real operator (it can, for example, be used as a function parameter).

ASCII is often used with parentheses ( ASCII(n) ), but these are not needed.

Example:

01 MAIN
02   DISPLAY ASCII 65, ASCII 66, ASCII 7
03 END MAIN

LIKE

Purpose:

The LIKE operator returns TRUE if a string matches a given mask.

Syntax:

expr [NOT] LIKE mask [ ESCAPE "char" ]

Notes:

  1. expr is any character string expression.
  2. mask is a character string expression defining the filter.
  3. char is a single char specifying the escape symbol.

Usage:

The mask can be any combination of characters, including the % and _ wildcards:

The ESCAPE clause can be used to define an escape character different from the default backslash. It must be enclosed in single or double quotes.

A backslash (or the escape character specified by the ESCAPE clause) makes the operator treat the next character as a literal character, even if it is one of the special symbols in the above list. This allows you to search for %, _ or \ characters.

Do not confuse with the LIKE clause of the DEFINE instruction. LIKE operators used in SQL statements are evaluated by the database server. This may have a different behavior than the LIKE operator of the language.

If you need to escape a wildcard character, keep in mind that a string constant must also escape the backslash character. As a result, if you want to pass a backslash to the LIKE operator (by using backslash as default escape character), you need to write four backslashes in the original string constant.

The next table shows some examples of string constants used in the source code and their equivalent LIKE pattern:

Original
String Constant

Equivalent
MATCHES pattern

Description
"%" % Matches any character in a non-empty string.
"_" _ Matches a single character. 
"abc%" abc% Starts with abc.
"*abc" %abc Ends with abc.
"%abc%" %abc% Contains abc.
"abc__" abc__ Strings equals abc followed by two additional characters. 
"\\%" \% Contains a single star character (the % wildcard is escaped)
"%abc\\\\def%" %abc\\def% Contains abc followed by a backslash followed by def (the backslash is escaped)

Example:

01 MAIN
02   IF "abcdef" LIKE "a%e_" THEN
03      DISPLAY "yes"
04   END IF
05 END MAIN

MATCHES

Purpose:

The MATCHES operator returns TRUE if a string matches a given mask.

Syntax:

expr [NOT] MATCHES mask [ ESCAPE "char" ]

Notes:

  1. expr is any character string expression.
  2. mask is a character string expression defining the filter.
  3. char is a single char specifying the escape symbol.

Usage:

The mask can be any combination of characters, including the *, ? and [] wildcards:

The ESCAPE clause can be used to define an escape character different from the default backslash. It must be enclosed in single or double quotes.

A backslash (or the escape character specified by the ESCAPE clause) makes the operator treat the next character as a literal character, even if it is one of the special symbols in the above list. This allows you to search for *, ?, [, ] or \ characters.

If you need to escape a wildcard character, keep in mind that a string constant must also escape the backslash character. As a result, if you want to pass a backslash to the MATCHES operator (by using backslash as default escape character), you need to write four backslashes in the original string constant.

The next table shows some examples of string constants used in the source code and their equivalent MATCHES pattern:

Original
String Constant

Equivalent
MATCHES pattern

Description
"*" * Matches any character in a non-empty string.
"?" ? Matches a single character. 
"abc*" abc* Starts with abc.
"*abc" *abc Ends with abc.
"*abc*" *abc* Contains abc.
"[a-z]*" [a-z]* Starts with a letter in the range a to z.
"abc??" abc?? Strings equals abc followed by two additional characters. 
"\\*" \* Contains a single star character (the * wildcard is escaped)
"*abc\\\\def*" *abc\\def* Contains abc followed by a backslash followed by def (the backslash is escaped)

Example:

01 MAIN
02   IF "55f-plot" MATCHES "55[a-z]-*" THEN
03      DISPLAY "Item reference format is correct."
04   END IF
05 END MAIN

CONCATENATE

Purpose:

The || operator is the concatenation operator that produces a string expression.

Syntax:

expr || expr

Notes:

  1. expr can be a character, numeric or date time expression.

Usage:

This operator has a high precedence; it can be used in parameters for function calls. The precedence of this operator is higher than LIKE and MATCHES, but less than arithmetic operators. For example, a || b + c is equivalent to (a||(b+c)).

If any of the members of a concatenation expression is NULL, the result string will be NULL.

Example:

01 MAIN
02   DISPLAY "Length: " || length( "ab" || "cdef" )
03 END MAIN

APPEND

Purpose:

The , (comma) language element appends a value to a string and returns the concatenated result.

Syntax:

char-expr , expr

Usage:

The comma operator concatenates expressions together. This operator can only be used in LET and DISPLAY instructions.

In earlier versions this was the only way to concatenate strings; you can also use the || concatenation operator.

Example:

01 MAIN
02   DISPLAY "Today:", TODAY, " and a number: ", 12345.67
03 END MAIN

SUBSTRING

Purpose:

The [] (square braces) extract a sub-string from a char/varchar variable.

Syntax:

char-variable [ start [, end ] ]

Notes:

  1. char-variable must be a character data type variable.
  2. start defines the position of the first character of the sub-string to be extracted.
  3. end defines the position of the last character of the sub-string to be extracted.
  4. If end is not specified, only one character is extracted.

Usage:

The [] (square braces) notation following a CHAR or VARCHAR variable extracts a sub-string from that character variable.

Note that sub-string expressions in SQL statements are evaluated by the database server. This may have a different behavior than the sub-string operator of the language.

Example:

01 MAIN
02   DEFINE s CHAR(10)
03   LET s = "abcdef"
04   DISPLAY s[3,4]
05 END MAIN

USING

Purpose:

The USING operator converts date, datetime and numeric values into a string with a formatting mask.

Syntax:

expr USING format

Notes:

  1. expr is a language expression.
  2. format is a string expression that defines the formatting mask to be used; see below for more details.

Usage:

The USING operator applies a formatting string to the left operand.

The format operand can be any valid string expression using formatting characters as described later in this section.

Note that the USING operator has a low order of precedence: if you use operators with a higher precedence, the resulting string might not be what you are expecting.
For example, the || concatenation operator is evaluated before USING. As a result:
   LET x = a || b USING "format"
will first concatenate a and b, then apply the USING format.
To solve this issue, use braces around the USING expression:
   LET x = a || (b USING "format")

Formatting symbols for numbers:

For numeric types such as INTEGER, FLOAT, DECIMAL, and especially MONEY, format-string consists of a set of placeholders that represent digits, currency symbols, thousands and decimal separators. For example, "###.##@" defines three places to the left of the decimal point and exactly two to the right, plus a currency symbol at the end of the string. The USING operator is required to display the thousands separator defined in DBFORMAT.

When used with numeric values, the format-string must use normalized placeholders described in the table below. Some of these wildcard characters will be replaced by digits, blanks or by the elements defined in the DBMONEY or DBFORMAT environment variables. Note that any other character will be interpreted as a literal, and can be used at any place in the format string. If the numeric value is too large to fit in the number of characters defined by the format, the result string is filled with a set of star characters (********) indicating an overflow.

Character

Description
* The star placeholder fills with asterisks any position that would otherwise be blank.
& The ampersand placeholder is used to define the position of a digit, and is replaced by a zero if that position would otherwise be blank.
# The sharp placeholder is used to define the position of a digit, it is used to specify a maximum width for the resulting string. This wildcard character does not change any blank positions in the display: The character is replaced by a blank if no digit is to be displayed at that position.
< Consecutive less than characters cause left alignment and define digit positions.
- Displays a minus sign or a blank at that position. USING displays a minus sign when the expression is lower than zero, and otherwise a blank character. When you group several minus signs in the format string, a single minus sign floats immediately to the left of the displayed number.
+ Displays a plus or minus sign at that position. USING displays a plus sign when the expression is greater than or equal to zero, and a minus sign the the value is less than zero. When you group several plus signs in the format string, a single plus sign floats immediately to the left of the displayed number.
( Displayed as left parenthesis for negative numbers. It is used to display accounting parentheses instead of a minus sign for negative numbers. Consecutive left parentheses display a single left parenthesis to the left of the number being printed.
) Displayed as right parenthesis for negative numbers. This wildcard character is used in conjunction with a open brace to display accounting parentheses for negative numbers.
, The comma placeholder is used to define the position for the thousand separator defined in DBFORMAT. The thousand separator will only be displayed if there is a number on the left of it.
. The period placeholder is used to define the position for the decimal separator defined in DBMONEY or DBFORMAT. You can only have one decimal separator in a number format string.
$ The dollar sign is the placeholder for the front currency symbol defined in DBMONEY or DBFORMAT. When you group several consecutive dollar signs, a single front currency symbol floats immediately to the left of the number being printed. The front currency symbol can be defined in DBFORMAT with more than one character.
@ The at sign is the placeholder for the back currency symbol defined in DBMONEY or DBFORMAT. Put several consecutive @ signs at the end of the format string to display a currency symbol defined in DBFORMAT with more than one character.

Numeric formatting examples:

Format String

Numeric value DBFORMAT Result string
[######.##] 0 :.:,: [      ,  ]
[######.##] -1234.56 :.:,: [  1234,56]
[######.##] -1234567.89 :.:,: [*********]
[######.##] +1234.56 :.:,: [  1234,56]
[#####&.&&] 0 :.:,: [     0,00]
[******.**] 0 :.:,: [******,00]
[******.**] -12.34 :.:,: [****12,34]
[******.**] +12.34 :.:,: [****12,34]
[<<<<<<.<<] +12.34 :.:,: [12,34]
[<<<<<<.<<] -12.34 :.:,: [12,34]
[---,--&.&&] -1234.56 :.:,: [ -1.234.56]
[+++,++&.&&] -1234.56 :.:,: [ -1.234.56]
[+++,++&.&&] +1234.56 :.:,: [ +1.234.56]
[$---,--&.&&] -1234.56 E:.:,: [E -1.234,56]
[$---,--&.&&] +1234.56 E:.:,: [E  1.234,56]
[$$$---,--&.&&] +1234.56 E:.:,: [E    1.234,56]
[$$$---,--&.&&] +1234.56 USD:.:,: [USD  1.234,56]
[---,--&.&&@] -1234.56 :.:,:E [ -1,234.56E]
[---,--&.&&@] +1234.56 :.:,:E [  1,234.56E]
[---,--&.&&@@@] +1234.56 :.:,:EUR [  1,234.56EUR]
[($---,--&.&&)] -1234.56 E:.:,: [(E -1,234.56)]
[($###,##&.&&)] -1234.56 E:.:,: [(E  1,234.56)]
[((((,(($.&&)] -1234.56 E:.:,: [ (E1,234.56)]
[((((,(($.&&)] +1234.56 E:.:,: [  E1,234.56 ]
[((((,(($.&&)] -12.34 E:.:,: [    (E12.34)]
[((((,(($.&&)] +12.34 E:.:,: [     E12.34 ]
[((((,(($.&&)] 0 E:.:,: [       E.00 ]
Formatting symbols for dates:

The next table shows the formatting symbols for DATE expressions (does apply to DATETIME values). Any other character is interpreted as a literal and will appear as is in the resulting string:

Character

Description
dd Day of the month as a 2-digit integer.
ddd Three-letter English-language abbreviation of the day of the week, for example, Mon, Tue.
mm Month as a 2-digit integer.
mmm Three-letter English-language abbreviation of the month, for example, Jan, Feb.
yy Year, as a 2-digits integer representing the 2 trailing digits. 
yyy Year as a 3-digit number (Ming Guo format only)
yyyy Year as a 4-digit number.
c1 Ming Guo format modifier.

Date formatting examples:

Format String

Date value Result string
dd/mm/yyyy 2011-10-24 24/10/2011
[dd/mm/yy] 2011-10-24 [24/10/11]
[ddd-mmm-yyyy] 0141-10-24 [Tue-Oct-0141]
(ddd.) mmm. dd, yyyy 1999-09-23 (Thu.) Sep. 23, 1999

Example:

01 MAIN
02   DEFINE d DECIMAL(12,2)
03   LET d = -12345678.91
04   DISPLAY d USING "$-##,###,##&.&&"
05   DISPLAY TODAY USING "yyyy-mm-dd"
06 END MAIN

CLIPPED

Purpose:

The CLIPPED operator removes trailing blanks of a string expression.

Syntax:

expr CLIPPED

Notes:

  1. expr is a language expression.

Example:

01 MAIN
02   DISPLAY "Some text   " CLIPPED
03 END MAIN

COLUMN

Purpose:

The COLUMN operator generates blanks.

Syntax:

COLUMN pos

Notes:

  1. pos is the column position (starts at 1).

Usage:

The COLUMN operator is typically used in REPORT routines to align data in PRINT statements and move the character position forward within the current line. This operator makes sense when used in an expression with the append operator: Spaces will be generated according to the number of characters that have been used in the expression, before the COLUMN operator.

The COLUMN operator can be used outside report routines, in order to align data to be displayed with a proportional font, typically in a TUI context. For example, the next lines will always display the content of the lastname variable starting from column 30 of the terminal, no matters the number of characters contained in the firstname variable (note that the example defines VARCHAR variables, since CHAR variables are blank-padded, we would need to use the CLIPPED operator):

01  DEFINE firstname, lastname VARCHAR(50)
02  DISPLAY firstname, COLUIMN(30), lasttname

The pos operand must be a non-negative integer that specifies a character position offset (from the left margin) no greater than the line width (that is, no greater than the difference (right margin - left margin). This designation moves the character position to a left-offset, where 1 is the first position after the left margin. If current position is greater than the operand, the COLUMN specification is ignored.

Example:

01  PAGE HEADER
02    PRINT "Number", COLUMN 12,"Name", COLUMN 35,"Location"
03  ON EVERY ROW
04    PRINT customer_num, COLUMN 12,fname, COLUMN 35,city

ORD

Purpose:

ORD() converts a character expression and returns the integer value of the first byte of that argument.

Syntax:

ORD( source STRING )

Notes:

  1. source is a string expression.

Usage:

Only the first byte of the argument is evaluated. This operator is case-sensitive. It returns NULL if the argument passed is not valid.

For a default (U.S. English) locale, ORD() is the logical inverse of the ASCII() operator.

See also: FGL_KEYVAL(), ASCII().


SPACES

Purpose:

SPACES returns a character string with blanks.

Syntax:

int-expr SPACES

Notes:

  1. int-expr is an integer expression.
  2. SPACE (without S) is an alias for this operator.

Example:

01 MAIN
02   DISPLAY 20 SPACES || "xxx"
03 END MAIN

LSTR

Purpose:

LSTR() returns a Localized String corresponding to the identifier passed as parameter.

Syntax:

LSTR(str-expr)

Notes:

  1. str-expr is a string expression.

Example:

01 MAIN
02   DISPLAY LSTR ("str"||123)  -- loads string 'str123'
03 END MAIN

SFMT

Purpose:

SFMT() returns a string after replacing the parameters passed.

Syntax:

SFMT( str-expr , param [ , param [...] ] )

Notes:

  1. str-expr is a string expression.
  2. param is any valid expression used to replace parameter placeholders (%n).
  3. At least one parameter is required.

Usage:

The SFMT() operator can be used with parameters that will be automatically set in the string at the position defined by parameter placeholders. The parameters used with the SFMT() operator can be any valid expressions. Numeric and date/time expressions are evaluated to strings according to the current format settings (DBDATE, DBMONEY).

A placeholder a is special marker in the string, that is defined by the percent character followed by the parameter number. For example, %4 represents the parameter #4. You are allowed to use the same parameter placeholder several times in the string. If you want to use the percent sign in the string, you must escape it with %%.

Predefined  placeholders can be used to insert information about last runtime system error that occurred. Note that these are only available in the context of a runtime error trapped with a WHENEVER ERROR GOTO / CALL handler:

Predefined parameter

Description
%(ERRORFILE) Name of the module where last runtime error occurred.
%(ERRORLINE) Line number in the module where last runtime error occurred.
%(ERRNO) Last operating system error number.
%(STRERROR) Last operating system error text.

Example:

01 MAIN
02   DEFINE n INTEGER
03   LET n = 234
04   DISPLAY SFMT("Order #%1 has been %2.",n,"deleted")
05 END MAIN

ADDITION

Purpose:

The + operator adds a number to another.

Syntax:

num-expr + num-expr

Notes:

  1. num-expr is a numeric expression.

Example:

01 MAIN
02  DISPLAY 100 + 200
03 END MAIN

SUBTRACTION

Purpose:

The - operator subtracts a number from another.

Syntax:

num-expr - num-expr

Notes:

  1. num-expr is a numeric expression.

Example:

01 MAIN
02  DISPLAY 100 - 200
03 END MAIN

MULTIPLICATION

Purpose:

The * operator multiplies a number with another.

Syntax:

num-expr * num-expr

Notes:

  1. num-expr is a numeric expression.

Example:

01 MAIN
02  DISPLAY 100 * 200
03 END MAIN

DIVISION

Purpose:

The / operator divides a number by another.

Syntax:

num-expr / num-expr

Notes:

  1. num-expr is a numeric expression.

Example:

01 MAIN
02  DISPLAY 100 / 200
03 END MAIN

EXPONENTIATION

Purpose:

The ** operator returns a value calculated by raising the left-hand operand to a power corresponding to the integer part of the right-hand operand.

Syntax:

num-expr ** int-expr

Notes:

  1. num-expr is a numeric expression.

Usage:

If the right operand is a number with a decimal part, it is rounded to a whole integer before computing the exponentiation.

Example:

01 MAIN
02  DISPLAY 2 ** 8
03  DISPLAY 10 ** 4
04 END MAIN

MODULUS

Purpose:

The MOD operator returns the remainder, as an integer, from the division of the integer part of two numbers. 

Syntax:

int-expr MOD int-expr

Notes:

  1. int-expr is an integer expression.

Usage:

If the right operand is a number with a decimal part, it is rounded to a whole integer before computing the modulus.

Example:

01 MAIN
02   DISPLAY 256 MOD 16
03   DISPLAY 26 MOD 2
04   DISPLAY 27 MOD 2
05 END MAIN

CURRENT

Purpose:

CURRENT returns the current date and time according to the qualifier.

Syntax:

CURRENT qual1 TO qual2[(scale)]

Notes:

  1. qual1, qual2 and scale define the date time qualifier; see the DATETIME data type for more details.

Example:

01 MAIN
02   DISPLAY CURRENT YEAR TO FRACTION(4)
03   DISPLAY CURRENT HOUR TO SECOND
04 END MAIN

EXTEND

Purpose:

EXTEND() adjusts a date time value according to the qualifier.

Syntax:

EXTEND ( dt-expr, qual1 TO qual2[(scale)] )

Notes:

  1. dt-expr is a date / time expression.
  2. qual1, qual2 and scale define the date time qualifier, see the DATETIME data type for more details.

Usage:

The EXTEND() operator is used to convert a date time expression to a DATETIME value with a different precision.

The default qualifier is YEAR TO DAY.

The expressions passed as first parameter must be a valid datetime value. If it is a character string, it must consist of valid and unambiguous time-unit values and separators, but with these restrictions:

Example:

01 MAIN
02   DISPLAY EXTEND ( TODAY, YEAR TO FRACTION(4) )
03 END MAIN

DATE

Purpose:

DATE() converts a character expression, an integer or a datetime to a date value.

Syntax:

DATE [(expr)]

Notes:

  1. expr is the expression to be converted to a date.

Usage:

DATE() converts a character string, an integer or a datetime expression to a DATE value.

When dt-expr is a character string expression, it must properly formatted according to datetime format settings like DBDATE. If dtexpr is an integer expression, it is used as the number of days since December 31, 1899. If you supply no operand, it returns a character representation of the current date in the format "weekday month day year".

Example:

01 MAIN
02   DISPLAY DATE ( 34000 )
03   DISPLAY DATE ( "12/04/1978" )
04   DISPLAY DATE ( CURRENT )
05 END MAIN

TIME

Purpose:

TIME() converts the time-of-day portion of its datetime operand to a character string.

Syntax:

TIME [(dt-expr)]

Notes:

  1. dt-expr is a datetime expression.

Usage:

This operator converts a date time expression to a character string representing the time-of-day part of its operand.

The format of the returned string is always "hh:mm:ss".

If you supply no operand, it returns a character representation of the current time. Note that you can use the CURRENT operator to get a datetime result of the current system time.

Example:

01 MAIN
02   DISPLAY TIME ( CURRENT )
03 END MAIN

TODAY

Purpose:

TODAY returns the current calendar date.

Syntax:

TODAY

Usage:

Reads current system clock and returns a DATE value that represents the current calendar date.

See also the CURRENT operator that returns current date and time.

Example:

01 MAIN
02   DISPLAY TODAY
03 END MAIN

YEAR

Purpose:

YEAR() extracts the year of a date time expression.

Syntax:

YEAR ( dt-expr )

Notes:

  1. dt-expr is a date / time expression.

Usage:

Returns an integer corresponding to the year portion of its operand.

Example:

01 MAIN
02   DISPLAY YEAR ( TODAY )
03   DISPLAY YEAR ( CURRENT )
04 END MAIN

MONTH

Purpose:

MONTH() extracts the month of a date time expression.

Syntax:

MONTH ( dt-expr )

Notes:

  1. dt-expr is a date / time expression.

Usage:

Returns a positive whole number between 1 and 12 corresponding to the month of its operand.

Example:

01 MAIN
02   DISPLAY MONTH ( TODAY )
03   DISPLAY MONTH ( CURRENT )
04 END MAIN

DAY

Purpose:

DAY() extracts the day of the month of a date time expression.

Syntax:

DAY ( dt-expr )

Notes:

  1. dt-expr is a date / time expression.

Usage:

Returns a positive whole number between 1 and 31 corresponding to the day of the month of its operand.

Example:

01 MAIN
02   DISPLAY DAY ( TODAY )
03   DISPLAY DAY ( CURRENT )
04 END MAIN

WEEKDAY

Purpose:

WEEKDAY() extracts the day of the week of a date time expression.

Syntax:

WEEKDAY ( dt-expr )

Notes:

  1. dt-expr is a date / time expression.

Usage:

Returns a positive whole number between 0 and 6 corresponding to the day of the week implied by its operand.

The integer 0 (Zero) represents Sunday.

Example:

01 MAIN
02   DISPLAY WEEKDAY ( TODAY )
03   DISPLAY WEEKDAY ( CURRENT )
04 END MAIN

MDY

Purpose:

Create a date from month, day and year.

Syntax:

MDY ( int-expr1, int-expr2, int-expr3 )

Notes:

  1. int-expr1 is an integer representing the month (from 1 to 12).
  2. int-expr2 is an integer representing the day (from 1 to 28, 29, 30 or 31 depending on the month).
  3. int-expr3 is an integer representing the year (four digits).

Usage:

The MDY() operator builds a date value with 3 integers representing the month, day and year. The result is a DATE value.

Note that this function is sensitive to the C1 modifier of DBDATE.

Example:

01 MAIN
02   DISPLAY MDY ( 12, 3+2, 1998 )
03 END MAIN

UNITS

Purpose:

Converts an integer to an interval.

Syntax:

int-expr UNITS qual[(scale)]

Notes:

  1. int-expr is an integer expression.
  2. qual is one of the DATETIME qualifiers.

Usage:

The UNITS operator converts an integer expression to an INTERVAL value expressed in a single unit of time that you specify after the UNITS keyword.

The unit can specified with qual be one of:

If the left-hand operand evaluates to a decimal number, any fractional part is discarded before the UNITS operator is applied.

Note that UNITS has a higher precedence than any arithmetic or Boolean operator. Therefore any left-hand arithmetic expression that uses a UNITS operator must be enclosed in parentheses. For example, 10 + 20 UNITS MINUTES will be evaluated as 10 + (20 UNITS MINUTES) and give a conversion error. This must be written (10 + 20) UNITS MINUTES to get the expected result.

Arithmetic operations with UNITS can return an invalid date and raise the runtime error -1267. For example, DATETIME(2011-01-31) YEAR TO DAY + (1 UNITS MONTH) does not give a valid date.

Example:

01 MAIN
02   DEFINE d DATE
03   LET d = TODAY + 200
04   DISPLAY (d - TODAY) UNITS DAY
05 END MAIN

GET_FLDBUF

Purpose:

GET_FLDBUF returns as character strings the current values of the specified fields.

Syntax:

GET_FLDBUF ( [group.]field [,...] )

Notes:

  1. group can be a table name, a screen record, a screen array or 'formonly'.
  2. field is the name of the screen field.

Usage:

The GET_FLDBUF operator is typically used to get the value of a screen field before the input buffer is copied into the associated variable.

If multiple fields are specified between parentheses, you must use the RETURNING clause.

When used in a INPUT ARRAY instruction, the runtime system assumes that you are referring to the current row.

The values returned by this operator are context dependent; it must be used carefully. If possible, use the variable associated to the input field instead.

Example:

01 ...
02   LET v = GET_FLDBUF( customer.custname )
03   CALL GET_FLDBUF( customer.* ) RETURNING rec_customer.*
04 ...

INFIELD

Purpose:

INFIELD returns TRUE if its operand is the identifier of the current screen field.

Syntax:

INFIELD ( [group.]field )

Notes:

  1. group can be a table name, a screen record, a screen array or 'FORMONLY'.
  2. field is the name of the field in the form.

Usage:

INFIELD is typically used to check for the current field in a CONSTRUCT, INPUT or INPUT ARRAY instruction.

When used in an INPUT ARRAY instruction, the runtime system assumes that you are referring to the current row.

Example:

01 ...
02 INPUT ...
03   IF INFIELD( customer.custname ) THEN
04      MESSAGE "The current field is customer's name."
05 ...

FIELD_TOUCHED

Purpose:

FIELD_TOUCHED returns TRUE if the value of a screen field has changed since the beginning of the interactive instruction.

Syntax:

FIELD_TOUCHED ( { [group.]field | group.* | * } [,...] )

Notes:

  1. group can be a table name, a screen record, a screen array or 'FORMONLY'.
  2. field is the name of the field in the form.

Usage:

This operator is typically used to check if the value of a field (or multiple fields) was modified during the dialog execution.

The operator accept a list of explicit field names, the [group.]* notation in order to check multiple fields in a unique function call. When passing a simple asterisk (*) to the operator, the runtime system will check all fields used by the current dialog.

Note that when used in an INPUT ARRAY instruction, the runtime system assumes that you are referring to the current row.

For more details about the FIELD_TOUCHED operator usage and the understand the "touched flag" concept, see the Touched Flag section of the DIALOG instruction.

The FIELD_TOUCHED operator can only be used inside an INPUT, INPUT ARRAY and CONSTRUCT interaction block.

Do not confuse with FGL_BUFFERTOUCHED; in that function, the flag is reset when entering a new field.

Example:

01 ...
02 AFTER FIELD custname
03   IF FIELD_TOUCHED( customer.custname ) THEN
04      MESSAGE "Customer name was changed."
05   END IF
06 ...
07 AFTER INPUT
08   IF FIELD_TOUCHED( customer.* ) THEN
09      MESSAGE "Customer record was changed."
10 ...