VISUALPQL homecontents start chapter top of pagebottom of pagenext page indexVariables

Variables

VisualPQL allows you to declare variables and define their characteristics; assign values to variables; create and use an
External Variable block to pass data to subroutines; define the data passed to any VisualPQL Procedures.

Variables for use within a routine are referred to as program, local or summary variables as opposed to database, table or external variables.

Local variables can be explicitly defined with specific data declaration commands. If a command assigns a value to an undeclared variable, the variable is implicitly defined. Arrays can be defined and referenced using subscripts.

The VARMAP option prints a list of program variables.

Every variable has a name and a data type. Variables may have extended definitions such as value labels and missing values.

All of the definitions that can be given to database variables in schema definition may be given to variables in routines. The extended variable definitions can be explicitly defined or copied from the dictionary schema with the GET VARS command.

Variable declarations and extended definitions typically appear at the beginning of a routine. The declaration of a variable must precede any extended variable definition commands. Variable definitions must precede any reference to the variable whether the declaration is implicit or explicit. The code that defines the variable must physically precede the lines of code that reference the variable. Variables should not be defined in subprocedures, unless the variable is only referenced in the subprocedure.


Explicit Variable Declarations

Variables are defined explicitly with commands.

Simple Variables

There are five types of simple local variables, DATE, INTEGER, REAL, STRING, TIME. The type can be followed by a length and a format for date and time. For example:

INTEGER*1 gender
REAL*8 total total1
STRING*25 name
DATE curdate ('DDIMMIYYYY')

Extended Variable Definitions

Each variable may contain extended definitions for data validation and for default labels. The extended definitions include:

VALUE LABELS which define descriptive labels for individual values of a variable.

VAR LABELS which define a descriptive label for the variable which can be used in place of the variable name.

MISSING VALUES which define specific values which are treated as missing in computations and statistical procedures.

VALID VALUES and VAR RANGES which define values or ranges of values that are valid for this variable.

SCALED VARS which define that an integer variable has a scaling factor. The scaling factor is a power of ten where negative values specify decimal places, positive values specify tens, hundreds, etc.


Variable Lists

Specify a list of variables with the TO keyword and use the same method to reference the variable. The order of local variables is determined by the order they are declared in the program. The order of database variables is determined by the order they are defined in the schema. Typically, programs declare variables whose names indicate a position within the list but this is not necessary. For example

INTEGER*1 VAR1 TO VAR10
SET VAR1 TO VAR10(2,4,6,8,10,12,14,16,18,20)

Variables can be referenced in a TO list format. A TO list specifies a beginning and ending variable. The following example declares seven variables and assigns a value to NAME, ADDRESS, CITY, STATE and COUNTRY. REGION and ZIPCODE are not affected by the SET command because they are not part of the implied list of variables.

STRING*25 REGION NAME ADDRESS
STRING*10 CITY STATE COUNTRY ZIPCODE
SET NAME TO COUNTRY ( 'Unknown' )

An individual variable can be referenced by specifying an index value after the TO list which specifies the position of the variable in the list. Specify the index value immediate following the TO list specification, enclosed in parentheses. For example:

INTEGER*1 NUMA NUMB NUMC NUMD    | declare variables
SET NUMA TO NUMD (11,12,13,14)   | assign values to variables
COMPUTE NUMX = NUMA TO NUMD(3)   | put 3rd var into NUMX

Variable list references may appear anywhere an expressions may appear. The index value may be any numeric expression, including variable names, array references and more complex expressions. For example:

COMPUTE NUMA TO NUMD(3) = 32
IF(NUMA TO NUMD(3) EQ 32) WRITE 'O.K.'
Note: The variable reference is resolved and the variable moved to a temporary string or numeric variable before further computations are done. This means that variables such as categorical, date and time variables always return their numeric value when referenced in a TO list.


Arrays

An array is a set of variables all of the same type. It has one or more dimensions which defines the number of variables in the array. There is no internal limit to the number of dimensions nor the number of variables in any dimension, though the machine must be able to refer to enough memory for the array. Arrays must be explicitly declared before their first use. The general syntax for declaring arrays is:

type [* size] ARRAY array_list (dimension [,...] ) [ (format)]

type Variable type: INTEGER, REAL, STRING, DATE or TIME

size Size of the integer, real or string variables.

ARRAY Keyword specifying that arrays are being declared

array list A list of the names of the arrays. Do not use VisualPQL function names. Do not use names of other variables referenced in the routine.

dimension The number of occurrences in a dimension. A dimension can be specified either as a single number which is the number of entries in the array with references starting at 1 or as a start and finish pair of references speparated by a colon ':' where the number of entries is the difference between these values plus 1. The number of entries must be a positive integer. e.g.
INTEGER*4 ARRAY monthtot (12)
INTEGER*4 ARRAY yeartot  (1990:2009)

Arrays may be declared and used for any of the basic data types. Following is the syntax for each data type:

INTEGER [* {1 | 2 | 4} ] ARRAY name_list (dimension [,...])
STRING  [* num_le_254  ] ARRAY name_list (dimension [,...])
REAL    [* {4 | 8 }    ] ARRAY name_list (dimension [,...])
DATE                     ARRAY name_list (dimension [,...]) ('date format')
TIME                     ARRAY name_list (dimension [,...]) ('time format')

Some commands, such as SET and PRESET, can operate on whole arrays, in which case reference the array by name plus an asterisk *. The extended variable commands refer to whole arrays. Some formats of the PQL MENU commands use whole arrays. Most other commands operate on individual array elements.

Reference array elements by the array name and the element location within the array in parentheses, commonly called the array subscript. The subscript may be a numeric expression or constant. Specify a value for each dimension: e.g.

COMPUTE MONTHTOT(12) = TOTAL
COMPUTE TOTAL = MONTHTOT(MONTH)
COMPUTE JAN01 = DAILYTOT(1,1)
COMPUTE DEC31 = DAILYTOT(12,31)

REDEFINE ARRAY

REDEFINE ARRAY array_name_exp (dim1, dim2,...)

The REDEFINE ARRAY command alters the dimensions of a locally defined array; arrays defined in EXTERNAL VARIABLE blocks cannot be redefined. The number of dimensions can be altered as well as the value of any dimension. The array can grow or shrink and existing values are mapped to the new dimensions. Any new values are set to missing.

Note that the array name is an expression, that is a string variable, expression or constant. To specify the name of the array to be redefined directly, simply enclose the name in quotation marks.

The VisualPQL compiler checks array subscript references where possible and warns if these do not match the array definition. If arrays are redefined, this checking may result in unwanted warnings. These can be suppressed with the NOARRAYMSG option. For example:

PROGRAM NOARRAYMSG
INTEGER*4 ARRAY NUM1 (50)
FOR I = 1,50
. COMPUTE NUM1 (I) = I
ROF
WRITE "Before redefine"
WRITE 'NUM1 (1) (50) Should be 1 50      ' NUM1(1)  NUM1(50)
REDEFINE ARRAY 'NUM1' (50,2)
WRITE "After redefine of NUM1 to (50,2)"
WRITE 'NUM1 (1,1)  (50,1) Should be 1 50 ' NUM1(1,1) NUM1(50,1)
WRITE 'NUM1 (1,2)  (50,2) Should be * *  ' NUM1(1,2) NUM1(50,2)
END PROGRAM

SORT

SORT array_name
     [BY key_array_varname]
     [(n)]
     [DESCENDING]

The SORT command sorts the entries in an array. By default, all entries are sorted according to their values into ascending sequence. Multiple dimensions are sequenced as a single extended dimension e.g. If an array has two dimensions then entry (1,1) is first, (1,2) is second through to (1,n) which is followed by (2,1) etc. Note that the names of arrays specified in this command are specified directly, they are not expressions.

BY key_array_varname One array can be sorted according to the values in a second array. The system matches the two arrays positionally and then sorts the original array according to the values in the named key array. If the arrays are different in size, the smaller value is used.

(n) The sort can be restricted to the first N entries.

DESCENDING The sort can be into descending sequence.


Implicit Variables

Variables are implicitly defined in VisualPQL in two ways:

Declaration by Assignment

If a value is assigned to a variable which does not exist, the variable is created. The data type of the new variable is taken from the context in which it is used. For example, assuming variable B already exists, the following implicitly defines variable A:
COMPUTE A = B

Numeric variables are declared as REAL*8. String variables are STRING*w where w is the current value of STRING LENGTH - default 20. Assigning dates and times creates numeric variables. Variables defined by assignment have no definitions other than the variable name, type and length.

The CRWARN option on the routine definition command issues a warning message during compilation whenever a variable is created by assignment.

GET VARS

The
GET VARS command implicitly declares new program variables copying the type and format, value labels and missing values from the schema definition of a database or table variable. GET VARS can copy individual variables or can use the keyword ALL which implicitly declares new program variables for all variables from a given record or table. A routine may access record variables directly in an appropriate block structure or may copy the data into an internal variable for further processing. For example:
PROCESS REC EMPLOYEE
GET VARS NAME
This creates a new implicit program variable NAME. This program variable is available outside the PROCESS REC / END PROCESS REC BLOCK. The GET VARS command can copy database or table variables into explicitly defined local variables, in which case the definition of the variable is not affected.


CONTROL VARS

CONTROL VARS varlist

Declares a list of variables or arrays that are Control variables for the TABULATE procedure.

The variables and arrays named on the command must be numeric and must have a VAR RANGES defined.

By default, variables that have VALID VALUES or VALUE LABELS are automatically control variables.

All other numeric variables are observation variables, that is variables with continuous values.

PROGRAM
INTEGER*2 var1
VAR RANGES var1 (1,30)
CONTROL VARS var1
....
PERFORM PROCS
....
TABULATE var1 ....


DATE

DATE varlist ('date format') [ / ... ]

Date variables are four byte integers. A date is held as the number of days since the start of the Gregorian calendar where October 15, 1582 is day 1. Dates can be represented as formatted strings and translated according to the date format.

When a date is assigned to another variable either the integer value or the equivalent formatted value is moved. If the assigned variable is numeric or undefined, the integer value is assigned. If the assigned variable is a string variable, the formatted string value is assigned.

The date format defines the default format. That is the format that is expected on input, is written on output and is assigned to string variables. The date format on date variable declarations deals only with the significant information on day, month and year. To output dates that contain other characters such as the day of the week, commas or slashes, either use the date functions or the formatting options on the WRITE command.

The date format may contain the letters M, D, Y and I (Upper or lower case is irrelevant.)

Caution

When comparing dates and strings remember that the date is converted to a string using its default format then compared with the string. For example (assuming the datemap for birthday is DDIMMIYYYY):
IF (BIRTHDAY lt '01 01 1980') SET AGEGROUP (2)
This is a comparison of strings does not classify dates correctly as any date string that has days of the month greater than 1 (i.e.'02 mm yyyy') is greater than the string '01 01 1980'.

If the datemap for birthday is YYYYIMMIDD then:

IF (BIRTHDAY lt '1980/01/31') SET AGEGROUP (2)
This compares strings like '1980 12 31' with '1980/01/31'. Again this gives rise to errors because the former is less than the later because the character ' '(blank) has a lower ascii value to the slash.

It is recommended that all date comparisons and processing are done with the numeric values:

IF (BIRTHDAY lt CDATE('1980/01/31','YYYYIMMIDD')) SET AGEGROUP (2)

D A D is a day character. This is numeric on both input and output. If no day characters appear in the format, input dates default to the first day of the month. One or two D's are the day of the month.
If the format has more than two D's, and no month characters, the day digits are the day of the year in Julian format (e.g. day 057 is February 26).
If the format has more than two D's, and also has month characters, extra leading D's are treated as ignore characters for input and are represented by the digit 0 (zero) for output.

M An M is a month character. On input, numbers are month numbers (1 to 12), letters are the initial letters of the month names (in English). If there is any ambiguity when letters are used, the month is the first month to which the character(s) apply. For example, 'JU' is interpreted as June, not July.
If no month characters and three or more day characters are specified, the day digits are the day of the year in Julian format (e.g. day 057 is February 26). Otherwise, if no month characters are specified, input dates default to January.
Invalid input results in missing values stored.
On output, two month characters are written as month number and more than two month characters are written as the initial letters of the month name.

Y A Y is a year character which is the year number. It is numeric on both input and output. If the format specifies more than four Y's, extra leading Y's are treated as ignore characters for input and are represented by the digit 0 (zero) for output. If fewer than four Y's are specified, the following applies to input :

With three Y's, the millennium is 1nnn for values above 583 and 2nnn for values below this:

With two Y's, if the year is greater than the year specified in the CENY parameter, the century is the century specified in the parameter otherwise the century is one greater.

With a single Y, the decade is this decade.

I An I is the ignore character. Characters in this position are ignored on input and written as blanks on output.

Other Characters Any other characters that appear in the format specification are treated as the Ignore character.

For example, the following program declares and uses date variables. The program expects a string such as 'Jan 30, 1990' as input for BIRTHDAY and a string like '01-30-90' for VISDATE. The input strings '01 30, 1990' and 'JA/30/90' would also be valid. Note that on output, the default separator characters are spaces not slashes or dashes. Use the format options on the write to output other characters.

PROGRAM
DATE  BIRTHDAY ('MMMiDDiiYYYY') /
      VISITDAT ('MMiDDiYY')
COMPUTE BIRTHDAY = 'Feb 26, 1950'
COMPUTE VISITDAT = '07/13/90'
WRITE 'Born on '        BIRTHDAY  ('WWW  DD/MMM/YYYY')
      'and visited on ' VISITDAT ('DD/MM/YYYY')
END PROGRAM

The M, D and Y strings cannot be split. The following is not allowed:

DATE BIRTHDAY ('YiMMiY')


INTEGER

INTEGER [ * { 1 | 2 | 4 } ] varlist

The INTEGER command declares the listed variables as integers. Optionally specify the size of the variables as 1, 2 or 4 byte integers. If a size is not specified, the variables are 4 byte integers.

Example:

PROGRAM
INTEGER*1 SCORE1 TO SCORE5 SEX
INTEGER*2 MONTHSAL
INTEGER*4 YEARSAL
SET SCORE1 TO SCORE5 (0)
SET SEX (1)
SET MONTHSAL (2500)
COMPUTE YEARSAL = MONTHSAL * 12
WRITE MONTHSAL ('99,999') 2X YEARSAL ('999,999')
END PROGRAM


MISSING VALUES

MISSING VALUES varlist (value [,value [,value]]) [/...]

MISSING VALUES specifies up to three values for a variable which are treated as missing. Missing values are excluded from statistical procedures and functions. A missing value is, by definition, a valid value for the variable and need not be re-specified.

The missing values can be constants or the keyword BLANK. If BLANK is not a missing value for a numeric variable, then blanks are stored as 0 (zero).

Missing values can be specified for string variables. Missing values for string, date and time variables are specified as strings. If the specified missing value matches the leftmost input characters, missing values are recorded.

Missing values can be specified for an array. Specify the array name in the command, not specific array elements.

For example, the following declares several variables and defines missing values for them. If the date 01/01/01 is assigned to TESTDATE, the value is treated as missing. If either a blank or the letters ZZ are assigned to STATE, they are considered missing. For the numeric array and numeric variables, the value 9 is treated as missing. If blanks are input with a READ command, they are treated as missing.

DATE TESTDATE ('MMiDDiYY')
STRING*2  STATE
INTEGER*1  ARRAY QUESTION (25)
INTEGER*1 MATHTEST READTEST
MISSING VALUES  STATE (BLANK ,'ZZ') /
                QUESTION MATHTEST READTEST (BLANK , 9) /
                TESTDATE ('01/01/01')


OBSERVATION VARS

OBSERVATION VARS varlist

Specifies variables and arrays which the TABULATE procedure use as Observation Variables. By default, variables that have Valid Values or Value Labels are Control Variables. OBSERVATION VARS changes these to Observation Variables.


REAL

REAL [ * { 4 | 8 } ] varlist

The REAL command declares the listed variables as double precision, real, floating point numbers. REAL*4 (single precision) and REAL*8 (double precision) are also allowed.

When assigning a value to real variables, integers can be used without a decimal point.


SCALED VARS

SCALED VARS varname (n)

SCALED declares the integer variables are scaled to power n. N is a positive or negative number representing the power of ten to which the variable is scaled.

If the variable has not been defined previously, this defines an INTEGER*4 variable. To create a different length integer, define the variable before declaring the scaling factor. The full, unscaled number, including any decimal point, is used wherever this number is referenced.


STRING

STRING [ * number] varlist

STRING declares the listed variables as string of maximum length number. The maximum length of a string variable is 4094. If a length is not specified, it defaults to the current setting of STRING LENGTH, which by default is twenty characters. If more characters than the declared string length are assigned to a variable, the string is truncated to the declared length.


TIME

TIME varlist ('time format') [ / ... ]

Time variables are four byte integers, the value of which is the number of seconds between the time and the previous midnight. Times can be represented as formatted strings and translated according to the time format.

When a time is assigned to another variable either the integer value or the equivalent formatted value is moved. If the assigned variable is numeric or undefined, the integer value is assigned. If the assigned variable is a string variable, the formatted string value is assigned.

The time format defines the default format. That is the format that is expected on input, is written on output and is assigned to string variables. The time format on time variable declarations deals only with the significant information on hours, minutes and seconds. Input times are in 24 hour time notation. To output times that contain other characters such as "AM/PM", commas or slashes, use the time functions and the formatting options on the WRITE command.

Caution

When comparing times and strings remember that the time is converted to a string using its default format then compared with the string.

eg (assuming the timemap for START is HHIMM):
IF (START gt '09:00') SET LATE (1)
is a comparison of strings and the string '09 59' is less than the string '09:00' because the character ' '(blank) has a lower ascii value to the colon.

In these cases it is best to convert the string to a number for the comparison:
IF (START gt CTIME('09:00','HHIMM')) SET LATE (1)

The time format may contain the letters H, M, S and I, representing digits of Hours, Minutes and Seconds and Ignore (Upper or lower case is irrelevant.)

H Each H in the time format represents one digit of the hour. On input, VisualPQL interprets numbers as hours in a 24 hour day. Numbers greater than 24 set the variable to undefined. If hour digits are not specified in the time format, input times default to the first hour of the day.

M Each M in the time format specifies a minute digit. Numbers greater than 60 on input set the variable to undefined. If no minute characters appear in the time format, input times default to the first minute of the hour.

S Each S in the time format represents a seconds digit. Numbers greater than 60 on input set the variable to undefined. If no second characters appear in the time format, input times default to the first second of the minute.

I Each I in the time format specification indicate characters that are ignored on input or are converted to semi-colons on output.

Other Characters Any other characters that appear in the format specification are treated as the Ignore character.

The following example declares two time variables:

TIME    CALLTIME   ('HHiMM') /
        EXACTIME   ('HHiMMiSS')

The following program declares and uses time variables:

PROGRAM
TIME STARTIME ENDTIME ('HHiMM')
COMPUTE STARTIME = SREAD('Enter Starting Time (HH:MM)')
COMPUTE ENDTIME  = SREAD('Enter Quitting Time (HH:MM)')
COMPUTE TTIME = ENDTIME - STARTIME
WRITE 'You worked ' TTIME(TIME 'HH')
      ' hours and ' TTIME(TIME 'MM') 'minutes.'
END PROGRAM

The H, M and S strings cannot be split. The following example is invalid:

TIME START ('MiHHiM')


VALID VALUES

VALID VALUES varlist ( value_list ) [ / . . . ]

Specifies the set of specific valid values a numeric variable can assume. If both VAR RANGES and VALID VALUES are defined for a variable, both specifications must be satisfied. Attempting to store a value in the variable that is not either a valid Missing Value or a Valid Value results in undefined. When a variable is updated during the running of a program, data validation takes place in the following order:

  1. Missing Values
  2. Valid Values
  3. Variable Ranges

Examples:

INTEGER * 1 VAR1 TO VAR5 SCOREA SCOREB SCOREC
VALID VALUES VAR1 TO VAR5     ( 1 , 2 ) /
             SCOREA TO SCOREC ( 1, 2, 3, 88, 99 )


VALUE LABELS

VALUE LABELS varlist (value1 ) 'label text'
                   [ (value2 ) 'label text_2' [...]]
                   [/...]
Defines descriptive labels for individual values of a variable. Each label may be up to 40 characters long. Enclose labels in quotes to include special characters. The keywords UNDEFINED and BLANK can be used as values and assign labels to undefined or blank missing values.

Specify value labels for multiple values of a single variable as one continuous command. If a number of variables have the same value labels, specify a list of variables, followed by the values and labels. If specifying value labels for an array, specify the array name not individual array elements. Specify value labels for several variables on the same command by separating the set of labels for one variable from the next set with the slash ( / ).

For example, to declare a string variable, an integer variable and a 25 element array and define value labels for each:

PROGRAM
STRING*3 STATE
INTEGER*1 REGION
INTEGER*1 ARRAY QUESTION (25)
VALUE LABELS QUESTION (1) 'Yes'
                      (2) 'No'  /
             REGION   (1) 'North'
                      (2) 'South'
                      (3) 'East'
                      (4) 'West' /
             STATE ('NSW') 'New South Wales'
                   ('QLD') 'Queensland'
                   ('VIC') 'Victoria'
SET STATE REGION ('NSW',1)
SET QUESTION *   ( 1)
COMPUTE STATEV  = VALLAB(STATE)
COMPUTE REGIONV = VALLAB(REGION)
COMPUTE QUESTV  = VALLAB(QUESTION(1))
WRITE STATEV REGIONV QUESTV
END PROGRAM


VAR LABELS

VAR LABELS {variable | array } 'var label text' [ / . . . ]

VAR LABELS specifies descriptive labels for variables. Variable labels may be up to 40 characters in length. Additional lines of text may be specified as documentation. Labels for multiple variables may be specified on a single command in which case the specification for each variable must be separated by a slash ( / ).

The variable label can be retrieved during program execution with the VARLAB function.

Several VisualPQL Procedures automatically use Variable Labels if they are defined.

Examples:

STRING*3 STATE
INTEGER*1 REGION
INTEGER*1 ARRAY QUESTION (25)
VARIABLE LABELS STATE    'State of Residence'    /
                REGION   'Region of the State' /
                QUESTION 'Survey Question'


VAR RANGES

VAR RANGES {variable | array } (min_value , max_value) [/ . . .]

Specifies the range of values that a variable can have. Input values outside the specified range are set to undefined. If specific VALID VALUES are defined for a variable, do not specify VAR RANGES. If both are specified, the value must satisfy both specifications. When a variable is updated during the running of a VisualPQL program, data validation takes place in the following order:

  1. Missing Values
  2. Valid Values
  3. Variable Ranges

Examples:

INTEGER*1 YRSEDUC YRSWORK YRSPLAY
INTEGER*4 INCOME
DATE      LASTDATE ('MMiDDiYY')
VAR RANGES  YRSEDUC TO YRSPLAY ( 0,99 ) /
            INCOME   ( 10000 , 90000) /
            LASTDATE ( '01/01/77' , '12/31/90')


Assigning Values

Values assigned to variables are specified as expressions. A variable may also be undefined or have a missing value. The eight commands that assign values explicitly to variables are:

AUTOSET which resets implicitly defined local variables to undefined. It is typically used to ensure that values from a GET VARS in a RECORD/ROW block are not carried forward accidentally when the block is not executed due to a non-occurrence of that record for this particular instance. It also resets any variable explicitly declared after the start of the routine (the first executable command). It resets the values each time the command is executed.

COMPUTE which sets a variable to a specified constant or expression value.

EVALUATE which compiles small VisualPQL expressions during execution, allowing programs to accept expressions 'on the fly'.

GET VARS which copies the definition and the value of a database or table variable to a local variable.

PRESET which sets the initial value of variables at compilation time. Pre-compiled subroutines and stored executable programs save any preset values as part of the executable image that is loaded and executed at run time.

PUT VARS which writes local data back into table or record variables.

SET which sets variables to given constant values at execution time. It resets the values each time the command is executed.

RECODE which recodes the value of a variable into itself or another variable.

The initial values of program variables are set to undefined unless PRESET is specified.


Missing Values

Until a variable has been assigned a real value, its value is undefined which is a special system assigned missing value.

Variables may be defined to have specific values that are considered missing. A variable SEX might have valid value of 1 and 2 for Male and Female, and a value 3, for Unknown, which is considered missing.

There are functions and procedures to get and use the actual value of the variable. In general, operations that result from evaluating a missing or undefined value yield an undefined value (e.g. adding a number to an undefined value yields an undefined value). Functions that calculate statistics on a set of values have special rules for dealing with undefined values.

The numeric value 0 (zero) is a normal numeric value and is different from undefined. A zero length string (a string with no characters) is also a valid value that is different from an undefined string.

Logical tests evaluate to true or false. A missing value or undefined in a logical test always evaluates to false which should be taken into account when specifying logical tests.


Expressions

Expressions evaluate to a single value. For example:

COMPUTE REGION = 'Western ' + 'Canada'
COMPUTE TOTAL = 10 + 17

Expressions have two main elements; other expressions and operators. Operators are a symbol that specifies an operation between two expressions. Parentheses () may be used to specify the precedence (order) of operations.

Simple expressions are:

Variables

Variables have names and during program execution contain a value. A reference to a variable resolves itself to the value held by the variable. In general, wherever a variable may be referenced a subscripted array reference may be used.

String Constants

String constants are expressed as characters enclosed in quotation marks (either the single or the double quotation mark ). If one type of quotation mark is used to start a string, the same type of quotation mark finishes the string. For example, in the EVALUATE command it is possible to specify a string inside another string by using both types of quotation mark:

EVALUATE X = 'NUMBR ( "20")' + ' + 22'

Numeric Constants

Numeric constants are numbers. A numeric constant may contain:

Following are valid examples of the SET command using several forms of expressing numeric constants.

SET TESTNUMB ( 22 )
SET TESTNUMB (+3.1)
SET TESTNUMB (-3.1)
SET TESTNUMB ( 4.5E-2)

Functions

Functions are named routines that perform an operation based on values passed to the function and return a single value. Functions are specified with a function name followed by a list of values enclosed in parentheses. The values passed to functions may be constants, variables, functions and expressions. There are around 300 functions which perform various operations including string manipulation, mathematical calculations, statistics setting and getting information from dialogs and getting information about a database or tabfile.

Operators

String Operators

There is one string operator, the concatenation operator, represented by the + sign. String concatenation appends one string value expression to another. Operations in string expressions are left to right. When string values are computed into a variable, if the string is longer than the declared length of the variable the result is truncated. Concatenating undefined or missing values result in an undefined value. For example:

PROGRAM
STRING*40 ADDRESS
INTEGER ZIPCODE
COMPUTE CITY    = 'Chicago'
COMPUTE STATE   = 'Illinois'
COMPUTE ZIPCODE =  60614
COMPUTE ADDRESS =  CITY + ', ' + STATE + ' ' + FORMAT(ZIPCODE)
WRITE ADDRESS
END PROGRAM

In this example, ADDRESS is computed from three types of simple value expressions; string constants in quotes, variable names and the FORMAT function which converts a number to a string.

Arithmetic Operators

There are five arithmetic operators:

Enclose signed constants that follow an arithmetic operator in parentheses. For example:

COMPUTE NUM1 = 10 + 20 + 33
COMPUTE NUM2 = 100 - NUM1
COMPUTE NUM2 = NUM1 * 5
COMPUTE NUM1 = 2 / 3
COMPUTE NUM1 = 4**3        | 4 cubed
COMPUTE NUM2 = NUM1**(1/3) | cube root
COMPUTE NUM = 13 * (-2)

In arithmetic expressions, operations of equal precedence are done from left to right. The precedence of operations is:

  1. expressions within parentheses
  2. functions
  3. exponentiation
  4. multiplication and division
  5. addition and subtraction

An arithmetic operation that involves an undefined or missing value returns an undefined value. A number divided by zero yields an undefined value.

Examples:

COMPUTE NUM = 6 + 3 / 3      | NUM is 7
COMPUTE NUM = ( 6 + 3 ) / 3  | NUM is 3
COMPUTE NUM = 16**1 / 2      | NUM is 8, 16 divided by 2
COMPUTE NUM = 16**(1/2)      | NUM is 4, square root of 16
MISSING VALUES NUM (1)
COMPUTE NUM  = 1             | NUM  is missing
COMPUTE NUM2 = NUM + 3       | NUM2 is undefined
COMPUTE NUM3 = 1 / 0         | NUM3 is undefined


Database Variables

Commands outside a case, record or row block only access local variables. Within a block, a command can access case or record variables in addition to all local variables. The GET VARS and PUT VARS commands access case, record or row variables specifically.

It is possible, even likely, that a local variable has the same name as a variable in the record. When a retrieval references one of these variables in a case or record block, VisualPQL determines which variable is used.

Assigning a value to a database variable is only allowed if this is a retrieval update. If a value is assigned to a database variable, the database is updated when the record or case block is exited.

For example, the first program updates the salary on every employee record as well as listing the records. (Without the RETRIEVAL UPDATE command, this would not compile). The second program does not update the database, it simply produces a list of new salaries:

RETRIEVAL UPDATE
PROCESS REC EMPLOYEE
. COMPUTE SALARY = SALARY* 1.1
. WRITE NAME SALARY
END PROCESS REC
END RETRIEVAL

RETRIEVAL
PROCESS REC EMPLOYEE
. GET VARS NEWSALARY = SALARY
. COMPUTE NEWSALARY = NEWSALARY * 1.1
. WRITE NAME NEWSALARY
END PROCESS REC
END RETRIEVAL


AUTOSET

AUTOSET [ varlist ( value_list )]

AUTOSET sets all implicitly declared variables and any variables not declared before the first executable command. An executable command is any command except variable declaration, variable definition and PRESET commands. AUTOSET is typically used to initialise local implicitly defined variables defined with GET VARS. AUTOSET sets variables to UNDEFINED unless a variable list and value list is specified. A list of variables may be specified with the values to which they should be set. If such a list is specified, all AUTOSET variables are set to undefined and then the listed variables are set to the values specified in the parenthesised value list. If fewer values are specified than variables, the value list is cycled through as many times as needed to assign a value to each of the variables in the list.

In the following retrieval, AUTOSET is used to make sure that values from a previous record type 3 record aren't accidentally carried over to another case if that case happens not to have a record type 3 record.

RETRIEVAL
PROCESS CASES              | for every case
AUTOSET                    | initialise variables
. PROCESS REC 1           | step thru rectype 1 recs
. GET VARS ALL            | move all vars to summary rec
.   PROCESS REC 3 REVERSE | step thru rectype 3, backwards
.   GET VARS ALL          | move all vars to summary rec
.   EXIT REC              | we only want this one, get out
.   END REC
. PERFORM PROCS           | copy summary rec to summary table
. END REC
END CASE SAS SAVE FILE FILENAME = 'SAS.SYS' / | create SAS file VARIABLES = ALL END RETRIEVAL


COMPUTE

COMPUTE varname = expression

Assigns the value determined by the expressions to a variable or array element. COMPUTE cannot be used to set a whole array. (Use SET)

The variable to which the value is assigned may be a local variable, an array element or a database variable.

The data type of the variable or array element to which the value is assigned must be compatible with the type implied by the expression. Arrays must have been previously declared before use with COMPUTE. If a variable name to the left of the equals sign has not been previously declared, an implicit local variable is declared as either a string or real number, depending on the type implied by the computation expression.


EVALUATE

EVALUATE varname = string_expression

The EVALUATE command compiles and then evaluates a VisualPQL expression during program execution. The expression that is evaluated is re-compiled and re-evaluated every time that it is traversed which is an expensive process to perform at run time. This is typically used when a user is asked to type in some condition at execution time.

If the expression is a logical expression, the command returns a 0 (zero) or a 1 (one) depending on whether the expression is true or false. If the expression is a numeric calculation, the result is returned. If the expression is a string operation, the result is a string. The left hand side variable determines the type expected from the right hand side expression. If this variable is not explicitly declared, it is implicitly declared as real.

The following retrieval allows the user to specify a condition for retrieving records.

RETRIEVAL
LOOP
. COMPUTE EXPRESS = SREAD('Enter search condition (CR to quit)')
. IF (LEN(TRIM(EXPRESS)) = 0) STOP
. PROCESS CASES
.  PROCESS REC 1
.   EVALUATE TRUE = EXPRESS
.   IF (TRUE) WRITE ID NAME TO CURRDATE
.  END REC
. END CASE
END LOOP
END RETRIEVAL

The expression to the right of the equal sign is a string expression and therefore enclosed in quotes. The syntax of the command may also require a string expression enclosed in quotes. Use a mixture of single and double quote marks. Each matching pair denotes a string. For example:

EVALUATE X = 'NUMBR ("20")' + ' + 22'

This passes a valid VisualPQL expression , NUMBR ("20") + 22, to the compiler, which then produces the result 42 in X.


GET VARS

GET VARS transfers values of database or table variables to local variables. If the referenced local variables are not explicitly declared, this command implicitly declares them with all the schema definitions of the database or table variables, including Data Type, Value Labels, Missing Values, Valid Values and Ranges. The command is only allowed inside a case, record or table block. It takes three forms:

GET VARS local_var_list = db_var_list The values of local variables are assigned the values of the database or table variables. The two lists must be of equal length and the value assignments are performed listwise.

GET VARS db_varlist There is an assumed left hand side list of local variables with the same names as the database or table variable list.

GET VARS ALL The keyword ALL specifies all record or table variables are assigned to local variables of the same name.
This is the only command which accesses table variables for input. If the name of the table variable is not a valid local variable name, the first form of the command must be used.

For example: the GET VARS command is used three times to retrieve database and table data and copy it into local variables. The first form of the command is used in the CASE and RECORD block. The second form of the command is used inside the ROW block since the row variable names are not valid VisualPQL names.

RETRIEVAL
PROCESS CASES ALL
. GET VARS ID
. PROCESS RECORD EMPLOYEE
.  GET VARS NAME
.  PROCESS ROWS OCCTAB INDEXED BY OCCINDEX VIA  (ID )
.   GET VARS  POS  START = CURRENT_POSITION  START_DATE
.   PERFORM PROCS
.  END PROCESS ROWS
. END PROCESS REC
END PROCESS CASE
REPORT   FILENAME = TEST.LIS /
         PRINT = ID NAME POS START
END RETRIEVAL


PRESET

PRESET varlist (value_list) ...

Assigns constants to variables and array elements during compilation. PRESET statements must precede the first executable command within a routine. PRESET may also be used in an EXTERNAL VARIABLE BLOCK. The values to which variables are preset are the initial values of those variables when program execution begins. The syntax is identical to the SET command. PRESET happens once at compilation; SET happens during execution whenever the SET is encountered.

Values in the value list are assigned in list order to the variables in the variable list. If the value list is shorter than the variable list, the value list is cycled until a value has been assigned to each variable. If the value list is longer than the variable list, the excess values are ignored.

Value Keywords for Undefined Values

The value list may contain value constants and the keywords MISSING, NMISSING and SMISSING. NMISSING assigns a numeric undefined value, SMISSING assigns a string undefined value and MISSING assigns the appropriate type of undefined value depending on the type of the variable being set. If MISSING is specified for an undeclared variable, it is implicitly declared as REAL.

Repeat Values

A shorthand syntax for repeating a value is the asterisk symbol. The syntax is:

PRESET varlist ( repeat_value * value [ value_list])

In the following example, the first four variables are set to 2, the next three are set to 12 and the last three are set to 7,8 and 9 respectively.

PRESET VAR1 TO VAR10 (4*2,3*12,7,8,9)

Setting Array Elements

Specific array elements may be preset. All elements in an array may be preset by specifying the array name followed by an asterisk. Values in the value list are assigned column wise by dimension. For example:

INTEGER*1 ARRAY A (3,2)    | declare two dimensional array A
PRESET A * ( 0 )           | preset all elements to 0
PRESET A * ( 1,2,3,4,5,6 ) | set each element to unique value
PRESET A(1,1) A(2,1) A(3,1) A(1,2) A(2,2) A(3,2)
        ( 1,2,3,4,5,6 )    | Equivalent to previous command


PUT VARS

PUT VARS transfers values of local variables into database or table variables. This command must be used to update the values in table variables, whereas database variables are automatically updated by assignment within a record or case block. PUT VARS takes three forms:

PUT VARS db_varlist = local_var_list The values of the database or table variables are assigned the values currently held by the local variables on the right side of the equals sign. The lists of variables must be of equal length. The value assignments are performed list wise; the first right side value is assigned to the first left hand variable, the second right to the second left, and so forth.

PUT VARS db_varlist There is an assumed right side list that is identical to the database or table variable list. The referenced database or table variables must have the same name as local variables.

Note that the PUT VARS takes local variables as the source and sets database variables to be the same as the local variables. As these have the same name, there is an opportunity for confusion if the variable values were set inside the database block. e.g.

PROCESS REC EMPLOYEE
GET VARS SALARY
COMPUTE SALARY = SALARY * 1.1
PUT VARS SALARY
END PROCESS REC
Because this is in a record processing block, the database variable SALARY would be updated by the compute, not the local variable with the same name. Then the PUT VARS would restore the original value of salary because that is the current value in the local variable. If database variables are updated inside a record block, the PUT VARS is unnecessary.

PUT VARS ALL Any record or table variables with the same names as local variables are updated.

Values of keyfields in records may not be updated. Values of keyfields of the index being used on table rows may not be updated.

For example: The program retrieves data from the database and creates a new row on a table, if one does not already exist for that employee in that position. The two forms of PUT VARS are used, one to move a local variable to a row variable of the same name, the other to set a row variable of a different name. Note that the index variables are set by the reference on the ROW IS and are not referenced by a PUT VARS.

RETRIEVAL  TUPDATE
PROCESS CASES ALL
.  GET VARS ID
.  PROCESS RECORD EMPLOYEE
.    GET VARS NAME  CURRPOS SALARY CURRDATE
.    NEW ROW IS OCCTAB INDEXED BY OCCINDEX (ID , CURRPOS)
.       PUT VARS  START_DATE = CURRDATE
.       PUT VARS  SALARY
.    END ROW IS
.  END PROCESS REC
END PROCESS CASE
END RETRIEVAL


RECODE

RECODE  [ update_var = ] recode_var
             [ (value_list =  recode_value) [...]]
The RECODE command computes a value according to the specifications and assigns the value to a named variable. The computed value may be re-assigned to the original variable or assigned to a different variable leaving the original value unchanged.

The values in the value list and the recode value are either constants or one of the value keywords documented below. (Expressions and variable names are not allowed as values.)

recode variable The variable or array element with the initial value to recode. If an update variable is not specified, this variable is updated with the recoded value.

update variable The variable or array element to receive the recoded value if the original recode variable is not updated. The update variable must be a data type compatible with the recode value.

recode value The single value to which the values in the value list are converted. This value must be of the same type as the update variable. The keyword UNDEFINED may be used to specify that values are recoded to undefined.

value list A list of original values to recode. A value list is specified for each single recode value. Any value in the list is recoded into the single recode value. If the value of the variable is not found in a value list, the value is not recoded and is assigned unaltered to the update variable. Specify a separate parenthesised recode value list for each recode value. In the following examples: In the first, if RVAR is 1, 2 or 3, UVAR is recoded to 0. If RVAR has any other value, RVAR is copied to UVAR. In the second example, UVAR is 0 if RVAR is 1, 2 or 3 and 1 (one) if RVAR is 4, 5 or 6 :
RECODE UVAR = RVAR(1,2,3 = 0)
RECODE UVAR = RVAR(1,2,3 = 0)(4,5,6 = 1)

A number of keywords may be used in the value list.

THRU Specifies an inclusive range of values. For example:
RECODE UVAR = RVAR (1 THRU 3 = 0)(4 THRU 6 = 1)
The value lists can overlap avoiding the possibility that a value (such as 3.5) falls between two value lists and is not recoded. The first match determines the recode used. Multiple ranges and multiple values can be specified in a value list. For example:
RECODE UVAR = RVAR
(1 THRU 3,7 THRU 99 = 0)(3 THRU 7 = 1)

LOWEST,LO Specifies the lowest possible value. For example:
RECODE UVAR = RVAR (LO THRU 3 = 0)(3 THRU 6 = 1)

HIGHEST,HI Specifies the highest possible value. For example:
RECODE UVAR = RVAR (LO THRU 3 = 0)(3 THRU HI = 1)

UNDEFINED Specifies an undefined value. For example:
RECODE UVAR = RVAR (UNDEFINED,LO THRU 3 = 0)(3 THRU 6 = 1)
UNDEFINED may also be used as the recode value. For example:
RECODE UVAR = RVAR (LO THRU 3 = 0)(3 THRU HI = UNDEFINED)

MISSING(0)
MISSING(1)
MISSING(2)
MISSING(3)
Specifies missing values. MISSING(0) is a synonym for UNDEFINED. MISSING(1) refers to the first missing value, MISSING(2) to the second, and MISSING(3) to the third. For example:
PROGRAM
INTEGER*1 RVAR
MISSING VALUES RVAR (7,8,9)
SET RVAR (9)
RECODE UVAR = RVAR
       (MISSING(1)=4)
       (MISSING(2)=5)
       (MISSING(3)=6)
WRITE    UVAR
END PROGRAM

BLANK Specifies that the blank missing value is recoded. For example:
RECODE UVAR = RVAR (BLANK,7 THRU HI = 0)

ELSE Specifies a recode for all values not included in any previously defined value list. If ELSE is specified, no other values may be specified in the value list. This must be the last recode specification of a set. For example:
RECODE UVAR = RVAR (1,2,3 = 1)(4,5,6 = 2)(ELSE = 0)

Mixed Data Type Recodes

A variable of one type may be recoded into a variable of another type. In the following example, a string variable is recoded into a numeric variable.

PROGRAM
INTEGER*1  NUMVAR
STRING*1   STRVAR
SET     STRVAR ('A')
RECODE  NUMVAR = STRVAR('A' = 1)('B' = 2)(ELSE = 0)
WRITE   STRVAR NUMVAR
END PROGRAM

If the recode variable in a mixed data type recode has a value not referenced in a recode value list, the update variable is set to undefined.


SET

SET varlist (value_list) ...

Assigns explicit values to variables and array elements during execution. Values in the value list are assigned in list order to the variables in the variable list. If the value list is shorter than the variable list, VisualPQL cycles through the value list until a value has been assigned to each variable. If the value list is longer than the variable list, the excess values are ignored.

Value Keywords for Undefined Values

The value list may contain value constants and the keywords BLANK MISSING NMISSING SMISSING. BLANK assigns blanks to a variable. This can be used to assign a blank missing value to a numeric variable. NMISSING assigns a numeric undefined value, SMISSING assigns a string undefined value and MISSING assigns the appropriate type of undefined value depending on the type of the variable being set. If MISSING is specified for an undeclared variable, it is implicitly declared as type REAL.

Repeat Values

The asterisk is a symbol for repeating a value. The syntax is:

SET varlist ( repeat_value * value [ value_list])

In the following example, the first four variables are set to 2, the next three are set to 12 and the last three are set to 7,8 and 9 respectively.

SET VAR1 TO VAR10 (4*2,3*12,7,8,9)

Setting Array Elements

Specific array elements may be included in the variable list. All elements in an array may be set by specifying the array name followed by the asterisk. Values in the value list are assigned column wise by dimension. For example:

PROGRAM
INTEGER*1 ARRAY A (3,2)  | declare two dimensional array A
SET A * ( 0 )            | set all elements to 0
SET A * ( 1,2,3,4,5,6 )  | set each element to unique value
WRITE A(1,1)
END PROGRAM

The second SET statement in the above example is equivalent to:

SET A(1,1) A(2,1) A(3,1) A(1,2) A(2,2) A(3,2) ( 1,2,3,4,5,6 )


EXTERNAL VARIABLE BLOCK

EXTERNAL VARIABLE BLOCK member[:V]
       [ NOSAVE ] [ REPLACE ] [PUBLIC ] [ VARMAP ]
...
variable definitions ...
...
END EXTERNAL VARIABLE BLOCK
An EXTERNAL VARIABLE BLOCK declares a set of variables and arrays that may be shared between routines. The external variable block contains variable declarations and definitions and the
PRESET command. No other commands are allowed in an external variable block. The block is ended with the END EXTERNAL VARIABLE BLOCK command.

The external variable block is compiled separately (by running it) and is stored in its compiled form in the specified member. This member is given the :V (for Variables) suffix. This set of variables is made available to routines by specifying the INCLUDE EXTERNAL VARIABLE BLOCK command within a routine.

The external variable block provides a common data area that can be used by a VisualPQL program and its subroutines as an alternative to passing values between subroutines with argument lists on the EXECUTE SUBROUTINE command. External variables that are updated in one routine are available to all other routines that include the external variable block during VisualPQL execution.

member The member name of the compiled variable definitions. It is given the :V (for Variables) suffix if not specified. The member name can contain complete procfile, family and password specifications.

NOSAVE Compiles the external variable block without saving it, simply checking the code for errors.

REPLACE Gives permission to overwrite an existing member of the same name. If such a member does not exist, the option has no effect.

PUBLIC Makes the compiled external variable block available to all users without need for passwords. These users may reference the member, but not modify or delete it.

VARMAP Lists the variables and their data types.


INCLUDE EXTERNAL VARIABLE BLOCK

INCLUDE EXTERNAL VARIABLE BLOCK member[:V]

Includes the variables as local variables in the routine. Do not declare variables from the included block in the routine that includes the block.

member Names a member with the :V suffix, which is a previously compiled and stored set of variable declarations.

Use this command anywhere that variable declaration or definition commands are legal (except within another EXTERNAL VARIABLE BLOCK). External variables that are updated in one routine are accessible in other routines that have included the block. External variables provide an alternative mechanism to passing values on the EXECUTE SUBROUTINE command.


DEFINE PROCEDURE VARIABLES

DEFINE PROCEDURE VARIABLES [ { INCLUDE | EXCLUDE } (varlist)]
       [ NOARRAYS    | ARRAYS   ]
       [ NOEXTERNALS | EXTERNALS [
       (external_block_list) ] ]
       [ NOSIMPLE    | SIMPLE  ]
Controls the variables that are copied to the Procedure Table with the
PERFORM PROCS command. If this command is not used, by default all local simple variables from the main routine are passed to the Procedure Table; arrays and external variables are not. If arrays or external variables are needed for the procedures, this command must be used. The options on the command are:

INCLUDE Specifies a list of variables included in the Procedure Table. This list may include simple program variable names, array names and external variable names. These variables must be available in the main program or retrieval.

EXCLUDE Specifies a list of variables and arrays that are excluded from the Procedure Table. All main routine program variables, external variables and arrays not mentioned in this list become part of the Procedure Table.

ARRAYS | NOARRAYS Specifies that all arrays declared in the main routine are included in the Procedure Table. NOARRAYS is the default.

EXTERNALS | NOEXTERNALS Specifies that any external variables included with the INCLUDE EXTERNAL VARIABLE BLOCK command in the main program or retrieval are included in the Procedure Table. The external variable blocks to include may be specified, in which case all variables in other, unspecified external variable blocks are excluded from the Procedure Table. NOEXTERNALS is the default.

SIMPLE | NOSIMPLE Specifies that all simple variables (not arrays, not external variables) explicitly or implicitly declared in the main program or retrieval are included in the Procedure Table. NOSIMPLE excludes all simple variables from the Procedure Table. SIMPLE is the default.

homecontents start chapter top of pagebottom of pagenext page index