To simulate user actions over the QuantumGrid control, you may need to locate the row that contains the data that you are going to work with. This topic describes several approaches that can be used to locate records in the QuantumGrid control.
You can locate the desired record using any of the approaches described below in this topic. At the end of the topic we will also compare these approaches.
In order for TestComplete to be able to perform these actions, the following conditions must be met:
When testing Developer Express QuantumGrid controls, use specific methods and properties of the corresponding |
Searching by Iterating Through Grid Rows
A general approach for searching within the grid control implies that you iterate through the grid rows in a loop and on each iteration check whether the row meets the specified condition, for example, if it holds a specific value in a particular column. The following example demonstrates how you can locate a particular row by iterating through the grid rows:
Example
JavaScript
function Main ()
{
var p, Grid, ColumnName, ColumnValue, RowIndex;
// Obtain the grid object
p = Sys.Process("MySampleApp");
Grid = p.VCLObject("FormName").VCLObject("GridName");
// Locate a row
ColumnName = "MyColumn";
ColumnValue = "MyValue";
RowIndex = FindRow (Grid, ColumnName, ColumnValue);
// Check if the row was found
if (RowIndex != -1)
{
Grid.ClickCell(RowIndex, ColumnName);
Log.Message("Row index: " + RowIndex);
}
else
Log.Error("Row was not found.");
}
function FindRow (Level, ColumnId, Value, ViewId)
{
// If the ViewId parameter is not specified,
// initialize it with the default value
if (strictEqual(ViewId, undefined))
ViewId = 0;
// Iterate through the rows
for (let i=0; i<Level.wRowCount(ViewId); i++)
// Check the cell value in the specified column
if (equal(Level.wValue(i, ColumnId, ViewId), Value))
return i; // Row is found
return -1; // Row is not found
}
JScript
function Main ()
{
var p, Grid, ColumnName, ColumnValue, RowIndex;
// Obtain the grid object
p = Sys.Process("MySampleApp");
Grid = p.VCLObject("FormName").VCLObject("GridName");
// Locate a row
ColumnName = "MyColumn";
ColumnValue = "MyValue";
RowIndex = FindRow (Grid, ColumnName, ColumnValue);
// Check if the row was found
if (RowIndex != -1)
{
Grid.ClickCell(RowIndex, ColumnName);
Log.Message("Row index: " + RowIndex);
}
else
Log.Error("Row was not found.");
}
function FindRow (Level, ColumnId, Value, ViewId)
{
// If the ViewId parameter is not specified,
// initialize it with the default value
if (typeof(ViewId) == "undefined")
ViewId = 0;
// Iterate through the rows
for (var i=0; i<Level.wRowCount(ViewId); i++)
// Check the cell value in the specified column
if (Level.wValue(i, ColumnId, ViewId) == Value)
return i; // Row is found
return -1; // Row is not found
}
Python
def Main ():
# Obtain the grid object
p = Sys.Process("MySampleApp")
Grid = p.VCLObject("FormName").VCLObject("GridName")
# Locate a row
ColumnName = "MyColumn"
ColumnValue = "MyValue"
RowIndex = FindRow (Grid, ColumnName, ColumnValue)
# Check if the row was found
if (RowIndex != -1):
Grid.ClickCell(RowIndex, ColumnName)
Log.Message("Row index: " + RowIndex)
else:
Log.Error("Row was not found.")
def FindRow (Level, ColumnId, Value, ViewId):
# If the ViewId parameter is not specified,
# initialize it with the default value
if (typeof(ViewId) == "undefined"):
ViewId = 0
# Iterate through the rows
for i in range(0, Level.wRowCount(ViewId)-1):
# Check the cell value in the specified column
if (Level.wValue(i, ColumnId, ViewId) == Value):
return i # Row is found
return -1 # Row is not found
VBScript
Sub Main
Dim p, Grid, ColumnName, ColumnValue, RowIndex
' Obtain the grid object
Set p = Sys.Process("MySampleApp")
Set Grid = p.VCLObject("FormName").VCLObject("GridName")
' Locate a row
ColumnName = "MyColumn"
ColumnValue = "MyValue"
RowIndex = FindRow (Grid, ColumnName, ColumnValue, 0)
' Check if the row was found
If RowIndex <> -1 Then
Call Grid.ClickCell(RowIndex, ColumnName)
Log.Message("Row index: " & RowIndex)
Else
Log.Error("Row was not found.")
End If
End Sub
Function FindRow (Level, ColumnId, Value, ViewId)
Dim i
' Iterate through the rows
For i = 0 to Level.wRowCount(ViewId)-1
' Check the cell value in the specified column
If Level.wValue(i, ColumnId, ViewId) = Value Then
FindRow = i ' Row is found
Exit Function
End If
Next
FindRow = -1 ' Row is not found
End Function
DelphiScript
function FindRow (Level, ColumnId, Value, ViewId : OleVariant = 0);
var i : OleVariant;
begin
// Iterate through the rows
for i := 0 to Level.wRowCount[ViewId]-1 do
// Check the cell value in the specified column
if Level.wValue[i, ColumnId, ViewId] = Value then
begin
Result := i; // Row is found
Exit;
end;
Result := -1; // Row is not found
end;
procedure Main;
var p, Grid, ColumnName, ColumnValue, RowIndex : OleVariant;
begin
// Obtain the grid object
p := Sys.Process('MySampleApp');
Grid := p.VCLObject('FormName').VCLObject('GridName');
// Locate a row
ColumnName := 'MyColumn';
ColumnValue := 'MyValue';
RowIndex := FindRow (Grid, ColumnName, ColumnValue);
// Check if the row was found
if RowIndex <> -1 then
begin
Grid.ClickCell(RowIndex, ColumnName);
Log.Message('Row index: ' + aqConvert.VarToStr(RowIndex));
end
else
Log.Error('Row was not found.');
end;
C++Script, C#Script
function Main ()
{
var p, Grid, ColumnName, ColumnValue, RowIndex;
// Obtain the grid object
p = Sys["Process"]("MySampleApp");
Grid = p["VCLObject"]("FormName")["VCLObject"]("GridName");
// Locate a row
ColumnName = "MyColumn";
ColumnValue = "MyValue";
RowIndex = SearchCellWithIncremental (Grid, null, ColumnName, ColumnValue);
// Check if the row was found
if (RowIndex != -1)
Log["Message"]("Row index: " + RowIndex);
else
Log["Error"]("Row was not found.");
}
// Searches for the row using the incremental search functionality
function SearchCellWithIncremental (Grid, View, ColumnId, SearchString)
{
var Column, RowIndex;
// Obtain the view object
if (View == null)
View = Grid["ActiveView"];
// Get the column object
Column = GetColumn (Grid, View, ColumnId);
// Activate the first row
View["DataController"]["GotoFirst"]();
// Search using the incremental search
View["DataController"]["Search"]["Locate"](Column["Index"], SearchString);
// Cancel the incremental search mode
View["DataController"]["Search"]["Cancel"]();
// Check if the search was successful
RowIndex = View["DataController"]["FocusedRowIndex"];
if (View["ViewData"]["Rows"](RowIndex)["DisplayTexts"](Column.Index) == SearchString)
{
// The cell was found; select it and return its row index
Column["Focused"] = true;
return RowIndex
}
else
return -1; // Row was not found
}
// Returns the column object by its caption or index
function GetColumn (Grid, View, ColumnId)
{
// Obtain the view object
if (View == null)
View = Grid["ActiveView"];
// Check type of the columnId parameter
if (aqObject["GetVarType"](ColumnId) == varOleStr)
{
// If ColumnId is a string,
// then search for the column by its caption
for (var i = 0; i < View["ColumnCount"]; i++)
if (View["GetColumn"](i)["Caption"] == ColumnId)
return View["GetColumn"](i); // Column is found
return null; // Column is not found
}
else
// If ColumnId is an integer,
// then search for column by its index
return View["GetColumn"](ColumnId);
}
Searching by Using the Incremental Search Feature
QuantumGrid controls include the incremental search functionality. When it is active, you can search for a row by focusing the desired column and typing the desired text. The grid will automatically locate the row containing the text you entered.
If the tested grid supports incremental search, then to search for a record, you can simulate user actions that will focus the desired column and then simulate keystrokes over the grid. The sample below demonstrates this approach.
Note: | The incremental search feature is activated by the OptionsBehavior.IncSearch property of a grid view. To enable the incremental search for a view, set the ViewObj.OptionsBehavior.IncSearch to True. If the tested grid only contains one level, you can use the GridObj.ActiveView.OptionsBehavior.IncSearch property. |
Example
JavaScript
function Main ()
{
var p, Grid, ColumnName, ColumnValue, RowIndex;
// Obtain the grid object
p = Sys.Process("MySampleApp");
Grid = p.VCLObject("FormName").VCLObject("GridName");
// Locate a row
ColumnName = "MyColumn";
ColumnValue = "MyValue";
RowIndex = SearchCellWithIncremental (Grid, null, ColumnName, ColumnValue);
// Check if the row was found
if (RowIndex != -1)
Log.Message ("Row index: " + RowIndex);
else
Log.Error ("Row was not found.");
}
// Searches for the row using the incremental search functionality
function SearchCellWithIncremental (Grid, View, ColumnId, SearchString)
{
var Column, RowIndex;
// Obtain the view object
if (strictEqual(View, null))
View = Grid.ActiveView;
// Get the column object
Column = GetColumn (Grid, View, ColumnId);
// Activate the first row
View.DataController.GotoFirst();
// Search using the incremental search
View.DataController.Search.Locate(Column.Index, SearchString);
// Cancel the incremental search mode
View.DataController.Search.Cancel();
// Check if the search was successful
RowIndex = View.DataController.FocusedRowIndex;
if (equal(View.ViewData.Rows(RowIndex).DisplayTexts(Column.Index), SearchString))
{
// The cell was found; select it and return its row index
Column.Focused = true;
return RowIndex
}
else
return -1; // Row was not found
}
// Returns the column object by its caption or index
function GetColumn (Grid, View, ColumnId)
{
// Obtain the view object
if (strictEqual(View, null))
View = Grid.ActiveView;
// Check type of the columnId parameter
if (equal(aqObject.GetVarType(ColumnId), varOleStr))
{
// If ColumnId is a string,
// then search for the column by its caption
for (let i = 0; i < View.ColumnCount; i++)
if (equal(View.GetColumn(i).Caption, ColumnId))
return View.GetColumn(i); // Column is found
return null; // Column is not found
}
else
// If ColumnId is an integer,
// then search for column by its index
return View.GetColumn(ColumnId);
}
JScript
function Main ()
{
var p, Grid, ColumnName, ColumnValue, RowIndex;
// Obtain the grid object
p = Sys.Process("MySampleApp");
Grid = p.VCLObject("FormName").VCLObject("GridName");
// Locate a row
ColumnName = "MyColumn";
ColumnValue = "MyValue";
RowIndex = SearchCellWithIncremental (Grid, null, ColumnName, ColumnValue);
// Check if the row was found
if (RowIndex != -1)
Log.Message ("Row index: " + RowIndex);
else
Log.Error ("Row was not found.");
}
// Searches for the row using the incremental search functionality
function SearchCellWithIncremental (Grid, View, ColumnId, SearchString)
{
var Column, RowIndex;
// Obtain the view object
if (View == null)
View = Grid.ActiveView;
// Get the column object
Column = GetColumn (Grid, View, ColumnId);
// Activate the first row
View.DataController.GotoFirst();
// Search using the incremental search
View.DataController.Search.Locate(Column.Index, SearchString);
// Cancel the incremental search mode
View.DataController.Search.Cancel();
// Check if the search was successful
RowIndex = View.DataController.FocusedRowIndex;
if (View.ViewData.Rows(RowIndex).DisplayTexts(Column.Index) == SearchString)
{
// The cell was found; select it and return its row index
Column.Focused = true;
return RowIndex
}
else
return -1; // Row was not found
}
// Returns the column object by its caption or index
function GetColumn (Grid, View, ColumnId)
{
// Obtain the view object
if (View == null)
View = Grid.ActiveView;
// Check type of the columnId parameter
if (aqObject.GetVarType(ColumnId) == varOleStr)
{
// If ColumnId is a string,
// then search for the column by its caption
for (var i = 0; i < View.ColumnCount; i++)
if (View.GetColumn(i).Caption == ColumnId)
return View.GetColumn(i); // Column is found
return null; // Column is not found
}
else
// If ColumnId is an integer,
// then search for column by its index
return View.GetColumn(ColumnId);
}
Python
def Main ():
# Obtain the grid object
p = Sys.Process("MySampleApp")
Grid = p.VCLObject("FormName").VCLObject("GridName")
# Locate a row
ColumnName = "MyColumn"
ColumnValue = "MyValue"
RowIndex = SearchCellWithIncremental (Grid, None, ColumnName, ColumnValue)
# Check if the row was found
if (RowIndex != -1):
Log.Message ("Row index: " + RowIndex)
else:
Log.Error ("Row was not found.")
# Searches for the row using the incremental search functionality
def SearchCellWithIncremental (Grid, View, ColumnId, SearchString):
# Obtain the view object
if (View == None):
View = Grid.ActiveView
# Get the column object
Column = GetColumn (Grid, View, ColumnId)
# Activate the first row
View.DataController.GotoFirst()
# Search using the incremental search
View.DataController.Search.Locate(Column.Index, SearchString)
# Cancel the incremental search mode
View.DataController.Search.Cancel()
# Check if the search was successful
RowIndex = View.DataController.FocusedRowIndex
if (View.ViewData.Rows(RowIndex).DisplayTexts(Column.Index) == SearchString):
# The cell was found select it and return its row index
Column.Focused = True
return RowIndex
else:
return -1 # Row was not found
# Returns the column object by its caption or index
def GetColumn (Grid, View, ColumnId):
# Obtain the view object
if (View == None):
View = Grid.ActiveView
# Check type of the columnId parameter
if (aqObject.GetVarType(ColumnId) == varOleStr):
# If ColumnId is a string,
# then search for the column by its caption
for i in range(0, View.ColumnCount-1):
if (View.GetColumn(i).Caption == ColumnId):
return View.GetColumn(i) # Column is found
return None # Column is not found
else:
# If ColumnId is an integer,
# then search for column by its index
return View.GetColumn(ColumnId)
VBScript
Sub Main_SearchByIncremental
Dim p, Grid, ColumnName, ColumnValue, RowIndex
' Obtain the grid object
Set p = Sys.Process("MySampleApp")
Set Grid = p.VCLObject("FormName").VCLObject("GridName")
' Locate a row
ColumnName = "MyColumn"
ColumnValue = "MyValue"
RowIndex = SearchCellWithIncremental (Grid, Nothing, ColumnName, ColumnValue)
' Check if the row was found
If RowIndex <> -1 Then
Log.Message("Row index: " & RowIndex)
Else
Log.Error ("Row was not found.")
End If
End Sub
' Searches for the row using the incremental search functionality
Function SearchCellWithIncremental (Grid, View, ColumnId, SearchString)
Dim Column, RowIndex
' Obtain the view object
If View Is Nothing Then
Set View = Grid.ActiveView
End If
' Get the column object
Set Column = GetColumn (Grid, View, ColumnId)
' Activate the first row
View.DataController.GotoFirst
' Search using the incremental search
Call View.DataController.Search.Locate(Column.Index, SearchString)
' Cancel the incremental search mode
View.DataController.Search.Cancel
' Check if the search was successful
RowIndex = View.DataController.FocusedRowIndex
If View.ViewData.Rows(RowIndex).DisplayTexts(Column.Index) = SearchString Then
' The cell was found. Select it and return its row index
Column.Focused = True
SearchCellWithIncremental = RowIndex
Else
SearchCellWithIncremental = -1 ' Row was not found
End If
End Function
' Returns the column object by its caption or index
Function GetColumn (Grid, View, ColumnId)
Dim i
' Obtain the view object
If View Is Nothing Then
Set View = Grid.ActiveView
End If
' Check type of the columnId parameter
If aqObject.GetVarType(ColumnId) = varOleStr Then
' If ColumnId is a string, search for the column by its caption
For i = 0 to View.ColumnCount-1
If View.GetColumn(i).Caption = ColumnId Then
Set GetColumn = View.GetColumn(i) ' Column id found
Exit Function
End If
Next
Set GetColumn = Nothing' Column is not found
Else
' If ColumnId is an integer, search for column by its index
Set GetColumn = View.GetColumn(ColumnId)
End If
End Function
DelphiScript
function SearchCellWithIncremental (Grid, View, ColumnId, SearchString); forward;
function GetColumn (Grid, View, ColumnId); forward;
procedure Main;
var p, Grid, ColumnName, ColumnValue, RowIndex : OleVariant;
begin
// Obtain the grid object
p := Sys.Process('MySampleApp');
Grid := p.VCLObject('FormName').VCLObject('GridName');
// Locate a row
ColumnName := 'MyColumn';
ColumnValue := 'MyValue';
RowIndex := SearchCellWithIncremental (Grid, nil, ColumnName, ColumnValue);
// Check if the row was found
if RowIndex <> -1 then
Log.Message('Row index: ' + aqConvert.VarToStr(RowIndex))
else
Log.Error ('Row was not found.');
end;
// Searches for the row using the incremental search functionality
function SearchCellWithIncremental (Grid, View, ColumnId, SearchString);
var Column, RowIndex;
begin
// Obtain the view object
if View = nil then
View := Grid.ActiveView;
// Get the column object
Column := GetColumn (Grid, View, ColumnId);
// Activate the first row
View.DataController.GotoFirst;
// Search using the incremental search
View.DataController.Search.Locate(Column.Index, SearchString);
// Cancel the incremental search mode
View.DataController.Search.Cancel;
// Check if the search was successful
RowIndex := View.DataController.FocusedRowIndex;
if View.ViewData.Rows[RowIndex].DisplayTexts[Column.Index] = SearchString then
begin
// The cell was found; select it and return its row index
Column.Focused := true;
Result := RowIndex
end
else
Result := -1; // Row was not found
end;
// Returns the column object by its caption or index
function GetColumn (Grid, View, ColumnId);
var i : OleVariant;
begin
// Obtain the view object
if View = nil then
View := Grid.ActiveView;
// Check type of the columnId parameter
if aqObject.GetVarType(ColumnId) = varOleStr then
begin
// If ColumnId is a string,
// then search for the column by its caption
for i := 0 to View.ColumnCount-1 do
if View.GetColumn(i).Caption = ColumnId then
begin
Result := View.GetColumn(i); // Column id found
Exit;
end;
Result := nil; // Column is not found
end
else
// If ColumnId is an integer,
// then search for column by its index
Result := View.GetColumn(ColumnId);
end;
C++Script, C#Script
function Main ()
{
var p, Grid, ColumnName, ColumnValue, RowIndex;
// Obtain the grid object
p = Sys["Process"]("MySampleApp");
Grid = p["VCLObject"]("FormName")["VCLObject"]("GridName");
// Locate a row
ColumnName = "MyColumn";
ColumnValue = "MyValue";
RowIndex = SearchCellWithIncremental (Grid, null, ColumnName, ColumnValue);
// Check if the row was found
if (RowIndex != -1)
Log["Message"]("Row index: " + RowIndex);
else
Log["Error"]("Row was not found.");
}
// Searches for the row using the incremental search functionality
function SearchCellWithIncremental (Grid, View, ColumnId, SearchString)
{
var Column, RowIndex;
// Obtain the view object
if (View == null)
View = Grid["ActiveView"];
// Get the column object
Column = GetColumn (Grid, View, ColumnId);
// Activate the first row
View["DataController"]["GotoFirst"]();
// Search using the incremental search
View["DataController"]["Search"]["Locate"](Column["Index"], SearchString);
// Cancel the incremental search mode
View["DataController"]["Search"]["Cancel"]();
// Check if the search was successful
RowIndex = View["DataController"]["FocusedRowIndex"];
if (View["ViewData"]["Rows"](RowIndex)["DisplayTexts"](Column.Index) == SearchString)
{
// The cell was found; select it and return its row index
Column["Focused"] = true;
return RowIndex
}
else
return -1; // Row was not found
}
// Returns the column object by its caption or index
function GetColumn (Grid, View, ColumnId)
{
// Obtain the view object
if (View == null)
View = Grid["ActiveView"];
// Check type of the columnId parameter
if (aqObject["GetVarType"](ColumnId) == varOleStr)
{
// If ColumnId is a string,
// then search for the column by its caption
for (var i = 0; i < View["ColumnCount"]; i++)
if (View["GetColumn"](i)["Caption"] == ColumnId)
return View["GetColumn"](i); // Column is found
return null; // Column is not found
}
else
// If ColumnId is an integer,
// then search for column by its index
return View["GetColumn"](ColumnId);
}
Which Approach to Choose
In the previous sections, we have described two variants of the searching procedure. One of these variants iterates through the rows of the grid and the other uses the incremental search functionality.
In general, incremental search provides a faster search. Since the search uses the cell’s display text, you do not have to be aware of the actual data type of grid cells; instead, you specify the text dispalyed in the desired cell. However, this kind of search cannot determine whether it has succeded or failed (in our example, we check this manually by analyzing the text in the row that became focused after the search). You can use the incremental search, for example, if you are sure that the grid contains a row with the sought-for text.
The approach that implies iterating through grid rows requires you to know the grid cells’s data types, because it analyzes cell values rather than their display text. This approach functions much slower than the incremental search, especially if the grid contains a large number of records. If you need better performance, you can implement a more effective search algorithm, for example, a binary search.
See Also
Working With Developer Express QuantumGrid
Iterating Through Rows in Developer Express QuantumGrid
Obtaining and Setting Cell Values in Developer Express QuantumGrid