General information
Before you use a variable in a PowerBuilder script, you must declare it (give it a datatype and a name).
A variable can be a standard datatype, a structure, or an object. Object datatypes can be system objects as displayed in the Browser or they can be objects you have defined by deriving them from those system object types. For most variables, you can assign it a value when you declare it. You can always assign it a value within a script.
Scope
You determine the scope of a PowerScript variable by selecting where you declare it. Instance variables have additional access keywords that restrict specific scripts from accessing the variable.
The following table shows the four scopes of variables.
Scope |
Description |
---|---|
Global |
Accessible anywhere in the application. It is independent of any object definition. |
Instance |
Belongs to an object and is associated with an instance of that object (you can think of it as a property of the object). Instance variables have access keywords that determine whether scripts of other objects can access them. They can belong to the application object, a window, a user object, or a menu. |
Shared |
Belongs to an object definition and exists across all instances of the object. Shared variables retain their value when an object is closed and opened again. Shared variables are always private. They are accessible only in scripts for the object and for controls associated with the object. They can belong to the application object, a window, a user object, or a menu. |
Local |
A temporary variable that is accessible only in the script in which you define it. When the script has finished executing, the variable constant ceases to exist. |
Global, instance, and shared declarations
Global, instance, and shared variables can be defined in the Script editor of the Application, Window, User Object, or Menu painters. Global variables can also be defined in the Function painter:
-
Select Declare from the first drop-down list in the Script view.
-
Select the type of variable you want to declare in the second drop-down list of the Script editor.
-
Type the declaration in the scripting area of the Script view.
Local declarations
You declare local variables for an object or control in the script for that object or control.
Declaring SQL cursors
You can also declare SQL cursors that are global, shared, instance, or local. Open a specific script or select a variable declaration scope in the Script editor and type the DECLARE SQL statement or select Paste SQL from the PainterBar or pop-up menu.
General information
To use or set a variable's value in a PowerBuilder script, you name the variable. The variable must be known to the compiler -- in other words, it must be in scope.
You can use a variable anywhere you need its value -- for example, as a function argument or in an assignment statement.
How PowerBuilder looks for variables
When PowerBuilder executes a script and finds an unqualified reference to a variable, it searches for the variable in the following order:
-
A local variable
-
A shared variable
-
A global variable
-
An instance variable
As soon as PowerBuilder finds a variable with the specified name, it uses the variable's value.
Referring to global variables
To refer to a global variable, you specify its name in a script. However, if the global variable has the same name as a local or shared variable, the local or shared variable will be found first.
To refer to a global variable that is masked by a local or shared variable of the same name, use the global scope operator (::) before the name:
::globalname
For example, this statement compares the value of local and global variables, both named total:
IF total < ::total THEN ...
Referring to instance variables
You can refer to an instance variable in a script if there is an instance of the object open in the application. Depending on the situation, you might need to qualify the name of the instance variable with the name of the object defining it.
Using unqualified names
You can refer to instance variables without qualifying them with the object name in the following cases:
-
For application-level variables, in scripts for the application object
-
For window-level variables, in scripts for the window itself and in scripts for controls in that window
-
For user-object-level variables, in scripts for the user object itself and in scripts for controls in that user object
-
For menu-level variables, in scripts for a menu object, either the highest-level menu or scripts for the menu objects included as items on the menu
For example, if w_emp has an instance variable EmpID, then you can reference EmpID without qualification in any script for w_emp or its controls as follows:
sle_id.Text = EmpID
Using qualified names
In all other cases, you need to qualify the name of the instance variable with the name of the object using dot notation:
object.instancevariable
This requirement applies only to Public instance variables. You cannot reference Private instance variables outside the object at all, qualified or not.
For example, to refer to the w_emp instance variable EmpID from a script outside the window, you need to qualify the variable with the window name:
sle_ID.Text = w_emp.EmpID
There is another situation in which references must be qualified. Suppose that w_emp has an instance variable EmpID and that in w_emp there is a CommandButton that declares a local variable EmpID in its Clicked script. In that script, you must qualify all references to the instance variable:
Parent.EmpID
Using pronouns as name qualifiers
To avoid ambiguity when referring to variables, you might decide to always use qualified names for object variables. Qualified names leave no doubt about whether a variable is local, instance, or shared.
To write generic code but still use qualified names, you can use the pronouns This and Parent to refer to objects. Pronouns keep a script general by allowing you to refer to the object without naming it specifically.
Window variables in window scripts
In a window script, use the pronoun This to qualify the name of a window instance variable. For example, if a window has an instance variable called index, then the following statements are equivalent in a script for that window, as long as there is no local or global variable named index:
index = 5 This.index = 5
Window variables in control scripts
In a script for a control in a window, use the pronoun Parent to qualify the name of a window instance variable -- the window is the parent of the control. In this example, the two statements are equivalent in a script for a control in that window, as long as there is no local or global variable named "index":
index = 5 Parent.index = 5
Naming errors
If a local or global variable exists with the name "index", then the unqualified name refers to the local or global variable. It is a programming error if you meant to refer to the object variable. You get an informational message from the compiler if you use the same name for instance and global variables.
Simple syntax
In its simplest form, a PowerScript variable declaration requires only two parts: the datatype and the variable name. For example:
datatype variablename
Full syntax
The full syntax allows you to specify access and an initial value. Arrays and some datatypes, such as blobs and decimals, accept additional information:
{ access } datatype { { size } } { { precision } } variablename { = value } {, variablename2 { = value2 } }
Parameter |
Description |
---|---|
access (optional) |
(For instance variables only) Keywords specifying the access for the variable. For information, see Access for instance variables. |
datatype |
The datatype of the variable. You can specify a standard datatype, a system object, or a previously defined structure. For blobs and decimals, you can specify the size or precision of the data by including an optional value in brackets. |
{ size } (optional) |
(For blobs only) A number, enclosed in braces, specifying the size in bytes of the blob. If { size } is omitted, the blob has an initial size of zero and PowerBuilder adjusts its size each time it is used at runtime. If you enter a size that exceeds the declared length in a script, PowerBuilder truncates the blob data. |
{ precision } (optional) |
(For decimals only) A number, enclosed in braces, specifying the number of digits after the decimal point. If you do not specify a precision, the variable takes the precision assigned to it in the script. |
variablename |
The name of the variable (must be a valid PowerScript identifier, as described in Identifier names). You can define additional variables with the same datatype by naming additional variable names, separated by commas; each variable can have a value. |
value (optional) |
A literal or expression of the appropriate datatype that will be the initial value of the variable. Blobs cannot be initialized with a value. For information, see Initial values for variables. |
Examples
Declaring instance variables
integer ii_total = 100 // Total shares date id_date // Date shares were bought
Declaring a global variable
string gs_name
Declaring shared variables
time st_process_start string ss_process_name
Declaring local variables
string ls_city = "Boston" integer li_count
Declaring blobs
This statement declares ib_Emp_Picture a blob with an initial length of zero. The length is adjusted when data is assigned to it:
blob ib_Emp_Picture
This statement declares ib_Emp_Picture a blob with a fixed length of 100 bytes:
blob{100} ib_Emp_Picture
Declaring decimals
These statements declare shared variables sc_Amount and sc_dollars_accumulated as decimal numbers with two digits after the decimal point:
decimal{2} sc_Amount decimal{2} sc_dollars_accumulated
This statement declares lc_Rate1 and lc_Rate2 as decimal numbers with four digits after the decimal point:
dec{4} lc_Rate1, lc_Rate2
This statement declares lc_Balance as a decimal with zero digits after the decimal point:
decimal{0} lc_Balance
This statement does not specify the number of decimal places for lc_Result. After the product of lc_Op1 and lc_Op2 is assigned to it, lc_Result has four decimal places:
dec lc_Result dec{2} lc_Op1, lc_Op2 lc_Result = lc_Op1 * lc_Op2
A PowerScript variable can be declared as one of the following datatypes:
-
A standard datatype (such as an integer or string).
-
An object or control (such as a window or CommandButton).
-
An object or structure that you have defined (such as a window called mywindow). An object you have defined must be in a library on the application's library search path when the script is compiled.
In a well-planned application, standards determine how you name your PowerScript variables. Naming conventions make scripts easy to understand and help you avoid name conflicts. A typical approach is to include a prefix that identifies the scope and the datatype of the variable. For example, a prefix for an instance variable's name typically begins with i (such as ii_count or is_empname), a local integer variable's name would be li_total and a global integer variable's name would be gi_total. For information about naming conventions, see the the section called “Naming conventions” in Users Guide.
X and Y as variable names
Although you might think of x and y as typical variable names, in PowerBuilder they are also properties that specify an object's onscreen coordinates. If you use them as variables and forget to declare them, you do not get a compiler error. Instead, PowerBuilder assumes you want to move the object, which might lead to unexpected results in your application.
When you declare a PowerScript variable, you can accept the default initial value or specify an initial value in the declaration.
Default values for variables
If you do not initialize a variable when you declare it, PowerBuilder sets the variable to the default value for its datatype as shown in the following table.
For this variable datatype |
PowerBuilder sets this default value |
---|---|
Blob |
A blob of 0 length; an empty blob |
Char (or character) |
ASCII value 0 |
Boolean |
false |
Date |
1900-01-01 (January 1, 1900) |
DateTime |
1900-01-01 00:00:00 |
Numeric (byte, integer, long, longlong, decimal, real, double, UnsignedInteger, and UnsignedLong) |
0 |
String |
Empty string ("") |
Time |
00:00:00 (midnight) |
Specifying a literal as a initial value
To initialize a variable when you declare it, place an equal sign (=) and a literal appropriate for that variable datatype after the variable. For information about literals for specific datatypes, see Standard datatypes.
Do not use a function's return value
You should not initialize a variable by assigning it the return value of a global user defined function, because it might not compile correctly, or because it could lead to confusion about the value assigned. For example, do not use:
integer i = f_return_one()
Although you can use global system functions or expressions to initialize variables with compile time values in a variable declaration statement, for runtime value assignments, you must also declare variables and assign their values in separate statements.
This example declares li_count as an integer whose value is 5:
integer li_count=5
This example declares li_a and li_b as integers and initializes li_a to 5 and li_b to 10:
integer li_a=5, li_b=10
This example initializes ls_method with the string "UPS":
string ls_method="UPS"
This example initializes ls_headers to three words separated by tabs:
string ls_headers = "Name~tAddress~tCity"
This example initializes li_a to 1 and li_c to 100, leaving li_b set to its default value of zero:
integer li_a=1, li_b, li_c=100
This example declares ld_StartDate as a date and initializes it with the date February 1, 2004:
date ld_StartDate = 2004-02-01
Specifying an expression as an initial value
You can initialize a variable with the value of an existing variable or expression, such as:
integer i = 100 integer j = i
When you do this, the second variable is initialized with the value of the expression when the script is compiled. The initialization is not reevaluated at runtime.
If the expression's value changes
Because the expression's value is set to the variable when the script is compiled (not at runtime) make sure the expression is not one whose value is based on current conditions. If you want to specify an expression whose value will be different when the application is executed, do not initialize the variable in the declaration. For such values, declare the variable and assign the value in separate statements.
In this declaration, the value of d_date is the date the script is compiled:
date d_date = Today( )
In contrast, these statements result in d_date being set to the date the application is run:
date d_date d_date = Today( )
How shared variables are initialized
When you use a shared variable in a script, the variable is initialized when the first instance of the object is opened. When the object is closed, the shared variable continues to exist until you exit the application. If you open the object again without exiting the application, the shared variable will have the value it had when you closed the object.
For example, if you set the shared variable Count to 20 in the script for a window, then close the window, and then reopen the window without exiting the application, Count will be equal to 20.
When using multiple instances of windows
If you have multiple instances of the window in the example above, Count will be equal to 20 in each instance. Since shared variables are shared among all instances of the window, changing Count in any instance of the window changes it for all instances.
How instance variables are initialized
When you define an instance variable for a window, menu, or application object, the instance variable is initialized when the object is opened. Its initial value is the default value for its datatype or the value specified in the variable declarations.
When you close the object, the instance variable ceases to exist. If you open the object again, the instance variable is initialized again.
When to use multiple instances of windows
When you build a script for one of multiple instances of a window, instance variables can have a different value in each instance of the window. For example, to set a flag based on the contents of the instance of a window, you would use an instance variable.
When to use shared variables instead
Use a shared variable instead of an instance variable if you need a variable that:
-
Keeps the same value over multiple instances of an object
-
Continues to exist after the object is closed
Description
The general syntax for declaring PowerScript variables (see Syntax of a variable declaration) showed that you can specify access keywords in a declaration for an instance variable. This section describes those keywords.
When you specify an access right for a variable, you are controlling the visibility of the variable or its visibility access. Access determines which scripts recognize the variable's name.
For a specified access right, you can control operational access with modifier keywords. The modifiers specify which scripts can read the variable's value and which scripts can change it.
Syntax
{ access-right } { readaccess } { writeaccess } datatype variablename
The following table describes the parameters you can use to specify access rights for instance variables.
Parameter |
Description |
---|---|
access-right (optional) |
A keyword specifying where the variable's name will be recognized. Values are:
|
readaccess (optional) |
A keyword restricting the ability of scripts to read the variable's value. Values are:
When access-right is PUBLIC, you can specify either keyword. When access-right is PROTECTED, you can specify only PRIVATEREAD. You cannot specify a modifier for PRIVATE access, because PRIVATE is already fully restricted. If readaccess is omitted, any script can read the variable. |
writeaccess (optional) |
A keyword restricting the ability of scripts to change the variable's value. Values are:
When access-right is PUBLIC, you can specify either keyword. When access-right is PROTECTED, you can specify only PRIVATEWRITE. You cannot specify a modifier for PRIVATE access, because PRIVATE is already fully restricted. If writeaccess is omitted, any script can change the variable. |
datatype |
A valid datatype. See Syntax of a variable declaration. |
variablename |
A valid identifier. See Syntax of a variable declaration. |
Access modifiers give you more control over which objects have access to a particular object's variables. A typical use is to declare a public variable but only allow the owner object to modify it:
public protectedwrite integer ii_count
You can also group declarations that have the same access by specifying the access-right keyword as a label (see Another format for access-right keywords).
When you look at exported object syntax, you might see the access modifiers SYSTEMREAD and SYSTEMWRITE. Only PowerBuilder can access variables with these modifiers. You cannot refer to variables with these modifiers in your scripts and functions and you cannot use these modifiers in your own definitions.
Examples
To declare these variables, select Declare>Instance Variables in the appropriate painter.
These declarations use access keywords to control the scripts that have access to the variables:
private integer ii_a, ii_n public integer ii_Subtotal protected integer ii_WinCount
This protected variable can only be changed by scripts of the owner object; descendants of the owner can read it:
protected privatewrite string is_label
These declarations have public access (the default) but can only be changed by scripts in the object itself:
privatewrite real ir_accum, ir_current_data
This declaration defines an integer that only the owner objects can write or read but whose name is reserved at the public level:
public privateread privatewrite integer ii_reserved
Private variable not recognized outside its object
Suppose you have defined a window w_emp with a private integer variable ii_int:
private integer ii_int
In a script you declare an instance of the window called w_myemp. If you refer to the private variable ii_int, you get a compiler warning that the variable is not defined (because the variable is private and is not recognized in scripts outside the window itself):
w_emp w_myemp w_myemp.ii_int = 1 // Variable not defined
Public variable with restricted access
Suppose you have defined a window w_emp with a public integer variable ii_int with write access restricted to private:
public privatewrite integer ii_int
If you write the same script as above, the compiler warning will say that you cannot write to the variable (the name is recognized because it is public, but write access is not allowed):
w_emp w_myemp w_myemp.ii_int = 1 // Cannot write to variable
Description
You can also group declarations of PowerScript variables according to access by specifying the access-right keyword as a label. It appears on its own line, followed by a colon (:).
Syntax
access-right: { readaccess } { writeaccess } datatype variablename { access-right } { readaccess } { writeaccess } datatype variablename { readaccess } { writeaccess } datatype variablename
Within a labeled group of declarations, you can override the access on a single line by specifying another access-right keyword with the declaration. The labeled access takes effect again on the following lines.
Examples
In these declarations, the instance variables have the access specified by the label that precedes them. Another private variable is defined at the end, where private overrides the public label:
Private: integer ii_a=10, ii_b=24 string is_Name, is_Address1 Protected: integer ii_Units double idb_Results string is_Lname Public: integer ii_Weight string is_Location="Home" private integer ii_test
Some of these protected declarations have restricted write access:
Protected: integer ii_Units privatewrite double idb_Results privatewrite string is_Lname