ViewDBFWin Expression Language Syntax

Contents
Introduction and Limitations Miscellaneous Functions
String Functions String Operators
Numeric Functions Numeric Operators
Date Functions Date Operators
Relational Operators Logical Operators
Evaluation Order MJ Library Functions

Go Back to 'Using ViewDBFWin'

Introduction and Limitations

The expression engine is used in specifying index keys, filter strings, pivot table parameters, statistical analysis definitions, report templates and set expressions, amongst many other things. Expressions result in values, strings or dates that arise from the evaluation of a statement on the current record. Field names in the expression are substituted for the values in the fields from the current record in the database. Using a combination of operators and function calls, a result is built up that represents the part of the database record you want to express. The results from successive evaluations of the expression on records in the database are commonly used to reorder the database, to filter the visible records to a more relevant subset, and to fill the contents of newly-added fields. You can try out any expressions using the Evaluate Expression option on the Record menu. There is a pre-defined set of functions that can be used in expressions. ViewDBFWin currently uses the Advantage Database Server engine. The limitations imposed by this engine are :-

  • No Memo fields can be used in an expression, unless you are using them as arguments to MJ Library Functions, or when used as a field on its own.
  • The maximum length of any expression should be limited to 250 characters. Sometimes longer ones work, and in other situations, they don't.
  • Dates can range between 1/1/0001 and 31/12/65535.
  • Numbers can be between 1.7*10^-308 and 1.7*10^308 and have 15 significant figures of accuracy.
  • Compound expressions (combining data of different types into, say, an index key) are formed by converting date and number fields to strings, and using the string concatenation operator + between elements. This can produce some fairly verbose expressions.
  • To produce index orders in descending rather than ascending order, requires the use of the function DESCEND. This makes entering a search string very tricky, as it too must be like the output of the DESCEND function, which is not always legible. Workarounds make verbose expressions.

    Character, number, logical, and date fields can be used in an expression by just quoting the relevant fieldname. White space in between operators is optional. Constants in expressions can be specified as follows:-
  • Logical - .T. .F. true false
  • Numeric - 56.7 -9.08 27 0 8*10^99
  • String - 'hello' "hello" [hello]
  • Date - CTOD("14/5/1677") CTOD('19/5/1806')

    Expressions can become very complex, especially when using nested IF functions. If there is a syntax error in an expression, the parser does not show you exactly where the problem was, so it can get quite difficult to debug complex expressions. In these situations, it is best to break the expression up, and test the segments using the Evaluate Expression option on the Record menu.
    Back to the Top

    Operators and Data Types

    String Operators

    String1 + String2
    Concatenates two strings. Trailing spaces in the strings are maintained.

    String1 - String2
    Joins two strings and removes trailing spaces from the string to the left of the operator and places them at the end of the string to the right of the operator.

    String1 $ String2
    String containment operator. A case-sensitive search is performed on the string to the right of the operator for the string to the left of the operator and returns True if found. Examples:-
    "A" $ "BACK" // Result: TRUE
    "a" $ "BACK" // Result: FALSE

    Numeric Operators

    Number1 + Number2
    Addition operator. The numeric value to the left of the operator is added to the numeric value to the right of the operator and the result is returned as a numeric value.

    Number1 - Number2
    Subtraction operator. The numeric value to the right of the operator is subtracted from the numeric value to the left of the operator and the result is returned as a numeric value.

    Number1 * Number2
    Multiplication operator. The numeric value to the left of the operator is multiplied to the numeric value to the right of the operator and the result is returned as a numeric value.

    Number1 / Number2
    Division operator. The numeric value to the left of the operator is divided by the numeric value to the right of the operator and the result is returned as a numeric value.

    Number1 ^ Number2
    Exponentiation operator. The numeric value to the left of the operator is raised to the power of the numeric value to the right of the operator and the result is returned as a numeric value.

    Number1 % Number2
    Modulus operator. Returns a numeric value representing the remainder of the operand on the left divided by the operand on the right.

    Date Operators

    Date1 + Number2
    Addition operator. Number2 is added as days to the date Date1 and the result is returned as a date value.

    Date1 - Entity2
    Subtraction operator. If both operands are date data type, the date operand on the right of the operator is subtracted from the date operator on the left of the operator and the result is returned as a numeric value representing the number of days between the two dates. If the left operand is date data type and the right operand numeric data type, the numeric operand is subtracted as days from date operand and a date value is returned. If the order of operands is reversed, an error occurs.

    Relational Operators

    Entity1 = Entity2
    Equal operator. Compares two values of the same data type and returns True if the operand on the left is equal to the operand on the right according to the following rules:-
    Character : The comparison is based on the underlying ANSI or OEM code (depending upon which collation is being used).
  • If Entity2 is an empty string, returns True.
  • If the length of Entity2 is greater than the length of Entity1, returns False.
  • Compare all characters in Entity2 with Entity1. If all characters in Entity2 equal Entity1, returns True; otherwise, returns False.
    Date : Dates are compared according to the underlying date value.
    Logical : True (.T.) is equal to true (.T.) and false (.F.) equal to false (.F.).
    Numeric : Compared based on magnitude.

    Entity1 == Entity2
    Exactly equal operator. Compares two values of the same data type and returns True if the operand on the left is exactly equal to the operand on the right.

    Entity1 != Entity2
    Not equal operator. Compares two values of the same data type and returns True if the operand on the left is not equal to the operand on the right according to the following rules:
    Character : The comparison is based on the underlying ANSI or OEM code (depending upon which collation is being used) and is the inverse of the equal operator (=).
  • If Entity2 is an empty string, returns False.
  • If the length of Entity2 is greater than the length of Entity1, returns True.
  • Compare all characters in Entity2 with Entity1. If any characters in Entity2 do not equal Entity1, returns True; otherwise, returns False.
    Other types : The comparison is the opposite of the = equals operator.

    Entity1 < Entity2
    Less than operator. Compares two values of the same data type and returns True if the operand on the left is less than the operand on the right.
    Character : The comparison is based on the underlying ANSI or OEM code (depending upon which collation is being used). If the lengths of the strings are equal, a simple comparison is performed. If the lengths of the strings are not equal, the first X number of characters in the string are compared, where X is the length of the shorter string. If those first X characters are the same:
  • If the string on the left is shorter, True is returned.
  • If the string on the right is shorter, False is returned.
    Date : Dates are compared according to the underlying date value.
    Logical : False (.F.) is less than true (.T.).
    Numeric : Compared based on magnitude.

    Similarly, there are the following operators :-
    Entity1 <= Entity2
    Entity1 > Entity2
    Entity1 >= Entity2

    Logical Operators

    AND or .AND.
    Logically ANDs two operands. If both expressions are True, True is returned. If either expression is False, False is returned.

    OR or .OR.
    Logically ORs two operands. If either expression is True, True is returned. If both expressions are False, False is returned.

    NOT or .NOT. or !
    Unary logical operator that returns the logical inverse of the operand.

    Evaluation Order

    When more than one type of operator appears in an expression, the order of evaluation is as follows:-

    1. string and join operators
    2. numeric and date operators
    3. relational operators
    4. logical operators
    Expressions containing more than one operator are evaluated from left to right. Parentheses are used to change the evaluation order. If parentheses are nested, the innermost set is evaluated first.

    Numeric operators are evaluated according to generally accepted arithmetic principles:-

    1. operators contained in parentheses
    2. exponentiation
    3. multiplication, division, and modulus
    4. addition and subtraction
    Order of evaluation may by altered with parentheses:-

    3 + 4 * 5 + 6 = 29
    (3+4) * 5 + 6 = 41
    (3+4) * (5+6) = 77

    Logical operators are evaluated as NOT first, AND second, and OR last. Logical evaluation order may also be altered with parentheses. To avoid confusion in multiple conditional expressions it is always best to use parentheses to clarify intent.
    Back to the Top

    Function Reference

    Numeric Functions

    ABS(number)
    Returns the absolute value of number. If number is negative then -number is returned. Otherwise number is returned.

    MAX(number1,number2)
    Returns the greater of number1 and number2. Also works on date arguments.

    MIN(number1,number2)
    Returns the lesser of number1 and number2. Also works on date arguments.

    ROUND(number,decimals)
    Returns number rounded to decimals decimal places. Specifying a zero or negative value for decimals allows rounding of whole numbers. A negative decimals indicates the number of digits to the left of the decimal point to round. Digits between five and nine (inclusive) are rounded up. Digits below five are rounded down.

    STR(number,[length],[decimals])
    STRZERO(number,[length],[decimals])
    Converts a numeric expression to a character string. number is the numeric expression to be converted to a character string. length is the length of the character string to return, including decimal digits, decimal point, and sign. The string is left justified with spaces when using STR(), and with zeroes when using STRZERO(). decimals is the number of decimal places to return. It is commonly used to concatenate numeric values to character strings. STR() has applications displaying numbers, creating codes such as part numbers from numeric values, and creating index keys that combine numeric and character data. STR() is like TRANSFORM(), which formats numeric values as character strings using a mask instead of length and decimal specifications. The inverse of STR() is VAL(), which converts character numbers to numerics. If the optional length and decimal arguments are not specified, STR() returns the character string according to the following rules:-

    ExpressionReturn Value Length
    Field VariableField length plus decimals
    Expressions/constantsMinimum of 10 digits plus decimals
    VAL()Minimum of 3 digits
    MONTH()/DAY()3 digits
    YEAR()5 digits
    RECNO()7 digits
    Note:-
  • If length is less than the number of whole number digits in number, STR() returns asterisks instead of the number.
  • If length is less than the number of decimal digits required for the decimal portion of the returned string, the number is rounded to the available number of decimal places.
  • If length is specified but decimals is omitted (no decimal places), the return value is rounded to an integer.

    String Functions

    CHR(number)
    Returns as a single character string, the character that corresponds to the ASCII value specified by number. Does not give expected result under ADT database format. Use the MJCHR function instead of this one for reliable results.

    I2BIN(number)
    Converts an integer numeric value to a character string formatted as a 16-bit binary integer - least significant byte first.

    L2BIN(number)
    Converts a long integer numeric value to a character string formatted as a 32-bit binary integer - least significant byte first.

    VAL(string)
    This function converts a character string containing numeric digits to a numeric value. When VAL() is executed, it evaluates until a second decimal point, the first non-numeric character, or the end of the expression is encountered. Leading spaces are ignored. As with all other functions that round, digits between zero and four are rounded down, and digits between five and nine are rounded up.

    AT(search,target)
    RAT(search,target)
    AT() is a character function used to determine the position of the first occurrence of a character substring within another string. If you only need to verify whether a substring exists within another string, use the $ operator. To find the last instance of a substring within a string, use RAT(). They both return the position of the first instance of search within target as an integer numeric value. If search is not found, they return zero.

    SPACE(number)
    Returns a string of number spaces.

    LTRIM(string)
    RTRIM(string)
    ALLTRIM(string)
    These functions remove leading and/or trailing spaces from the string argument, and returns the resultant string. LTRIM removes from the left (leading spaces), and RTRIM removes from the right (trailing spaces) of the string. ALLTRIM removes both leading and trailing space characters. To remove carriage returns, line feeds, and tabs as well, use the MJTRIM function.

    PADL(string or date or number,length,[fillchar])
    PADR(string or date or number,length,[fillchar])
    PADC(string or date or number,length,[fillchar])
    These functions pad string on the left (PADL), right (PADR) or on both the left and right (PADC) with spaces if fillchar is not specified, and with fillchar otherwise. string can be a number instead. They always return strings with length characters in them. If string is longer than length already, it is truncated. PADC attempts to centre string in length characters. For example,

    PADR("hello",6)+"goodbye" yields "hello goodbye"
    PADC("hello",9,"-") yields "--hello--"
    PADL(7805,8,"0") yields "00007805"


    LEFT(string,length)
    Returns the lefthand length characters of string. If length is greater than the number of characters in string, then string is returned. If length is zero, an empty string is returned (""). For example, LEFT("Train Timetable",10) = "Train Time".

    RIGHT(string,length)
    Returns the righthand length characters of string. If length is greater than the number of characters in string, then string is returned. If length is zero, an empty string is returned (""). For example, RIGHT("Train Timetable",9) = "Timetable".

    SUBSTR(string,start,[length])
    Extracts the substring of string, starting at character position start, and going on for length characters if length is specified, or until the end of the string if it is not.

    LEN(string)
    Returns the number of characters in string as a number.

    LOWER(string)
    UPPER(string)
    LOWER returns the string argument with all capital letters replaced by lowercase letters. UPPER returns the string argument with all lowercase letters replaced by capital letters.

    REVERSE(string)
    Returns the string back to front. For example, REVERSE("Little Lamb") = "bmaL elttiL".

    CONTAINS(field,searchstring)
    ONLY USE THIS FUNCTION IN FILTERS AND INDEXES - NOWHERE ELSE
    Returns true or false as to whether searchstring exists in field. The search conditions used for full text searches are character strings composed of words, phrases, logical operators, and parentheses for grouping precedence. Aside from white space characters, which are considered to be delimiters in search strings, special characters include the double quote (0x22) used for delimiting phrases, the asterisk (0x2A) used for prefix, postfix, and substring matching, and parentheses (0x28 and 0x29). The reserved words include the logical operators OR, AND, NOT, NEAR.

    The precedence of the logical operators from lowest to highest is OR, AND, NOT, NEAR. You can use parentheses to change the precedence grouping. For example, the search condition 'meeting and request or changelog' finds records that have both the words "meeting" and "request" or the word "changelog". Changing the precedence with parentheses to 'meeting and (request or changelog)' causes the search condition to find records that have the word "meeting" and either of the words "request" or "changelog".

    The logical OR operator produces a "true" result when either operand evaluates to true. The logical AND operator produces a true result only when both of its operands evaluate to true. The logical NOT operator produces a true result when its single operand has a false result. The NEAR operator (proximity operator) is similar to the AND operator in that both of its operands must be found. In addition, it requires that its operands be within a certain physical distance of each other for it to return a true result. The default distance for the NEAR operator is 8 words. To use a proximity value other than the default, specify the distance as a parameter to the NEAR operator. For example ' medical near(15) doctor' will evaluate to true for records where the word "medical" is within 15 words of "doctor".

    Search words that do not have logical operators specified are assumed to have an implied AND operator between them. For example, the following two search conditions are equivalent:

    'mechanical engineer' 
    'mechanical AND engineer'
    
    And the following two are equivalent:
    'computer programmer or software developer' 
    '(computer AND programmer) OR (software AND developer)'
    
    Individual search words that are not enclosed in double quotes can be searched for as exact matches, prefix matches, postfix matches, or substring matches. This behavior is controlled through the use of the asterisk (*) character.
  • Exact match. Simply specify the word in the search condition. The word will be matched if it is found exactly as given in the text. For example, the search word "special" will match only "special" in the text (or upper case versions if it is not a case sensitive index).
  • Prefix match. Place an asterisk at the end of the word to match all words that begin with the given characters. For example, the search word "special*" will match "special", "specialty", "specialization", etc.
  • Postfix match. Place an asterisk at the beginning of the word to match all words that end with the given characters. For example, the search word "*ation" will match words "station", "specialization", "citation", etc.
  • Substring match. Place an asterisk at both the beginning and end of the word to match all words that contain the given characters. For example, the search word "*lock*" will match the words "locker", "antilock", "blocking", etc.

    Double quotes are used as phrase delimiters. In addition, special characters can be enclosed inside double quotes to ensure that they are unchanged by the search condition parser. For example, to search for a parenthesis, it is necessary to enclose it in double quotes in order to keep it from being treated as a precedence operator in the search condition itself. To search for a physical double quote, use two of them in a row. Single quotes are not treated as a special case by the FTS parser, but they are the text delimiter in SQL statements. This means that if you use single quotes inside FTS search conditions in an SQL statement, you must include two of them in a row.

    Spaces are considered to be delimiters in search conditions. If you have a special situation in which spaces are not delimiters in the text and are part of search words, then it may be necessary to enclose the search words in double quotes in order to preserve the spaces. Multi- word phrases in search conditions match identical phrases in the text being searched. For example, the search condition ' "alpine skiing" ' will match only records that have the exact words "alpine" and "skiing" in that order in the text with no other non-noise words between them.

    If you use the NEAR operator with sub-expressions, you may need to use the optional form of the operator with the parentheses after it to avoid ambiguity in the expression. For example, the condition "a near (b and c)" is not valid because the left parenthesis is interpreted as the opening of the NEAR proximity parameter. The condition would need to be written as "a near() (b and c)". The empty parentheses after the NEAR operator remove the ambiguity; because they are empty, the default proximity value is used. You can also specify a proximity value: "a near (25) (b and c)".

    The following is a more formal grammar definition for the search conditions. The square brackets indicate optional items.
    search-condition ::=   |  OR 
    and-term ::=  |  [AND] 
    not-term ::=  | NOT 
    near-term ::=  |  NEAR [] 
    near-distance ::= ( [integer] )
    value-term ::= (  ) | 
    
    simple-term ::= text | text* | *text | *text* | "phrase" 
    

    Date Functions

    CTOD(datestring)
    Converts datestring to a date. If datestring cannot be converted, an empty date is returned.

    STOTS(datetimestring)
    Converts datetimestring to a timestamp. If datetimestring cannot be converted, an empty timestamp is returned. datetimestring should be in the format YYYYMMDD hh:mm:ss.nnn (nnn is milliseconds)

    CTOTS(datetimestring)
    Converts datetimestring to a timestamp. If datetimestring cannot be converted, an empty timestamp is returned. datetimestring should be in the format DD/MM/YYYY hh:mm:ss. For example, "whenitwas<CTOTS( ’30/9/1996 10:30am’)" could be used as a filter for records whose whenitwas TIMESTAMP field is before 30th September 1996 at 10.30 in the morning.

    TSTOD(timestamp field)
    Converts a Timestamp field to a date. Empty dates return the string '00/00/0000'.

    DTOC(date)
    Converts date into a string in the format DD/MM/YYYY. If date is an empty date, DTOC returns a string of 10 spaces.

    DTOS(date)
    Converts date into a string in the format YYYYMMDD. If date is an empty date, DTOS returns a string of 8 spaces.

    STOD(datestring)
    Converts datestring to a date, where datestring is in the format YYYYMMDD.

    DATE()
    Returns the current system date as a date.

    TIME()
    Returns the current system time as an 8 character string in the 24-hour format HH:MM:SS. This function does not seem to take into account daylight savings time.

    DAY(date)
    MONTH(date)
    YEAR(date)
    These functions return a number representing the day, month or year of date respectively. YEAR() always returns a 4-digit year. If date is empty, then these functions all return zero.

    Miscellaneous Functions

    DESCEND(expression)
    Returns representation of the opposite of expression. It is mostly used for descending order indices. If expression is a number, the result is the negative of the number. If expression is a logical value, then the NOT of this value is returned. If it is a date, then a numerical representation of the opposite of this date is returned. You can make a descending index of a field DATE, by using the index expression DESCEND(DATE). If the expression is a string, the return value is formed so that collation happens in the opposite direction to normal. You can try out a few expressions using the Evaluate Expression option on the Record menu to see what return values are given for various input expressions.

    EMPTY(expression)
    Returns true if the expression is empty, and false otherwise. Empty is defined as :-
    Character Spaces, tabs, CR/LF, or an empty string ("")
    Numeric 0
    Date CTOD("") or STOD("")
    Logical False (.F.)

    DELETED()
    Returns true or false as to whether the current database record is deleted.

    RECNO()
    Returns the current database record number. This is usually the slot in the database that the record is physically stored in. It returns the same number for the same record, no matter what order the database is in.

    IF(condition,expression1,expression2)
    If condition is true, then this returns whatever expression1 evaluates to, otherwise it returns whatever expression2 evaluates to. For example,
    IF(EMPTY(ENTRYDATE),DATE(),ENTRYDATE)
    Back to the Top
    Back to DKapture Help Index


    © DK Computing