PowerBuilder: DataWindow property expressions

In PowerBuilder, DataWindow property expressions use dot notation. These sections explain how to use the expressions and what syntax to use to construct them:

Basic structure of DataWindows and property expressions in PowerBuilder

Controls in a DataWindow

A DataWindow object is made up of many controls (such as Columns, Text, Pictures, and Reports). In PowerBuilder scripts, the datatype of these controls is DWObject. Each DWObject has a set of properties according to its type. The syntax of a property expression allows you to address any of these properties.

Object property

A DataWindow property expression uses the Object property of the DataWindow control to access the DataWindow object. Following the Object property, you specify a control name and one or more properties.

The simple syntax is:

dwcontrol.Object.dwcontrolname.property

For example:

dw_1.Object.empname.Resizeable

For the full syntax, see PowerBuilder syntax for DataWindow property expressions.

About DataWindow data expressions

Expressions that access data in a DataWindow object using dot notation use the Object and Data properties. These expressions are called data expressions (in contrast to property expressions); because of the intricate syntax for data expressions, they are described separately, in Accessing Data in Code.

Datatypes of DataWindow property expressions in PowerBuilder

DataWindow property values

The values of DataWindow object properties are strings. These strings can contain numeric or yes/no values, but the values you access are strings, not integers or boolean values.

Although the property values are really strings, the PowerScript compiler allows you to assign numbers and boolean values to properties whose strings represent numeric values or contain yes/no strings. This does not mean the datatype is integer or boolean. It is just a convenience when assigning a value to the property.

For example, both of these statements are correct:

dw_1.Object.empname.Border = 1
dw_1.Object.empname.Border = '1'

DataWindow property expressions

In PowerBuilder, the datatype of a property expression is Any (not string), but the value of the data in the Any variable is a string. This may sound like an unnecessary distinction, but it does matter when you use a property expression as a method argument. If the method does not accept an Any variable as an argument, you might need to use the String function to cast the data to the correct datatype.

For example, because the MessageBox function accepts a string argument not an Any datatype, the property expression is enclosed in a String conversion function:

MessageBox("Border", & String(dw_1.Object.empname.Border))

Using the DWObject variable in PowerBuilder

A PowerBuilder DWObject object is an object that exists within a DataWindow object. Each column, computed field, text control, or drawing control is a DWObject.

A DWObject reference allows you to refer directly to controls within a DataWindow.

You can use a DWObject variable to simplify DataWindow property and data expressions. A DWObject variable takes the place of several elements of the control's dot notation.

The following syntaxes and examples show how using a DWObject variable affects property and data expressions.

Property expressions

The simple syntax for a property expression is:

dwcontrol.Object.dwcontrolname.property

You can use a DWObject variable to refer to dwcontrolname.

If the code declares a DWObject variable and assigns the control within the DataWindow to the variable, using syntax like this:

DWObject dwobjectvar
dwobjectvar = dwcontrol.Object.dwcontrolname

the syntax of the expression itself becomes:

dwobjectvar.property

For example, if the DataWindow had a column named empname, a text control named t_emplabel, and a computed field named cf_average, you could make the following assignments:

DWObject dwo_column, dwo_text, dwo_compute
dwo_column = dw_1.Object.empname
dwo_text = dw_1.Object.t_emplabel
dwo_compute = dw_1.Object.cf_average

Data expressions

You can use a DWObject variable to refer to a column in a data expression. For example, this syntax gets data for a single row and column:

dwcontrol.Object.columnname {.buffer } {.datasource } [ rownum ]

If the code declares a DWObject variable and assigns the control within the DataWindow to the variable, using syntax like this:

DWObject dwobjectvar
dwobjectvar = dwcontrol.Object.columnname

The syntax of the expression itself becomes:

dwobjectvar. {.buffer } {.datasource } [ rownum ]

DWObject variables in PowerBuilder

In PowerBuilder, you can get better performance by using a DWObject variable to resolve the object reference in a DataWindow property or data expression. Evaluating the reference once and reusing the resolved reference is more efficient than fully specifying the object reference again.

This technique yields the most benefit if your application uses compiled code or if you are using a DataWindow expression in a loop.

For example, this code is not optimized for best performance, because the fully specified data expression within the loop must be resolved during each pass:

integer li_data
FOR li_cnt = 1 to 100
      li_data = dw_1.Object.emp_salary[li_cnt]
      .. // Code to process data value
NEXT

This code has been optimized. The reference to the control within the DataWindow (emp_salary) is resolved once before the loop begins. The reference stored in the DWObject variable is reused repeatedly in the loop:

integer li_data
DWObject dwo_empsalary

dwo_empsalary = dw_1.Object.emp_salary

FOR li_cnt = 1 to 100
      li_data = dwo_empsalary.Primary[li_cnt]
      .. // Code to process data value
NEXT

PowerBuilder DWObject versus data

In a data expression for a column that refers to one item, the brackets for the row index identify the expression as a data expression (for information, see Syntax for one or all data items in a named column). However, if you assign the column control to a DWObject variable, the brackets incorrectly signify an array of objects. Therefore you must include a buffer name or data source to specify that you want data:

dw_1.Object.emp_salary[1] //Single data item
DWObject dwo_empsalary
dwo_empsalary = dw_1.Object.emp_salary
dwo_empsalary[1] // Incorrect: array of DWObject
dwo_empsalary.Primary[1] // Single data item

DWObject arguments for DataWindow events in PowerBuilder

In PowerBuilder, several DataWindow events pass a DWObject argument called dwo to the event script. The value is a resolved reference to a control within the DataWindow having something to do with the user's action that triggered the event. Often it is the column the user is changing or the control the user clicked.

What type of DWObject?

You can use DataWindow properties to find out more about the control stored in dwo. The first step is to find out the control's type so that subsequent statements will use properties that are appropriate for the control type. If an expression uses a property that does not correspond to the control's type, it will trigger the Error event. This statement in an event script gets the type:

ls_type = dwo.Type

The possible values that can be assigned to ls_type are:

bitmap (for Picture)
button
column
compute (for Computed Field)
graph
groupbox
line
ole
ellipse (for Oval)
rectangle
roundrectangle
report
tableblob
text
datawindow (when the user doesn't click a specific control)

You can write a CHOOSE CASE statement for the expected types.

After you have determined the type, you can get more details about the specific control.

Examples

If the control is a column, you can get the column name with this statement:

ls_name = dwo.Name

If the control is a column, you can get data from the whole column or from specific rows. You must specify the buffer from which you want to retrieve data. In this statement, row is another argument passed to the event so the value in ls_data is the data in the row and column the user clicked. In this example, if the column value is not a string, an error occurs (check ColType property to get the column datatype):

ls_data = dwo.Primary[row]

This statement assigns a new value to the row and column the user clicked. The assignment does not trigger the ItemChanged event and bypasses validation. If the column is not numeric, an error occurs:

dwo.Primary[row] = 41

This statement gets all the data in the column the user clicked. The data is stored as an array in the Any variable. An Any variable can hold all datatypes, so no error occurs:

Any la_data
la_data = dwo

This statement gets data in the column from selected rows. The data is stored as an array in the Any variable:

Any la_data
la_data = dwo.Selected

When a DataWindow property expression is evaluated in PowerBuilder

In PowerBuilder, expressions that refer to DataWindow object properties and data are not verified until your application runs.

No compiler checking

When your script is compiled, PowerBuilder does not verify the parameters of the expression that follow the Object property. Your application can select the DataWindow object in a DataWindow control at runtime without invalidating the compiled script.

Potential execution errors

If the datatype of the expression is not compatible with how the expression is used, or if the specified rows or columns do not exist, then an error will occur at runtime.

You can handle the error by surrounding the expression in a try-catch block or by writing a script for the DataWindow Error event.

Handling errors from DataWindow property expressions in PowerBuilder

What causes errors

In PowerBuilder, an invalid DataWindow property expression causes a runtime error in your application. A runtime error causes the application to terminate unless you catch the error in a runtime error handler or unless there is a script for the Error event.

Conditions that cause errors

Possible causes

Invalid names of controls within the DataWindow object

Mistyping, which the compiler does not catch because it does not evaluate the expression.

A different DataWindow object has been inserted in the control and it has different columns and controls.

A property is not valid for the specified control

Mistyping.

The control is a different type than expected.


You can prevent the application from terminating by handling the error in the DataWindow control's Error event or by catching the error in a try-catch block.

Responding to errors in the Error event script

The Error event's arguments give you several options for responding to the error. You choose a course of action and set the action argument to a value of the ExceptionAction enumerated datatype.

ExceptionAction enumerated datatype

If you give the action argument a value other than ExceptionIgnore!, you will prevent error-handling code in try-catch blocks from executing. For more information on values for the ExceptionAction enumerated datatype, see the Error event description in the the section called “Error” in PowerScript Reference.

If you are trying to find out a property value and you know the expression might cause an error, you can include code that prepares for the error by storing a default value in an instance variable. Then the Error event script can return that value in place of the failed expression.

There are three elements to this technique: the declaration of an instance variable, the script that sets the variable's default value and then accesses a DataWindow property, and the Error event script. These elements are shown in Example 2 below.

Responding to errors in a try-catch block

You can prevent the application from terminating by handling the DataWindow runtime error (DWRuntimeError) in a try-catch block. If you are trying to find out a property value and you know the expression might cause an error, you can include code that automatically assigns a valid default value that can be substituted for the failed expression, as in Example 2 below.

Examples

Example 1

This code displays complete information about the error in a multilineedit mle_1.

The error event script:

mle_1.text = &
   "error#: " + string(errornumber) + "~r~n" + &
   "text: " + errortext + "~r~n" + &
   "parent: " + errorwindowmenu + "~r~n" + &
   "object: " + errorobject + "~r~n" + &
   "line: " + string(errorline) + "~r~n"
action = ExceptionIgnore!

The try-catch block:

Try   ... //DataWindow property expression
Catch (DWRuntimeError myExc)
   mle_1.text = &
   "error#: " + string(myExc.number) + "~r~n" +&
   "text: " + myExc.text + "~r~n" + &
   "script: " + myExc.routinename + "~r~n" + &
   "object: " + myExc.objectname + "~r~n" + &
   "line: " + string(myExc.line) + "~r~n"
End Try

If the correct evaluation of the expression is not critical to the application, the application continues without terminating.

Example 2

This example provides a return value that will become the expression's value if evaluation of the expression causes an error.

There are three elements to code in the error event script. The instance variable is a string:

string is_dwvalue

This script for a button or other control stores a valid return value in an instance variable and then accesses a DataWindow property:

is_dwvalue = "5"
ls_border = dw_1.Object.id.Border

The Error event script uses the instance variable to provide a valid return value:

action = ExceptionSubstituteReturnValue!
returnvalue = is_dwvalue

The try-catch block:

try ls_border = dw_1.Object.id.Border
catch (DWRuntimeError myDWError)
   ls_border = "5"
end try

At runtime, if the id column does not exist or some other error occurs, then the expression returns a valid border value -- here the string "5". If you are using the Error event instead of a try-catch block, you must first store the value in an instance variable.

PowerBuilder syntax for DataWindow property expressions

The following sections describe syntax for property expressions:

Basic syntax for DataWindow property expressions in PowerBuilder

Description

DataWindow property expressions in PowerBuilder use dot notation to specify the controls and properties that you want to access.

Syntax

dwcontrol.Object.dwcontrolname { .property } .property { = value }

Argument

Description

dwcontrol

The name of the DataWindow control or child DataWindow in which you want to get or set properties.

Object

Object indicates that subsequent elements refer to the DataWindow object within dwcontrol.

dwcontrolname

a control within the DataWindow object. Possible values are DataWindow (for properties that apply to the whole DataWindow) or the name of a column, computed field, graph, line, oval, picture, rectangle, roundrectangle, report, TableBlob, or text control.

Nested DataWindow objects

If dwcontrolname is a column with the DropDownDataWindow style, a report, or an OLE Object control, you can specify another Object keyword and dwcontrolname to refer to properties of controls within the nested DataWindow object. You can specify Object.dwobjectname as many times as needed to refer to a deeply nested report.

For nested syntax, see Syntax for nested objects in DataWindow property expressions in PowerBuilder.

property

A property that applies to dwcontrolname. If the property requires additional qualifying properties, list the additional properties, separating them with a dot.

For lists of applicable properties, see the Property tables at the beginning of DataWindow Object Properties

value

A string whose value is to be assigned to the property.

If the property value is a number, value can either be a string whose value is a number or a numeric datatype. The value is stored as a string.

If the property value is a yes or no value, value can be either a string whose value is "yes" or "no" or a boolean value (true or false). The value is stored as "yes" or "no" strings.

If the property value can be an expression, then value can be a string that takes the form:

defaultvalue~t DataWindowexpression

where:

  • Defaultvalue is any value that is allowed for property.

  • DataWindowexpression is an expression that can include names of controls in the DataWindow and DataWindow expression functions.

  • Defaultvalue and DataWindowexpression are separated by a tab character (~t).

For examples of DataWindow expressions, see Using DataWindow expressions as property values.


Datatype

Any. The datatype of the expression is Any, but actual data is a string.

For more information about the expression's datatype, see Datatypes of DataWindow property expressions in PowerBuilder.

Examples

Example 1 Boolean property values

In this statement, the boolean value false is stored as the string "no":

dw_1.Object.DataWindow.ReadOnly = false

This statement displays the value of the ReadOnly property (either "yes" or "no") in the StaticText st_status:

st_status.Text = dw_1.Object.DataWindow.ReadOnly

When you test the value of a property in a relational expression, you must compare your test value to the stored values. For ReadOnly, stored values are yes or no, not boolean true or false:

IF dw_1.Object.DataWindow.Readonly = 'yes' THEN

This statement fails because the expression is not boolean:

IF dw_1.Object.DataWindow.Readonly THEN // Not valid

Example 2

Valid values for the Visible property are 0 and 1. You can set the property to numbers, yes and no, or true and false. Therefore, these three statements are equivalent:

dw_1.Object.street.Visible = false
dw_1.Object.street.Visible = "NO"
dw_1.Object.street.Visible = 0

Example 3

This example tests whether the X property contains a constant (which can be converted to a number) or a DataWindow expression. The code assigns a default value of 50 to the variable li_x, which remains the value if the property contains an expression the script cannot convert:

integer li_x
IF IsNumber( dw_1.Object.id.X ) THEN
      li_x = Integer( dw_1.Object.id.X )
ELSE
      li_x = 50
END IF

Example 4

This script sets the X property to a DataWindow expression. The expression causes IDs with values less than 10 to be indented:

string modstring, ls_x
ls_x = "50"
modstring = ls_x + "~t" + &
      "If(id > 10, " + ls_x + "," + &
      String(li_x + 20 ) + ")"
dw_1.Object.id.X = modstring

Example 5

This example makes three columns updatable and reports the value of the Update property in the StaticText st_status. The reported value is "yes", not true:

dw_1.Object.id.Update = true
dw_1.Object.street.Update = true
dw_1.Object.last_name.Update = true
 
st_status.Text = &
      "Updateable: id " + dw_1.Object.id.Update + &
      ", street " + dw_1.Object.street.Update + &
      ", last_name " + dw_1.Object.last_name.Update

Example 6

This example checks whether the id column is set up as a spin control. If so, it sets the spin range to 0 through 10:

IF dw_1.Object.id.EditMask.Spin = "yes" THEN
      dw_1.Object.id.EditMask.SpinRange = "0~~~~10"
END IF

Syntax for nested objects in DataWindow property expressions in PowerBuilder

Description

In PowerBuilder, DataWindow property expressions use additional Object keywords to refer to nested objects. Nested objects include composite or related nested reports and child DataWindows associated with DropDownDataWindow columns. Related nested and composite reports can include their own nested objects. You can extend the dot notation to refer to any level of nesting.

Syntax

dwcontrol.Object.nestedcontrolname { [row ] } .Object.dwcontrolname. 
   property { .property } { = value }

Argument

Description

dwcontrol

The name of the DataWindow control or child DataWindow in which you want to get or set properties.

Object

The Object keyword indicates that subsequent elements refer to the DataWindow object within dwcontrol.

nestedcontrolname

The name of a DropDownDataWindow column, nested report, or OLE Object control within the DataWindow object in dwcontrol.

About nested reports

A nested report can be one of a group of reports in the Composite presentation style or a nested report included in a base report, which is associated with a specific row.

row

When nestedcontrolname is a nested report in a base report, the number of the row the report is associated with

If the report is in a band other than the detail band, it is still associated with a row (see Usage below).

dwcontrolname

The name of a control within the nested DataWindow object. Possible values are DataWindow (for properties that apply to the whole DataWindow) or the name of a Button, Column, Computed field, Graph, GroupBox, Line, Oval, Picture, Rectangle, RoundRectangle, Report, TableBlob, or Text control.

If dwcontrolname is a column with the DropDownDataWindow style, a Report control, or an OLE Object control, you can specify an additional Object keyword and dwcontrolname to refer to properties of controls within the nested DataWindow object. You can specify Object.dwcontrolname as many times as needed to refer to a control in a deeply nested DataWindow object.

property

A property that applies to dwcontrolname. If the property requires additional qualifying properties, list the additional properties, separating them with a dot.

For lists of applicable properties, see the Property tables in DataWindow Object Properties

value

A string whose value is to be assigned to the property

For more information, see Basic syntax for DataWindow property expressions in PowerBuilder.


Datatype

Any. The datatype of the expression is Any, but the actual data is a string.

For more information about the expression's datatype, see Datatypes of DataWindow property expressions in PowerBuilder.

Usage

A nested report within a base report is usually in the detail band, and each instance of the report is associated with a row. The property expression must include a row number to identify which report to access. If the nested report is in a band other than detail, there may be only one or a few instances of the report, but it is still associated with a row. The expression must include a row number that has an instance of the report.

The following table lists the band and the row that is associated with the report:

If the report is in this band

This row is associated with the report

detail

The specified row.

header

The first row on the page. On screen, this is the first row visible in the DataWindow body.

footer

The last row on the page. On screen, this is the last row visible in the DataWindow body.

header.n (group header)

The first row of the group (where n is the group number).

trailer.n (group trailer)

The last row of the group (where n is the group number).

summary

The last row in the report.


Examples

Example 1

Suppose that a DataWindow has the Composite presentation style and includes a report called rpt_employee. The report includes a column emp_id. This expression gets the validation expression for the column:

string ls_valid
ls_valid = dw_composite.Object.rpt_employee.&
      Object.emp_id.Validation

Example 2

In a Composite DataWindow, one of the reports rpt_1 has a graph gr_1. This example turns on grid lines for the category axis of that graph. The example sets an instance variable to a default value of "not found". If the expression fails and triggers the Error event, the ExceptionSubstituteReturnValue! action causes the text "not found" to be returned so that the second assignment succeeds:

is_dwvalue = "not found"
dw_1.Object.rpt_1.Object.&
      gr_1.Category.MajorGridline = 5
st_status.Text = dw_1.Object.rpt_1.Object.&
      gr_1.Category.MajorGridline

The script for the Error event includes these lines:

action = ExceptionSubstituteReturnValue!
returnvalue = is_dwvalue

Example 3

Suppose that a DataWindow called dw_emp is a base report with employee information. The detail band includes a nested report of salary history called rpt_salary. This means there is a separate report with its own properties in each row.

The script checks whether the employee belongs to management (the value in the rank column in the base report is M). If so, the script assigns a DataWindow expression to the Color property of the salary column in the rpt_salary nested report. The expression highlights salaries that are over $60,000 in red.

Another statement sets the salary column's Mode property so the color change will be visible:

integer li_row
 
FOR li_row = 1 to RowCount( )
      IF dw_emp.Object.rank.Primary[li_row] = "M" THEN
 
       dw_emp.Object.rpt_salary[li_row].Object.&
         salary.Background.Color = &
         '255 ~t If(salary > 60000, 255, 0)'
 
       dw_emp.Object.rpt_salary[li_row].Object.&
         salary.Background.Mode = 0
 
      END IF
NEXT

Example 4

In this example there is a graph in the summary band of a base report called dw_emp. The graph is a nested report called rpt_graph_salaries. Although the graph is not related to a particular row, you still need to provide the row number associated with the summary band when you refer to its properties. This statement turns on autoscaling for the values axis:

dw_emp.Object.rpt_graph_salaries.Object.&
      gr_1.Values.AutoScale = 1

Example 5

If a column has a DropDownDataWindow edit style, there are properties that affect the column's appearance. Using nested object syntax, you can also change properties of the child DataWindow for the column. In this example, the DataWindow dw_gift allows a clerk at a nonprofit organization to record donations. The clerk can pick a standard donation amount from a drop-down DataWindow.

This example makes the drop-down DataWindow column called amount a required value and changes the display format for the dollars column in the child DataWindow:

dw_gift.Object.amount.dddw.Required = "Yes"
dw_gift.Object.amount.Object.dollars.Format = "$#,##0"