DEFINE VARIABLE statement
- Last Updated: January 18, 2024
- 17 minute read
- OpenEdge
- Version 12.8
- Documentation
Defines a variable for use in one or more procedures, a variable data member of a class for use in a single class or class hierarchy, or by other classes and procedures, or a variable data element for use within a single class-based method.
The VAR statement is a shorthand notation for the
DEFINE VARIABLE statement and may be used for NO-UNDO
variables. For more information, see the VAR statement in the
ABL Reference.
Syntax
|
- NEW SHARED VARIABLE variable-name
- Defines and identifies a variable to be shared by a procedure called directly or indirectly by the current procedure. The called procedure must name the same variable in a DEFINE SHARED VARIABLE statement.
- NEW GLOBAL SHARED VARIABLE variable-name
- Defines and identifies a variable that can be used by any procedure that names that variable using the DEFINE SHARED VARIABLE statement. The value of a global shared variable remains available throughout an ABL session.
- SHARED VARIABLE variable-name
- Defines and identifies a variable that was created by another procedure that used the DEFINE NEW SHARED VARIABLE or DEFINE NEW GLOBAL SHARED VARIABLE statement.
- [PRIVATE|PACKAGE-PRIVATE|PROTECTED|PACKAGE-PROTECTED|PUBLIC] [STATIC] [SERIALIZABLE|NON-SERIALIZABLE] VARIABLE variable-name
- Defines and identifies a variable as a data member of a class, and optionally specifies an access mode (PRIVATE, PACKAGE-PRIVATE, PROTECTED, PACKAGE-PROTECTED, or PUBLIC) and scope (instance or STATIC) for that data member, as well as whether or not the variable will participate in serialization (SERIALIZABLE or NON-SERIALIZABLE).
- VARIABLE variable-name
- Defines and identifies a variable whose value you can access only within the current procedure, method of a class (including constructors, destructors, and property accessors), or as a PRIVATE data member of a class.
- AS primitive-type-name
- Specifies a built-in primitive type for the variable you are
defining. The built-in data type (primitive-type-name) can be one of the following:
CHARACTER | COM-HANDLE | DATE | DATETIME | DATETIME-TZ | DECIMAL | HANDLE | INT64 | INTEGER | LOGICAL | LONGCHAR | MEMPTR | RAW | RECID | ROWIDFor more information on these primitive types, see the Data types reference entry.
- AS [ CLASS ]{object-type-name}
- Defines the variable as an object reference with the data type of a
class or interface. The default value of the variable is the Unknown value (
?). You cannot assign an initial value using the INITIAL option.- object-type-name
- Specifies the type name of an ABL or .NET class or interface.
Specify an object type name using the syntax described in the Type-name syntax reference entry. With an
appropriate USING statement,
you can also specify a class or interface name alone, without the qualifying
package or namespace.
You cannot directly specify the type name of a .NET mapped object type (such as System.Int32). To define a variable that matches a .NET mapped type, you must define it as the corresponding ABL primitive type (primitive-type-name).
- CLASS
- If the specified class or interface type name conflicts with an abbreviation for a built-in primitive type name, such as INT for INTEGER, you must specify the CLASS keyword.
For more information on object references, see the Class-based object reference reference entry.
- LIKE field
- Indicates the name of the variable, database field, temp-table field,
or work table field whose characteristics you want to use for the variable you are
defining. If you name a variable with this option, you must have defined that variable
earlier in the procedure. You can override the format, label, initial value, decimals,
and extent of the variable or database field by using the FORMAT, LABEL, COLUMN-LABEL,
INITIAL, DECIMALS, EXTENT, and VIEW-AS options. If you do not use these options, the
variable takes on the characteristics of the variable or database field you name.
If field has help and validate options defined, the variable you are defining does not inherit those characteristics.
If you reference a database field in a LIKE option in a DEFINE VARIABLE statement, DEFINE TEMP-TABLE statement, DEFINE WORK-TABLE statement, or format phrase, the database containing the referenced field must be connected at compile time but not necessarily at run time. Therefore, use the LIKE option with caution.
- EXTENT [constant ]
- Defines the variable as an array of data elements, where the element
data type is specified by the AS primitive-type-name option, the LIKE field option, or the AS object-type-name option. This option can specify an array variable as
either determinate (has a defined number of elements) or indeterminate (has an undefined
number of elements). To define a determinate array variable, specify the EXTENT option
with the constant argument. This optional argument
is an integer value that represents the number of data elements in the array variable.
To define an indeterminate array variable, specify the EXTENT option without the
constant argument.
The EXTENT is part of the variable data type. For more information, see the Type-name syntax reference entry.
An indeterminate array variable can be in one of two states: with a size (fixed) or without a size (unfixed). An indeterminate array variable does not have a size when first defined, unless initial values are provided.. You can set the size of an indeterminate array variable by:
- Initializing the array values when you define the variable, using the INITIAL option
- Setting the number of elements in the array variable using the EXTENT statement
- Assigning a sized array to the indeterminate array, setting the size to the size of the source array
- Passing array parameters to a procedure, user-defined function, or class-based method, so that the indeterminate array variable is the target for the passing of a determinate array, setting the size to the size of the determinate array
If you want to define a variable that is like an array variable or field, using the LIKE option, but if you do not want the variable to be an array, you can use EXTENT 0 to indicate a non-array field.
If you are using the AS option and you do not use the EXTENT option (or you specify constant as 0), the variable is not an array variable. If you are using the LIKE field option and you do not use the EXTENT option, the variable uses the extent defined for the database field you name (if any).
- SERIALIZE-NAME serialize-name
- An optional CHARACTER constant that specifies the name of the variable as it should appear when serialized into JSON. The default is variable-name. Use this option when the serialized name contains invalid characters for an ABL name, is an ABL keyword, or an invalid JSON property name.
- BGCOLOR expression
- Specifies a background color for the variable in graphical interfaces. This option is ignored in character interfaces.
- [ NOT ] CASE-SENSITIVE
- CASE-SENSITIVE indicates that the value stored for a character variable is case sensitive, and that all comparisons operations involving the variable are case sensitive. If you do not use this option, ABL comparisons are usually case insensitive. If you define a variable LIKE another field of variable, the new variable inherits case sensitivity. Use [NOT] CASE-SENSITIVE to override this default.
- COLUMN-LABEL label
- Names the label you want to display above the variable data in a
frame that uses column labels. If you want the label to use more than one line (a
stacked label), use an exclamation point (!) in the label to indicate where to break the
line. For example:
r-collbl.p
DEFINE VARIABLE credit-percent AS INTEGER NO-UNDO COLUMN-LABEL "Enter !percentage!increase ". FOR EACH Customer: DISPLAY Customer.Name Customer.CreditLimit. SET credit-percent. Customer.CreditLimit = (Customer.CreditLimit * (credit-percent / 100)) + Customer.CreditLimit. DISPLAY Customer.CreditLimit @ new-credit LIKE Customer.CreditLimit LABEL "New max cred". END.If you want to use the exclamation point (!) as one of the characters in a column label, use two exclamation points (
!!).The AVM does not display column labels if you use the SIDE-LABELS or NO-LABELS options with the Frame phrase.
If you define a variable to be LIKE a field, and that field has a column label in the Data Dictionary, the variable inherits that column label.
- CONTEXT-HELP-ID expression
- An integer value that specifies the identifier of the help topic for this variable in a help file specified at the session, window or dialog box level using the CONTEXT-HELP-FILE attribute.
- DCOLOR expression
- Specifies the display color for the variable in character interfaces. This option is ignored in graphical interfaces.
- DECIMALS n
- Specifies the number of decimal places to store for a DECIMAL
variable, where n is an integer constant. When you
define a variable AS DECIMAL, ABL automatically stores up to 10 decimal places for the
value of that variable. Use the DECIMALS option to store a smaller number of decimal
places. The DECIMALS option has nothing to do with the display format of the variable,
just the storage format.
If you use the LIKE option to name a field whose definition you want to use to define a variable, ABL uses the number of decimals in the field definition to determine how many decimal places to store for the variable.
Note: The XML-WRITE() method on a temp-table, temp-table buffer, or ProDataSet object also uses the DECIMALS attribute to determine the number of decimal places to export to the XML Document. - DROP-TARGET
- Indicates whether you want to be able to drop a file onto the
object.
The following example shows setting the DROP-TARGET option for a variable:
DEFINE VARIABLE fill-in-1 AS CHARACTER DROP-TARGET. - FGCOLOR expression
- Specifies a foreground color for the variable in graphical interfaces. This option is ignored in character interfaces.
- FONT expression
- Specifies a font for the variable.
- FORMAT string
- The data format of the variable you define. If you use the AS
primitive-type-name option and you do not use
FORMAT string, the variable uses the default format
for its data type. The following table lists the default data formats for the data
types.
Table 1. Default display formats Data type Default display format BLOB (See note) CHARACTER x(8) CLASS N/A (See note) CLOB (See note) COM-HANDLE >>>>>>9 DATE 99/99/99 DATETIME 99/99/9999 HH:MM:SS.SSS DATETIME-TZ 99/99/9999 HH:MM:SS.SSS+HH:MM DECIMAL ->>,>>9.99 HANDLE >>>>>>9 INT64 ->,>>>,>>9 INTEGER ->,>>>,>>9 LOGICAL yes/no LONGCHAR (See note) MEMPTR (See note) RAW (See note) RECID >>>>>>9 ROWID (See note) Note: You cannot display a BLOB, CLOB, MEMPTR, RAW, or ROWID value directly. However, you can convert a MEMPTR, RAW, or ROWID value to a character string representation using the STRING function and display the result. You can also convert a BLOB to a MEMPTR, and then use the STRING function. A MEMPTR or RAW value converts to decimal integer string. A ROWID value converts to a hexadecimal string, "0xhexdigits", where hexdigits is any number of characters "0" through "9" and "A" through "F". You can only display a LONGCHAR using the VIEW-AS EDITOR LARGE phrase. You can display a CLOB field by converting it to a LONGCHAR.Note: If you display a class instance using the MESSAGE statement, ABL automatically invokes the ToString( ) method (Object) (provided by the Progress.Lang.Object class) on the object reference. To display a class instance in a frame (for example, using the DISPLAY statement), you must first explicitly convert the object reference to a displayable type using the INT64 function, the INTEGER function, the STRING function, or the ToString( ) method (Object).See Develop ABL Applications for more information on data formatting.
If you use the LIKE field option and you do not use the FORMAT string option, the variable uses the format defined for the database field you name. You must enclose the string in quotes.
- INITIAL {constant| [ constant[ , constant] . . . ] }
- The initial value of the variable you want to define. If you use the
AS primitive-type-name option and you do not use
the INITIAL constant option, the default is the
initial value for the data type of the variable or array element.
When you define an array variable, you can supply initial values for each element in the array. For example:
DEFINE VARIABLE array-var AS CHARACTER NO-UNDO EXTENT 3 INITIAL ["Add","Delete","Update"].If you do not supply enough values to fill up the elements of the array, the AVM puts the last value you named into the remaining elements of the array. If you supply too many values, the AVM raises an error.
If you define a variable as an indeterminate array, and you supply initial values for elements in the array, the AVM sets the size to the number of elements in the array. You can then use the array as you would a determinate array, but you can also change its size later, if desired.
You can also use the EXTENT statement to set or reset the number of elements in an indeterminate array variable. For more information, see the EXTENT statement reference entry.
The following table lists the default initial values for the various variable data types.
Table 2. Default variable initial values Data type Default initial value CHARACTER "" (an empty string) CLASS Unknown value ( ?)(See note)
COM-HANDLE Unknown value ( ?)(See note)
DATE Unknown value ( ?) (displays as blanks)DATETIME Unknown value ( ?)DATETIME-TZ Unknown value ( ?)DECIMAL 0 HANDLE Unknown value ( ?)(See note)
INT64 0 INTEGER 0 LOGICAL no LONGCHAR Unknown value ( ?)MEMPTR A zero-length sequence of bytes (See note)
RAW A zero-length sequence of bytes (See note)
RECID Unknown value ( ?)ROWID Unknown value ( ?)(See note)
Note: You cannot use the INITIAL option of the variable definition to specify an initial value for CLASS, COM-HANDLE, HANDLE, MEMPTR, RAW, and ROWID data types.If you are using the LIKE field option and you do not use the INITIAL constant option, the variable uses the initial value of the field or variable. In the DEFINE SHARED VARIABLE statement, the INITIAL option has no effect. However, the DEFINE NEW SHARED VARIABLE, the DEFINE NEW SHARED TEMP-TABLE, and the DEFINE NEW WORK-TABLE statements work with the INITIAL option.
- LABEL string[ , string]...
- The label you want to use when the variable is displayed. If you use
the AS primitive-type-name option and you do not use
the LABEL string option, the default label is the
variable name. If you use the LIKE field option and
you do not use the LABEL string option, the variable
uses the label of the field or variable you name. You must enclose the string in quotes.
You can specify a label for each element in a determinate array variable. You cannot specify a label for elements in an indeterminate array variable.
In MS-Windows, you can designate a character within each label as a navigation mnemonic. Precede the character with an ampersand (&). When the variable is displayed with side labels, the mnemonic is underlined. The user can move focus to the variable by pressing ALT and the underlined letter. Navigation mnemonics operate only when you use side labels. If you specify more than one widget with the same mnemonic, the AVM transfers focus to each of these in tab order when you make a selection.
Ending a label with an ampersand might produce unwanted behavior. To include a literal ampersand within a label, specify a double ampersand (&&).
- MOUSE-POINTER expression
- Specifies the default mouse pointer for the variable.
- NO-UNDO
- When the value of a variable is changed during a transaction and the
transaction is undone, the AVM restores the value of the variable to its prior value. If
you do not want, or if you do not need, the value of a variable to be undone even when
it has been changed during a transaction, use the NO-UNDO option with the DEFINE
VARIABLE statement. NO-UNDO variables are more efficient; use this option whenever
possible.
Specifying NO-UNDO for a variable is especially useful if you want to indicate an error condition as the value of the variable, perform an UNDO, and later take some action based on that error condition. If one variable is defined LIKE another that is NO-UNDO, the second variable will be NO-UNDO only if you specify NO-UNDO in the definition of the second variable.
- PFCOLOR expression
- Specifies the prompt-for color for the variable in character interfaces. This option is ignored in graphical interfaces.
- view-as-phrase
- Specifies the default data representation widget for this variable.
Following is the syntax for the view-as-phrase:
VIEW-AS { combo-box-phrase | editor-phrase | FILL-IN [ NATIVE ] [size-phrase] [ TOOLTIP tooltip] | radio-set-phrase | selection-list-phrase | slider-phrase | TEXT [size-phrase] [ TOOLTIP tooltip] | TOGGLE-BOX [size-phrase] [ TOOLTIP tooltip] }For more information on view-as-phrase, see the VIEW-AS phrase reference entry.
- trigger-phrase
- Defines triggers for the data representation widget specified in the
view-as-phrase. Following is the syntax for the
trigger-phrase:
TRIGGERS: { ON event-list[ ANYWHERE ] { trigger-block | PERSISTENT RUN proc-name [ IN handle] [ ( input-parameters ) ] } }... END [ TRIGGERS ]For more information on triggers, see the Trigger phrase reference entry.
Example
The r-dfvar.p procedure defines two variables, del
and nrecs to be shared with procedure r-dfvar2.p. The
del variable passes information to r-dfvar2.p, while
nrecs passes information back to r-dfvar.p from
r-dfvar2.p.
r-dfvar.p
|
r-dfvar2.p
|
The following example is a startup procedure. It defines a new global variable with the initial value TRUE and uses that variable to determine whether to run an initialization procedure, r-init.p, that displays sign-on messages. Then the global variable first-time is set to FALSE. If you restart this procedure during the same session (pressed STOP), r-init.p does not run again.
The procedure also defines the variable selection for entering menu choices within this procedure:
r-dfvar3.p
|
The following procedure finds the day of the week of a date the user enters. The procedure defines an array with seven elements and uses the INITIAL option to define the initial value of each element in the array.
r-dfvar4.p
|
The following example defines a variable with a VIEW-AS phrase and a Trigger phrase:
r-defsel.p
|
For examples of instance and static variable data member definitions, see the descriptions of r-CustObj.cls, r-CustObjStatic.cls, and r-CustObjAbstract.cls in the CLASS statement reference entry.
Notes
- You can use the DEFINE VARIABLE statement anywhere. However, all references to the variable must appear after the DEFINE VARIABLE statement that defines it.
- You cannot define a variable as a BLOB or CLOB field. You can define a variable using their MEMPTR and LONGCHAR counterparts, respectively.
- A HANDLE variable defined as a static data member can reference the handle of any compile-time defined (static) or run-time defined (dynamic) handle-based object, such as a button, temp-table, or ProDataSet.
- Defining a LONGCHAR variable supports the same options as a CHARACTER variable, except for the FORMAT option and all VIEW-AS options except VIEW-AS EDITOR LARGE.
- You should use the CASE-SENSITIVE option only when it is important to distinguish between uppercase and lowercase values entered for a character variable. For example, use CASE-SENSITIVE to define a variable for a part number that contains mixed uppercase and lowercase characters.
- After you use the DEFINE NEW GLOBAL SHARED VARIABLE statement to create a global shared variable, use the DEFINE SHARED VARIABLE statements in other procedures to access that variable.
- You cannot define the same global variable twice in the same ABL session. If you try, and the definitions of the two variables do not match, the AVM raises an error. If the definitions of the two variables match, the AVM disregards the second variable you tried to define (if you are rerunning a startup procedure).
- Changes made to variables when there is no active transaction are not undone when a block is undone.
- When a procedure names and uses a shared variable:
- The AVM searches through the calling chain of procedures looking for the most recent DEFINE NEW SHARED VARIABLE statement that created that shared variable.
- If no DEFINE NEW SHARED VARIABLE statement is found, the AVM searches for a DEFINE NEW GLOBAL SHARED VARIABLE statement that created the shared variable.
- If the procedure that names the shared variable is called from a trigger or internal procedure that is part of a persistent procedure context, the persistent context is also checked for the most recent DEFINE NEW SHARED VARIABLE or DEFINE NEW GLOBAL SHARED VARIABLE statement at the point in the calling chain where the trigger or internal procedure is executed.
- If the AVM finds one of these statements, it does not search any further for other statements that might have defined the same variable as NEW or NEW GLOBAL.
- The AVM checks the definition of a SHARED variable against that of the corresponding NEW SHARED or NEW GLOBAL SHARED variable. The data types and array extents must match. If the FORMAT, LABEL and DECIMALS specifications are not the same, each procedure uses its individual specification. The DEFINE NEW SHARED statement determines if a shared variable is NO-UNDO.
- A SHARED variable remains in scope for an instance of a persistent procedure until the
instance is deleted. This is true even if the original procedure that defined the variable
as NEW SHARED goes out of scope while the procedure instance remains persistent.
If a trigger or internal procedure of a persistent procedure executes an external subprocedure that defines a SHARED variable, the AVM includes the persistent procedure in the resolution of the corresponding NEW SHARED variable as though the procedure were on the procedure call stack.
- If an application with several procedures defines a NEW SHARED variable with the same name in each procedure, the AVM creates a different instance of the NEW SHARED variable in each procedure. This behavior supports recursive procedures and bill-of-materials applications.
- You can neither define a SHARED or NEW SHARED variable, nor access such a variable
defined in a procedure file, from within a class definition (
.cls) file. If you do, ABL generates a compilation error. However, multiple procedure (.p) files can define and access an object reference variable for a class instance as a NEW SHARED or NEW GLOBAL SHARED variable. In this case, the object reference variables must be defined for the same class (not a subclass or a super class) in all procedures that use them. - For SpeedScript, the following options are invalid: BGCOLOR, CONTEXT-HELP-ID, DCOLOR, FONT, FGCOLOR, MOUSE-POINTER, PFCOLOR, and view-as-phrase.
See also
Class-based data member access, DEFINE BUFFER statement, RUN statement, Trigger phrase, Type-name syntax, USING statement, VAR statement, VIEW-AS phrase