Declaring variables

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.

Where to declare variables

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:

  1. Select Declare from the first drop-down list in the Script view.

  2. Select the type of variable you want to declare in the second drop-down list of the Script editor.

  3. 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.

About using variables

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:

  1. A local variable

  2. A shared variable

  3. A global variable

  4. 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.

Syntax of a variable declaration

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
Datatype of a variable

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.

Variable names

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.

Initial values for variables

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

Access for instance variables

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:

  • PUBLIC -- (Default) Any script in the application can refer to the variable. In another object's script, you use dot notation to qualify the variable name and identify the object it belongs to.

  • PROTECTED -- Scripts for the object for which the variable is declared and its descendants can refer to the variable.

  • PRIVATE -- Scripts for the object for which the variable is declared can refer to the variable. You cannot refer to the variable in descendants of the object.

readaccess (optional)

A keyword restricting the ability of scripts to read the variable's value. Values are:

  • PROTECTEDREAD -- Only scripts for the object and its descendants can read the variable.

  • PRIVATEREAD -- Only scripts for the object can read the variable.

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:

  • PROTECTEDWRITE -- Only scripts for the object and its descendants can change the variable.

  • PRIVATEWRITE -- Only scripts for the object can change the variable.

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.


Usage

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 
Another format for access-right keywords

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