Find method (DataWindows)
Description
Finds the next row in a DataWindow or DataStore in which data
meets a specified condition.
Controls
DataWindow type |
Method applies to |
---|---|
PowerBuilder |
DataWindow control, DataWindowChild object, DataStore |
Web |
Server component |
Web ActiveX |
DataWindow control, DataWindowChild object |
Syntax
[PowerBuilder and Web DataWindow server component]
1 |
long <span>dwcontrol</span><span>.</span><span>Find </span>( string <span>expression</span>, long <span>start</span>, long <span>end </span>) |
[Web DataWindow and Web ActiveX]
1 |
number <span>dwcontrol</span><span>.Find </span>( string <span>expression</span>, number <span>start</span>, number <span>end</span> ) |
Argument |
Description |
---|---|
dwcontrol |
A reference to the DataWindow control, |
expression |
A string whose value is a boolean expression |
start |
A value identifying the row location |
end |
A value identifying the row location |
Return Values
Returns the number of the first row that meets the search
criteria within the search range. Returns 0 if no rows are found
and one of these negative numbers if an error occurs:
-
–1 General
error -
–5 Bad argument
If any argument’s value is null, in PowerBuilder
and JavaScript the method returns null.
Usage
For use with a RichTextEdit control or presentation style,
see Find in the PowerScript Reference.
The search is case sensitive. When you compare text to a value
in a column, the case must match.
When the Find expression includes quotes
If the text you want to find includes quotes, you must treat
the nested quote as doubly nested, because the DataWindow parses
the string twice before the Find method uses
it. Therefore, you cannot simply alternate double and single quotes, as
you can in most strings.
For example, to find the name O’Connor, the Find
expression can be:
"O~~~'Connor"
(3
tildes and single quote) or "O~~~~~"Connor"
(5
tildes and double quote)
but not:
"O'Connor"
or "O~"OConnor"
When the last row satisfies the search criteria
If you use Find in a loop that searches
through all rows, you may end up with an endless loop if the last
row satisfies the search criteria. When the start value
becomes greater than end, the search reverses
direction and Find would always succeed, resulting in an endless
loop.
To solve this problem, you could make the end value
1 greater than the number of rows (see the examples). Another approach,
shown below, would be to test within the loop whether the current
row is greater than the row count and, if so, exit. This PowerBuilder
code illustrates how:
1 |
long ll_find = 1, ll_end |
1 |
ll_end = dw_main.RowCount() |
1 |
ll_find = dw_main.Find(<span>searchstr</span>, ll_find, ll_end) |
1 |
DO WHILE ll_find > 0 |
1 |
... // Collect found row |
1 |
ll_find++ |
1 |
// Prevent endless loop |
1 |
IF ll_find > ll_end THEN EXIT |
1 |
ll_find = dw_main.Find(<span>searchstr</span>, ll_find, ll_end) |
1 |
LOOP |
Examples
This statement searches for the first row in dw_status
in which the value of the emp_salary column is greater
than 100,000. The search begins in row 3 and continues until it
reaches the last row in dw_status:
1 |
long ll_found |
1 |
ll_found = dw_status.<span>Find</span>("emp_salary > 100000", & |
1 |
3, dw_status.RowCount()) |
To test values in more than one column, use boolean
operators to join conditional expressions. The following statement
searches for the employee named Smith whose salary exceeds 100,000:
1 |
long ll_found |
1 |
ll_found = dw_status.<span>Find</span>( & |
1 |
<span></span> "emp_lname = 'Smith' and emp_salary > 100000", & |
1 |
1, dw_status.RowCount()) |
These statements search for the first row in dw_emp
that matches the value that a user entered in the SingleLineEdit
called Name (note the single quotes embedded in the search expression
around the name):
1 |
string ls_lname_emp |
1 |
long ll_nbr, ll_foundrow |
1 |
1 |
ll_nbr = dw_emp.RowCount() |
1 |
1 |
// Remove leading and trailing blanks. |
1 |
ls_lname_emp = Trim(sle_Name.Text) |
1 |
1 |
ll_foundrow = dw_emp.<span>Find</span>( & |
1 |
"emp_lname = '" + ls_lname_emp + "'", 1, ll_nbr) |
This script excerpt finds the first row that has
a null value in emp_id. If no null is found, the script
updates the DataWindow object. If a null is found, it displays a
message:
1 |
IF dw_status.AcceptText() = 1 THEN |
1 |
IF dw_status.<span>Find</span>("IsNull(emp_id)", & |
1 |
1, dw_status.RowCount()) > 0 THEN |
1 |
MessageBox("Caution", "Cannot Update") |
1 |
ELSE |
1 |
dw_status.Update() |
1 |
END IF |
1 |
END IF |
The following script attached to a Find Next command
button searches for the next row that meets the specified criteria
and scrolls to that row. Each time the button is clicked, the number
of the found row is stored in the instance variable il_found.
The next time the user clicks Find Next, the search continues from
the following row. When the search reaches the end, a message tells
the user that no row was found. The next search begins again at
the first row.
Note that although the search criteria are hard-coded here,
a more realistic scenario would include a Find button that prompts
the user for search criteria. You could store the criteria in an
instance variable, which Find Next could use:
1 |
long ll_row |
1 |
1 |
// Get the row num. for the beginning of the search |
1 |
// from the instance variable, il_found |
1 |
ll_row = il_found |
1 |
1 |
// Search using predefined criteria |
1 |
ll_row = dw_main.<span>Find</span>( & |
1 |
"item_id = 3 or item_desc = 'Nails'", & |
1 |
ll_row, dw_main.RowCount()) |
1 |
IF ll_row > 0 THEN |
1 |
// Row found, scroll to it and make it current |
1 |
dw_main.ScrollToRow(ll_row) |
1 |
ELSE |
1 |
// No row was found |
1 |
MessageBox("Not Found", "No row found.") |
1 |
END IF |
1 |
1 |
// Save the number of the next row for the start |
1 |
// of the next search. If no row was found, |
1 |
// ll_row is 0, making il_found 1, so that |
1 |
// the next search begins again at the beginning |
1 |
il_found = ll_row + 1 |
This example searches all the rows in dw_main
and builds a list of the names that include a lowercase a. Note
that the end value of the search is one greater than the row count,
avoiding an infinite loop if the name in the last row satisfies
the search:
1 |
long ll_find, ll_end |
1 |
string ll_list |
1 |
1 |
// The end value is one greater than the row count |
1 |
ll_end = dw_main.RowCount() + 1 |
1 |
ll_find = 1 |
1 |
1 |
ll_find = dw_main.Find("Pos(last_name,'a') > 0", & |
1 |
ll_find, ll_end) |
1 |
DO WHILE ll_find > 0 |
1 |
//collect names |
1 |
ll_list = ll_list + '~r' & |
1 |
+ dw_main.GetItemString(ll_find,'last_name') |
1 |
1 |
// Search again |
1 |
ll_find++ |
1 |
ll_find = dw_main.Find("Pos(last_name,'a') & |
1 |
> 0", ll_find, ll_end ) |
1 |
LOOP |