Modify
method (DataWindows)
Description
Modifies a DataWindow object by applying specifications, given as a
list of instructions, that change the DataWindow object’s
definition.
You can change appearance, behavior, and database information for
the DataWindow object by changing the values of properties. You can add
and remove controls from the DataWindow object by providing specifications
for the controls.
Applies to
|
DataWindow type |
Method applies to |
|---|---|
|
PowerBuilder |
DataWindow control, DataWindowChild object, DataStore |
Syntax
PowerBuilder
|
1 |
string dwcontrol.Modify ( string modstring ) |
|
Argument |
Description |
|---|---|
|
dwcontrol |
A reference to a DataWindow control, DataStore, or |
|
modstring |
A string whose value is the specifications for the |
Return value
Returns the empty string (“”) if it succeeds and an error message if
an error occurs. The error message takes the form “Line n Column
n incorrect syntax”. The character columns are counted from the beginning
of the compiled text of modstring.
If any argument’s value is null, in PowerBuilder and JavaScript the
method returns null.
Usage
Modify lets you make many of the same settings in a script that you
would make in the DataWindow painter. Typical uses for Modify are:
-
Changing colors, text settings, and other appearance settings of
controls -
Changing the update status of different tables in the DataWindow
so that you can update more than one table -
Modifying the WHERE clause of the DataWindow object’s SQL SELECT
statement -
Turning on Query mode or Prompt For Criteria so users can
specify the data they want -
Changing the status of Retrieve Only As Needed
-
Changing the data source of the DataWindow object
-
Controlling the Print Preview display
-
Deleting and adding controls (such as lines or bitmaps) in the
DataWindow object
Each of these uses is illustrated in the Examples for this
method.
You can use three types of statements in modstring to modify a
DataWindow object.
|
Statement type |
What it does |
|---|---|
|
CREATE control (settings) |
Adds control to the DataWindow object (such as text, Control cannot be an OLE Object control. You |
|
DESTROY [COLUMN] control |
Removes control from the DataWindow object. When |
|
controlname.property=value |
Changes the value of property to value. Properties Depending on the
|
Object names
The DataWindow painter automatically gives names to all controls. In
previous versions, it named only columns and column labels, and to
describe and modify properties of other controls easily, you had to name
them.
Expressions for Modify
When you specify an expression for a DataWindow property, the
expression has the format:
|
1 |
defaultvalue~tDataWindowpainterexpression |
Defaultvalue is a value that can be converted to the appropriate
datatype for the property. It is followed by a tab (~t).
DataWindowpainterexpression is an expression that can use any
DataWindow painter function. The expression must also evaluate to the
appropriate datatype for the property. When you are setting a column’s
property, the expression is evaluated for each row in the DataWindow,
which allows you to vary the display based on the data.
A typical expression uses the If function:
|
1 |
'16777215 ~t If(emp_status=~~'A~~',255,16777215)' |
To use that expression in a modstring, specify the following
(entered as a single line):
|
1 2 |
modstring = "emp_id.Color='16777215 ~t If(emp_status=~~'A~~',255,16777215)'" |
Not all properties accept expressions. For details on each property,
see DataWindow Object
Properties.
Quotes and tildes
Because Modify’s argument is a string, which can include other
strings, you need to use special syntax to specify quotation marks. To
specify that a quotation mark be used within the string rather than match
and end a previously opened quote, you can either specify the other style
of quote (single quotes nested with double quotes) or precede the
quotation mark with a tilde (~).
For another level of nesting, the string itself must specify ~”, so
you must include ~~ (which specifies a tilde) followed by ~” (which
specifies a quote). For example, another way to type the modstring shown
above (entered as a single line) is:
|
1 2 |
modstring = "emp_id.Color=~"16777215 ~t If(emp_status=~~~"A~~~",255,16777215)~"" |
For more information about quotes and tildes, see the section called “Standard datatypes” in PowerScript Reference.
Building a modstring with
variables
To use variable data in modstring, you can build the string using
variables in your program. As you concatenate sections of modstring, make
sure quotes are included in the string where necessary. For example, the
following code builds a modstring similar to the one above, but the
default color value and the two color values in the If function are
calculated in the script. Notice how the single quotes around the
expression are included in the first and last pieces of the string:
|
1 2 3 4 5 6 7 8 |
red_amount = Integer(sle_1.Text) modstring = "emp_id.Color='" + & String(RGB(red_amount, 255, 255)) + & "~tIf(emp_status=~~'A~~'," + & String(RGB(255, 0, 0)) + & "," + & String(RGB(red_amount, 255, 255)) + & ")'" |
The following is a simpler example without the If function. You do
not need quotes around the value if you are not specifying an expression.
Here the String and RGB functions produce in a constant value in the
resulting modstring:
|
1 2 |
modstring = "emp_id.Color=" + & String(RGB(red_amount, 255, 255)) |
You can set several properties with a single call to Modify by
including each property setting in modstring separated by spaces. For
example, assume the following is entered on a single line in the script
editor:
|
1 2 3 |
rtn = dw_1.Modify("emp_id.Font.Italic=0 oval_1.Background.Mode=0 oval_1.Background.Color=255") |
However, it is easier to understand and debug a script in which each
call to Modify sets one property.
Debugging tip
If you build your modstring and store it in a variable that is the
argument for Modify, you can look at the value of the variable in Debug
mode. When Modify’s error message reports a column number, you can count
the characters as you look at the compiled modstring.
Modifying a WHERE clause
For efficiency, use Modify instead of SetSQLSelect to modify a
WHERE clause. Modify is faster because it does not verify the syntax and
does not change the update status of the DataWindow object. However,
Modify is more susceptible to user error. SetSQLSelect modifies the
syntax twice (when the syntax is modified and when the retrieve
executes) and affects the update status of the DataWindow object.
PowerBuilder already includes many functions for modifying a
DataWindow. Before using Modify, check the list of DataWindow functions in
Objects and Controls to see if a function exists for
making the change. Many of these functions are listed in the See also
section.
Modify is for modifying the properties of a DataWindow object and
its internal controls. You can set properties of the DataWindow
control that contains the object using standard dot notation. For example,
to put a border on the control, specify:
|
1 |
dw_1.Border = true |
Examples
These examples illustrate the typical uses listed in the Usage
section. The examples use PowerScript. For a discussion of Modify and
nested quotation marks in JavaScript, see Accessing DataWindow Object Properties in
Code
Changing colors
The effect of setting the Color property depends on the control you
are modifying. To set the background color of the whole DataWindow object,
use the following syntax:
|
1 |
dwcontrolname.Modify ( "DataWindow.Color='long'" ) |
To set the text color of a column or a text control, use similar
syntax:
|
1 |
dwcontrolname.Modify ( "controlname.Color='long'" ) |
To set the background color of a column or other control, use the
following syntax to set the mode and color. Make sure the mode is
opaque:
|
1 2 3 |
dwcontrolname.Modify ( "controlname.Background.Mode= & '<0 - Opaque, 1 - Transparent>'") dwcontrolname.Modify ( "controlname.Background.Color='long'" ) |
The following examples use the syntaxes shown above to set the
colors of various parts of the DataWindow object.
This statement changes the background color of the DataWindow
dw_cust to red:
|
1 |
dw_cust.Modify("DataWindow.Color = 255") |
This statement causes the DataWindow dw_cust to display the text of
values in the salary column in red if they exceed 90,000 and in green if
they do not:
|
1 2 |
dw_cust.Modify( & "salary.Color='0~tIf(salary>90000,255,65280)'") |
This statement nests one If function within another to provide three
possible colors. The setting causes the DataWindow dw_cust to display the
department ID in green if the ID is 200, in red if it is 100, and in black
if it is neither:
|
1 2 |
dw_cust.Modify("dept_id.Color='0~t " & + "If(dept_id=200,65380,If(dept_id=100,255,0))'") |
The following example uses a complex expression with nested If
functions to set the background color of the salary column according to
the salary values. Each portion of the concatenated string is shown on a
separate line. See the pseudocode in the comments for an explanation of
what the nested If functions do. The example also sets the background mode
to opaque so that the color settings are visible.
The example includes error checking, which displays Modify’s error
message, if any:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
string mod_string, err long color1, color2, color3, default_color err = dw_emp.Modify("salary.Background.Mode=0") IF err <> "" THEN MessageBox("Status", & "Change to Background Mode Failed " + err) RETURN END IF /* Pseudocode for mod_string: If salary less than 10000, set the background to red. If salary greater than or equal to 10000 but less than 20000, set the background to blue. If salary greater than or equal to 20000 but less than 30000, set the background color to green. Otherwise, set the background color to white, which is also the default. */ color1 = 255 //red color2 = 16711680 //blue color3 = 65280 //green default_color = 16777215//white mod_string = & "salary.Background.Color = '" & + String(default_color) & + "~tIf(salary < 10000," & + String(color1) & + ",If(salary < 20000," & + String(color2) & + ",If(salary < 30000," & + String(color3) & + "," & + String(default_color) & + ")))'" err = dw_emp.Modify(mod_string) IF err <> "" THEN MessageBox("Status", & "Change to Background Color Failed " + err) RETURN END IF |
This example sets the text color of a RadioButton column to the
value of color1 (red) if the column’s value is Y; otherwise, the text is
set to black. As above, each portion of the concatenated string is shown
on a separate line:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
integer color1, default_color string mod_string, err color1 = 255 //red default_color = 0 //black mod_string = "yes_or_no.Color ='" & + String(default_color) & + "~tif(yes_or_no=~~'Y~~'," & + String(color1) & + "," & + String(default_color) & + ")'" err = dw_emp.Modify(mod_string) IF err <> "" THEN MessageBox("Status", & "Modify to Text Color " & + "of yes_or_no Failed " + err) RETURN END IF |
Changing displayed text
To set the text of a text control, the next two examples use this
syntax:
|
1 |
dwcontrolname.Modify ( "textcontrolname.Text='string'" ) |
This statement changes the text in the text control Dept_t in the
DataWindow dw_cust to Dept:
|
1 |
dw_cust.Modify("Dept_t.Text='Dept'") |
This statement sets the displayed text of dept_t in the DataWindow
dw_cust to Marketing if the department ID is greater than 201; otherwise
it sets the text to Finance:
|
1 2 |
dw_cust.Modify("dept_t.Text='none~t " + & "If(dept_id > 201,~'Marketing~',~'Finance~')'") |
Updating more than one table
An important use of Modify is to make it possible to update more
than one table from one DataWindow object. The following script updates
the table that was specified as updatable in the DataWindow painter; then
it uses Modify to make the other joined table updatable and to specify the
key column and which columns to update. This technique eliminates the need
to create multiple DataWindow objects or to use embedded SQL statements to
update more than one table.
In this example, the DataWindow object joins two tables: department
and employee. First department is updated, with status flags not reset.
Then employee is made updatable and is updated. If all succeeds, the
Update command resets the flags and COMMIT commits the changes. Note that
to make the script repeatable in the user’s session, you must add code to
make department the updatable table again:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
integer rc string err /* The SELECT statement for the DataWindow is: SELECT department.dept_id, department.dept_name, employee.emp_id, employee.emp_fname, employee.emp_lname FROM department, employee ; */ // Update department, as set up in the DW painter rc = dw_1.Update(true, false) IF rc = 1 THEN //Turn off update for department columns. dw_1.Modify("department_dept_name.Update = No") dw_1.Modify("department_dept_id.Update = No") dw_1.Modify("department_dept_id.Key = No") // Make employee table updatable. dw_1.Modify( & "DataWindow.Table.UpdateTable = ~"employee~"") //Turn on update for desired employee columns. dw_1.Modify("employee_emp_id.Update = Yes") dw_1.Modify("employee_emp_fname.Update = Yes") dw_1.Modify("employee_emp_lname.Update = Yes") dw_1.Modify("employee_emp_id.Key = Yes") //Then update the employee table. rc = dw_1.Update() IF rc = 1 THEN COMMIT USING SQLCA; ELSE ROLLBACK USING SQLCA; MessageBox("Status", & + "Update of employee table failed. " & + "Rolling back all changes.") END IF ELSE ROLLBACK USING SQLCA; MessageBox("Status", & + "Update of department table failed. " & + "Rolling back changes to department.") END IF |
Adding a WHERE clause
The following scripts dynamically add a WHERE clause to a DataWindow
object that was created with a SELECT statement that did not include a
WHERE clause. (Since this example appends a WHERE clause to the original
SELECT statement, additional code would be needed to remove a where clause
from the original SELECT statement if it had one.) This technique is
useful when the arguments in the WHERE clause might change at execution
time.
The original SELECT statement might be:
|
1 |
SELECT employee.emp_id, employee.l_name FROM employee |
Presumably, the application builds a WHERE clause based on the
user’s choices. The WHERE clause might be:
|
1 |
WHERE emp_id > 40000 |
The script for the window’s Open event stores the original
SELECT statement in original_select, an instance variable:
|
1 2 3 |
dw_emp.SetTransObject(SQLCA) original_select = & dw_emp.Describe("DataWindow.Table.Select") |
The script for a CommandButton’s Clicked event attaches a
WHERE clause stored in the instance variable where_clause to
original_select and assigns it to the DataWindow’s Table.Select
property:
|
1 2 3 4 5 6 7 8 9 10 |
string rc, mod_string mod_string = "DataWindow.Table.Select='" & + original_select + where_clause + "'" rc = dw_emp.Modify(mod_string) IF rc = "" THEN dw_emp.Retrieve( ) ELSE MessageBox("Status", "Modify Failed" + rc) END IF |
Quotes inserted in the DataWindow painter
For SQL Anywhere and Oracle, the DataWindow painter puts double
quotes around the table and column name (for example, SELECT
“EMPLOYEE”.”EMP_LNAME”). Unless you have removed the quotes, the sample
WHERE clause must also use these quotes. For example:
|
1 2 3 4 |
where_clause = & " where ~~~"EMPLOYEE~~~".~~~"SALARY~~~" > 40000" |
Query mode
Query mode provides an alternate view of a DataWindow in which the
user specifies conditions for selecting data. PowerBuilder builds the
WHERE clause based on the specifications. When the user exits query mode,
you can retrieve data based on the modified SELECT statement.
In this example, a window that displays a DataWindow control has a
menu that includes a selection called Select Data. When the user chooses
it, its script displays the DataWindow control in query mode and checks
the menu item. When the user chooses it again, the script turns query mode
off and retrieves data based on the new WHERE clause specified by the user
through query mode. The script also makes a CheckBox labeled Sort data
visible, which turns query sort mode on and off.
The script for the Select Data menu item is:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
string rtn IF m_selectdata.Checked = false THEN // Turn on query mode so user can specify data rtn = dw_1.Modify("DataWindow.QueryMode=YES") IF rtn = "" THEN // If Modify succeeds, check menu to show // Query mode is on and display sort CheckBox This.Check() ParentWindow.cbx_sort.Show() ELSE MessageBox("Error", & "Can't access query mode to select data.") END IF ELSE // Turn off Query mode and retrieve data // based on user's choices rtn = dw_1.Modify("DataWindow.QueryMode=NO") IF rtn = "" THEN // If Modify succeeds, uncheck menu to show // Query mode is off, hide the sort // CheckBox, and retrieve data This.UnCheck() ParentWindow.cbx_sort.Hide() dw_1.AcceptText() dw_1.Retrieve() ELSE MessageBox("Error", & "Failure exiting query mode.") END IF END IF |
A simple version of the script for Clicked event of the Sort data
CheckBox follows. You could add code as shown in the Menu script above to
check whether Modify succeeded:
|
1 2 3 4 5 |
IF This.Checked = true THEN dw_1.Modify("DataWindow.QuerySort=YES") ELSE dw_1.Modify("DataWindow.QuerySort=NO") END IF |
For details on how you or the user specifies information in query
mode, see the section called “Providing
query ability to users” in DataWindow Programmers Guide.
DataWindow presentation styles
You cannot use QueryMode and QuerySort with DataWindow objects
that use any of the following presentation styles: N-Up, Label,
Crosstab, RichText, and Graph.
Prompt for criteria
is another way of letting the user specify retrieval criteria. You
set it on a column-by-column basis. When a script retrieves data,
PowerBuilder displays the Specify Retrieval Criteria window, which gives
the user a chance to specify criteria for all columns that have been
set.
In a script that is run before you retrieve data, for example, in
the Open event of the window that displays the DataWindow control, the
following settings would make the columns emp_name, emp_salary, and
dept_id available in the Specify Retrieval Criteria dialog when the
Retrieve method is called:
|
1 2 3 |
dw_1.Modify("emp_name.Criteria.Dialog=YES") dw_1.Modify("emp_salary.Criteria.Dialog=YES") dw_1.Modify("dept_id.Criteria.Dialog=YES") |
There are other Criteria properties that affect both query mode and
prompt for criteria. For details, see the Criteria DataWindow object
property in DataWindow Object
Properties
Retrieve as needed
In this example, the DataWindow object has been set up with Retrieve
Only As Needed selected. When this is on, PowerBuilder retrieves enough
rows to fill the DataWindow, displays them quickly, then waits for the
user to try to display additional rows before retrieving more rows. If you
want the fast initial display but do not want to leave the cursor open on
the server, you can turn off Retrieve Only As Needed with Modify.
After you have determined that enough rows have been retrieved, the
following code in the RetrieveRow event script changes the
Retrieve.AsNeeded property, which forces the rest of the rows to be
retrieved:
|
1 |
dw_1.Modify("DataWindow.Retrieve.AsNeeded=NO") |
Changing the data source
This example changes the data source of a DataWindow object from a
SQL SELECT statement to a stored procedure. This technique works only if
the result set does not change (that is, the number, type, and order of
columns is the same for both sources).
When you define the DataWindow object, you must define all possible
DataWindow retrieval arguments. In this example, the SELECT statement
defined in the painter has three arguments, one of type string, one of
type number, and one of type date. The stored procedure has two arguments,
both of type string. So, in the painter, you need to define four
DataWindow arguments, two of type string, one of type number, and one of
type date. (Note that you do not have to use all the arguments you
define.)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
string rc, mod_string, name_str = "Watson" integer dept_num = 100 // Remove the DataWindow's SELECT statement Dw_1.Modify("DataWindow.Table.Select = ''") // Set the Procedure property to your procedure mod_string = "DataWindow.Table.Procedure = & '1 execute dbo.emp_arg2;1 @dept_id_arg & = :num_arg1, @lname_arg = :str_arg1'" rc = dw_1.Modify(mod_string) // If change is accepted, retrieve data IF rc = "" THEN dw_1.Retrieve(dept_num, name_str) ELSE MessageBox("Status", & "Change to DW Source Failed " + rc) END IF |
Replacing a DropDownDataWindow object
Suppose you use Modify to replace one DropDownDataWindow object
with another; for example:
|
1 2 3 4 |
dw_parent.Modify(dept_id.dddw.name= & d_dddw_empsal_by_dept ) |
PowerBuilder compares the two DataWindow objects and reuses the
original result set if the number of columns and their datatypes match.
The display and data value column names must exist in the data object
SQL statements for both objects. If there are any differences,
PowerBuilder will re-retrieve the data.
Deleting and adding controls in the DataWindow
object
This statement deletes a bitmap control called logo from the
DataWindow dw_cust:
|
1 |
dw_cust.Modify("destroy logo") |
This statement deletes the column named salary from the DataWindow
dw_cust. Note that this example includes the keyword column, so the column
in the DataWindow and the data are both deleted:
|
1 |
dw_cust.Modify("destroy column salary") |
This example adds a rectangle named rect1 to the header area of the
DataWindow dw_cust (with the value of modstring entered as a single
line):
|
1 2 3 4 5 |
string modstring modstring = 'create rectangle(Band=background X="206" Y="6" height="69" width="1363" brush.hatch="6" brush.color="12632256" pen.style="0" pen.width="14" pen.color="268435584" background.mode="2" background.color="-1879048064" name=rect1 )' dw_cust.Modify(modstring) |
These statements add a bitmap named logo to the header area for
grouping level 1 in the DataWindow dw_cust (with the value of modstring
entered as a single line):
|
1 2 3 4 5 |
string modstring modstring = 'create bitmap(band=footer x="37" y="12" height="101" width="1509" filename="C:PBBEACH.BMP" border="0" name=bmp1 )' dw_cust.Modify(modstring) |
Syntax for creating controls
To create a control, you must provide DataWindow syntax. The
easiest way to get correct syntax for all the necessary properties is to
paint the control in the DataWindow painter and export the syntax to a
file. Then you make any desired changes and put the syntax in your
script, as shown above. This is the only way to get accurate syntax for
complex controls like graphs.
See also