To simulate user actions over the TDBGrid control or to obtain the data of the grid cells, you will have 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 TDBGrid 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.
To perform these actions, TestComplete must have access to internal methods and properties of the TDBGrid control. This requires the following conditions be met:
When testing Borland TDBGrid controls, use specific methods and properties of the corresponding |
Searching in the Underlying Dataset
A TDBGrid control displays data stored in the dataset (TDataset
object), to which the control is connected. When the tested application activates another record in the dataset, the TDBGrid control activates the appropriate row. To choose a row in the grid, you can use the methods of the dataset object that search for the appropriate record. When you activate a record in the dataset, the grid control will highlight the appropriate row.
To find a record in the dataset, you can use methods of the TDataset
object. Most often you will use the Locate
method. This method locates a record, in which fields contain the specified values. The method has the following syntax:
DatasetObj.Locate(Fields, Values, Options)
The method parameters specify the following information:
- Fields - The name of the dataset field (or fields), in which the method will search. Multiple field names should be separated with semicolons.
- Values - One or several sought-for values. If you search in several fields, the parameter should specify the array holding the search values.
- Options - A combination of the two constants:
DB.loCaseInsensitive
andDB.loPartialKey
. These constants defines the search options. IfDB.loCaseInsensitive
is specified, the method ignores the case when comparing string values. IfDB.loPartialKey
is specified, the search value can include only part of the matching field, for instance, New will match both Newfoundland and New York. TheDB.loCaseInsensitive
andDB.loPartialKey
constants are analogues to theloCaseInsensitive
andloPartialKey
constants defined by the VCL library.
If the method finds the record, it returns True, else - False. For complete information on the Locate
method, see Delphi or C++Builder documentation.
Note: | The first parameter of the method should specify the dataset’s field name (or names) and these names may differ from the column names. So, you have to write script code that obtains the field name by column name (see sample below).
Also, since the |
The Locate
method can also search for a record by using several field values. Below is the code that demonstrates this.
Example
JavaScript
function Main ()
{
var p, Grid, Values, ConvertedValues;
// Obtain the grid object
p = Sys.Process("csdemos");
p.VCLObject("FrmLauncher").VCLObject("BtnViews").ClickButton();
Grid = p.VCLObject("FrmViewDemo").VCLObject("Panel2").VCLObject("DBGrid1");
// Create the array of sought-for values
Values = new Array ("Papadopoulos", "Chris", 887);
// Convert the array
ConvertedValues = ConvertArray(Values);
// Locate a record
if (SearchByLocateEx (Grid, "LastName;FirstName;PhoneExt", ConvertedValues) )
Log.Message ("Record was found and selected.")
else
Log.Message ("Record was not found.");
}
// Search using the Locate method
function SearchByLocateEx(GridObj, ColCaptions, SearchValues)
{
// Obtain the field names
let FldNames = GetFieldNameEx (GridObj, ColCaptions);
// Prepare the search options (DB.loCaseInsensitive and DB.loPartialKey constants
// are analogues to VCL's loCaseInsensitive loPartialKey constants)
let SearchOptions = MkSet (DB.loCaseInsensitive, DB.loPartialKey);
// Call the Locate method
return GridObj.DataSource.DataSet.Locate(FldNames, SearchValues, SearchOptions);
}
// Get columns' field names
function GetFieldNameEx (GridObj, ColCaptions)
{
// Get an array of column captions
let ColCaptionsArr = ColCaptions.split(";");
// Create an array that will store field names
let FldNamesArr = new Array (ColCaptionsArr.length);
// Get the columns' field names
for (let i=0; i<ColCaptionsArr.length; i++)
FldNamesArr[i] = GetFieldName (GridObj, ColCaptionsArr[i]);
// Return a semicolon-delimited string holding field names
return FldNamesArr.join(";");
}
// Get the field name
function GetFieldName (GridObj, ColCaption)
{
// Iterate through the columns collection
for (let i = 0; i < GridObj.Columns.Count; i++)
// Check the column caption
if (equal(GridObj.Columns.Items(i).Field.DisplayName, ColCaption))
return GridObj.Columns.Items(i).FieldName; // Column is found
return ""; // Column is not found
}
// Convert the array
function ConvertArray(JavaScriptArray)
{
// Use the Dictionary object to convert JavaScript array
let objDict = getActiveXObject("Scripting.Dictionary");
objDict.RemoveAll();
for (i in JavaScriptArray)
objDict.Add(i, JavaScriptArray[i]);
return objDict.Items();
}
JScript
function Main ()
{
var p, Grid, Values, ConvertedValues;
// Obtain the grid object
p = Sys.Process("csdemos");
p.VCLObject("FrmLauncher").VCLObject("BtnViews").ClickButton();
Grid = p.VCLObject("FrmViewDemo").VCLObject("Panel2").VCLObject("DBGrid1");
// Create the array of sought-for values
Values = new Array ("Papadopoulos", "Chris", 887);
// Convert the array
ConvertedValues = ConvertArray(Values);
// Locate a record
if (SearchByLocateEx (Grid, "LastName;FirstName;PhoneExt", ConvertedValues) )
Log.Message ("Record was found and selected.")
else
Log.Message ("Record was not found.");
}
// Search using the Locate method
function SearchByLocateEx(GridObj, ColCaptions, SearchValues)
{
// Obtain the field names
var FldNames = GetFieldNameEx (GridObj, ColCaptions);
// Prepare the search options (DB.loCaseInsensitive and DB.loPartialKey constants
// are analogues to VCL's loCaseInsensitive loPartialKey constants)
var SearchOptions = MkSet (DB.loCaseInsensitive, DB.loPartialKey);
// Call the Locate method
return GridObj.DataSource.DataSet.Locate(FldNames, SearchValues, SearchOptions);
}
// Get columns' field names
function GetFieldNameEx (GridObj, ColCaptions)
{
// Get an array of column captions
var ColCaptionsArr = ColCaptions.split(";");
// Create an array that will store field names
var FldNamesArr = new Array (ColCaptionsArr.length);
// Get the columns' field names
for (var i=0; i<ColCaptionsArr.length; i++)
FldNamesArr[i] = GetFieldName (GridObj, ColCaptionsArr[i]);
// Return a semicolon-delimited string holding field names
return FldNamesArr.join(";");
}
// Get the field name
function GetFieldName (GridObj, ColCaption)
{
// Iterate through the columns collection
for (var i = 0; i < GridObj.Columns.Count; i++)
// Check the column caption
if (GridObj.Columns.Items(i).Field.DisplayName == ColCaption)
return GridObj.Columns.Items(i).FieldName; // Column is found
return ""; // Column is not found
}
// Convert the array
function ConvertArray(JScriptArray)
{
// Use the Dictionary object to convert JScript array
var objDict = new ActiveXObject("Scripting.Dictionary");
objDict.RemoveAll();
for (var i in JScriptArray)
objDict.Add(i, JScriptArray[i]);
return objDict.Items();
}
Python
def Main ():
# Obtain the grid object
p = Sys.Process("csdemos")
p.VCLObject("FrmLauncher").VCLObject("BtnViews").ClickButton()
Grid = p.VCLObject("FrmViewDemo").VCLObject("Panel2").VCLObject("DBGrid1")
# Create the array of sought-for values
Values = list("Papadopoulos", "Chris", 887)
# Locate a record
if(SearchByLocateEx (Grid, "LastNameFirstNamePhoneExt", Values)):
Log.Message ("Record was found and selected.")
else:
Log.Message ("Record was not found.")
# Search using the Locate method
def SearchByLocateEx(GridObj, ColCaptions, SearchValues):
# Obtain the field names
FldNames = GetFieldNameEx (GridObj, ColCaptions)
# Prepare the search options (DB.loCaseInsensitive and DB.loPartialKey constants
# are analogues to VCL's loCaseInsensitive loPartialKey constants)
SearchOptions = MkSet (DB.loCaseInsensitive, DB.loPartialKey)
# Call the Locate method
return GridObj.DataSource.DataSet.Locate(FldNames, SearchValues, SearchOptions)
# Get columns' field names
def GetFieldNameEx (GridObj, ColCaptions):
# Get an array of column captions
ColCaptionsArr = ColCaptions.split("")
# Create an array that will store field names
FldNamesArr = list(ColCaptionsArr.length)
# Get the columns' field names
for i in range(0, ColCaptionsArr.length-1):
FldNamesArr[i] = GetFieldName (GridObj, ColCaptionsArr[i])
# Return a semicolon-delimited string holding field names
return FldNamesArr.join("")
# Get the field name
def GetFieldName (GridObj, ColCaption):
# Iterate through the columns collection
for i in range(0, GridObj.Columns.Count-1):
# Check the column caption
if (GridObj.Columns.Items[i].Field.DisplayName == ColCaption):
return GridObj.Columns.Items[i].FieldName # Column is found
return "" # Column is not found
VBScript
Sub Main
Dim p, Grid, Values
' Obtain the grid object
Set p = Sys.Process("csdemos")
p.VCLObject("FrmLauncher").VCLObject("BtnViews").ClickButton
Set Grid = p.VCLObject("FrmViewDemo").VCLObject("Panel2").VCLObject("DBGrid1")
' Create the array of sought-for values
Values = Array ("Papadopoulos", "Chris", 887)
' Locate a record
If SearchByLocateEx (Grid, "LastName;FirstName;PhoneExt", Values) Then
Log.Message ("Record was found and selected.")
Else
Log.Message ("Record was not found.")
End If
End Sub
' Search using the Locate method
Function SearchByLocateEx (GridObj, ColCaptions, SearchValues)
Dim FldNames, SearchOptions
' Obtain the field names
FldNames = GetFieldNameEx(GridObj, ColCaptions)
' Prepare the search options (DB.loCaseInsensitive and DB.loPartialKey constants
' are analogues to VCL's loCaseInsensitive loPartialKey constants)
SearchOptions = MkSet(DB.loCaseInsensitive, DB.loPartialKey)
' Call the Locate method
SearchByLocateEx = GridObj.DataSource.DataSet.Locate (FldNames, SearchValues, SearchOptions)
End Function
' Get the columns' field names
Function GetFieldNameEx (GridObj, ColCaptions)
Dim ColCaptionsArr, FldNamesArr, i
' Get an array of column captions
ColCaptionsArr = Split (ColCaptions, ";")
' Create an array that will store field names
FldNamesArr = CreateVariantArray (0, UBound(ColCaptionsArr))
' Get the columns' field names
For i=0 To UBound(ColCaptionsArr)
FldNamesArr(i) = GetFieldName (GridObj, ColCaptionsArr(i))
Next
' Return a semicolon-delimited string holding field names
GetFieldNameEx = Join (FldNamesArr, ";")
End Function
' Get the field name
Function GetFieldName (GridObj, ColCaption)
' Iterate through columns collection
For i = 0 To GridObj.Columns.Count
' Check the column caption
If GridObj.Columns.Items(i).Field.DisplayName = ColCaption Then
GetFieldName = GridObj.Columns.Items(i).FieldName ' Column is found
Exit Function
End If
Next
GetFieldName = "" ' Column is not found
End Function
DelphiScript
function GetFieldNameEx(GridObj, ColCaptions); forward;
function GetFieldName (GridObj, ColCaption); forward;
function SearchByLocateEx (GridObj, ColCaptions, SearchValues); forward;
procedure Main;
var p, Grid, Values : OleVariant;
begin
// Obtain the grid object
p := Sys.Process('csdemos');
p.VCLObject('FrmLauncher').VCLObject('BtnViews').ClickButton;
Grid := p.VCLObject('FrmViewDemo').VCLObject('Panel2').VCLObject('DBGrid1');
// Create the array of sought-for values
Values := CreateVariantArray (0, 2);
Values[0] := 'Papadopoulos';
Values[1] := 'Chris';
Values[2] := 887;
// Locate a record
if SearchByLocateEx (Grid, 'LastName;FirstName;PhoneExt', Values) then
Log.Message ('Record was found and selected.')
else
Log.Message ('Record was not found.');
end;
// Search using the Locate method
function SearchByLocateEx (GridObj, ColCaptions, SearchValues);
var FldNames, SearchOptions : OleVariant;
begin
// Obtain the field names
FldNames := GetFieldNameEx(GridObj, ColCaptions);
// Prepare the search options (DB.loCaseInsensitive and DB.loPartialKey constants
// are analogues to VCL's loCaseInsensitive loPartialKey constants)
SearchOptions := MkSet(DB.loCaseInsensitive, DB.loPartialKey);
// Call the Locate method
Result := GridObj.DataSource.DataSet.Locate (FldNames, SearchValues, SearchOptions);
end;
// Get columns' field names
function GetFieldNameEx(GridObj, ColCaptions);
var FldNames, n, i : OleVariant;
begin
FldNames := '';
// Process the string of column names
aqString.ListSeparator := ';';
n := aqString.GetListLength (ColCaptions);
for i := 0 to n-2 do
// Get the field name for the current column and add it to the resulting string
FldNames := FldNames + GetFieldName (GridObj, aqString.GetListItem(ColCaptions, i)) + ';' ;
FldNames := FldNames + GetFieldName (GridObj, aqString.GetListItem(ColCaptions, n-1));
Result := FldNames;
end;
// Get the field name
function GetFieldName (GridObj, ColCaption);
var i : OleVariant;
begin
// Iterate through the columns collection
for i := 0 to GridObj.Columns.Count-1 do
// Check the column caption
if GridObj.Columns.Items[i].Field.DisplayName = ColCaption then
begin
Result := GridObj.Columns.Items[i].FieldName; // Column is found
Exit;
end;
Result := ''; // Column is not found
end;
C++Script, C#Script
function Main ()
{
var p, Grid, Values, ConvertedValues;
// Obtain the grid object
p = Sys["Process"]("csdemos");
p["VCLObject"]("FrmLauncher")["VCLObject"]("BtnViews")["ClickButton"]();
Grid = p["VCLObject"]("FrmViewDemo")["VCLObject"]("Panel2")["VCLObject"]("DBGrid1");
// Create the array of sought-for values
Values = new Array ("Papadopoulos", "Chris", 887);
// Convert the array
ConvertedValues = ConvertArray(Values);
// Locate a record
if (SearchByLocateEx (Grid, "LastName;FirstName;PhoneExt", ConvertedValues) )
Log["Message"]("Record was found and selected.")
else
Log["Message"]("Record was not found.");
}
// Search using the Locate method
function SearchByLocateEx(GridObj, ColCaptions, SearchValues)
{
// Obtain the field names
var FldNames = GetFieldNameEx (GridObj, ColCaptions);
// Prepare the search options (DB.loCaseInsensitive and DB.loPartialKey constants
// are analogues to VCL's loCaseInsensitive loPartialKey constants)
var SearchOptions = MkSet (DB["loCaseInsensitive"], DB["loPartialKey"]);
// Call the Locate method
return GridObj["DataSource"]["DataSet"]["Locate"](FldNames, SearchValues, SearchOptions);
}
// Get columns' field names
function GetFieldNameEx (GridObj, ColCaptions)
{
// Get an array of column captions
var ColCaptionsArr = ColCaptions["split"](";");
// Create an array that will store field names
var FldNamesArr = new Array (ColCaptionsArr["length"]);
// Get the columns' field names
for (var i=0; i<ColCaptionsArr["length"]; i++)
FldNamesArr[i] = GetFieldName (GridObj, ColCaptionsArr[i]);
// Return a semicolon-delimited string holding field names
return FldNamesArr["join"](";");
}
// Get the field name
function GetFieldName (GridObj, ColCaption)
{
// Iterate through the columns collection
for (var i = 0; i < GridObj["Columns"]["Count"]; i++)
// Check the column caption
if (GridObj["Columns"]["Items"](i)["Field"]["DisplayName"] == ColCaption)
return GridObj["Columns"]["Items"](i)["FieldName"]; // Column is found
return ""; // Column is not found
}
// Convert the array
function ConvertArray (JScriptArray)
{
// Use the Dictionary object to convert JScript array
var objDict = new ActiveXObject ("Scripting.Dictionary");
objDict["RemoveAll"]();
for (var i in JScriptArray)
objDict["Add"](i, JScriptArray[i]);
return objDict["Items"]();
}
Searching by Iterating Through Grid Rows
Quite often, users search for records by iterating through grid records and examining cell values. You can create a script that will emulate these user actions. Below is a sample script that demonstrates this approach.
Example
JavaScript
// Activate a row by its index (zero-based)
function ActivateRow(GridObject, RowIndex)
{
GridObject.DataSource.DataSet.First();
GridObject.DataSource.DataSet.MoveBy(RowIndex);
}
// Get the cell by its row and column indexes (zero-based)
function GetCell(GridObject, Row, Col)
{
var FldName, Fld;
// Get the field name
FldName = GridObject.Columns.Items(Col).FieldName;
// Activate the row
ActivateRow(GridObject, Row);
// Get the field text
Fld = GridObject.DataSource.DataSet.FieldByName(FldName);
return Fld.AsString;
}
// Search for a row by cell value
function SearchCell(GridObject, ColIndex, Value)
{
let r = -1;
// Iterate through grid records
for(let i = 0; i < GridObject.DataSource.DataSet.RecordCount; i++)
{
// Get cell value and comparing it with the sought-for value
if (equal(GetCell(GridObject, i, ColIndex), Value))
{
r = i;
break;
}
}
return r;
}
function Main()
{
var p, Grid;
// Obtain the grid object
p = Sys.Process("csdemos");
Grid = p.VCLObject("FrmViewDemo").VCLObject("Panel2").VCLObject("DBGrid1");
// Search
if(!equal(SearchCell(Grid, 1, "Papadopoulos"), - 1))
Log.Message("Found");
else
Log.Message("Not Found");
}
JScript
// Activate a row by its index (zero-based)
function ActivateRow(GridObject, RowIndex)
{
GridObject.DataSource.DataSet.First();
GridObject.DataSource.DataSet.MoveBy(RowIndex);
}
// Get the cell by its row and column indexes (zero-based)
function GetCell(GridObject, Row, Col)
{
var FldName, Fld;
// Get the field name
FldName = GridObject.Columns.Items(Col).FieldName;
// Activate the row
ActivateRow(GridObject, Row);
// Get the field text
Fld = GridObject.DataSource.DataSet.FieldByName(FldName);
return Fld.AsString;
}
// Search for a row by cell value
function SearchCell(GridObject, ColIndex, Value)
{
var i, r;
r = -1;
// Iterate through grid records
for(i = 0; i < GridObject.DataSource.DataSet.RecordCount; i++)
{
// Get cell value and comparing it with the sought-for value
if (GetCell(GridObject, i, ColIndex) == Value)
{
r = i;
break;
}
}
return r;
}
function Main()
{
var p, Grid;
// Obtain the grid object
p = Sys.Process("csdemos");
Grid = p.VCLObject("FrmViewDemo").VCLObject("Panel2").VCLObject("DBGrid1");
// Search
if( SearchCell(Grid, 1, "Papadopoulos") != - 1)
Log.Message("Found");
else
Log.Message("Not Found");
}
Python
# Activate a row by its index (zero-based)
def ActivateRow(GridObject, RowIndex):
GridObject.DataSource.DataSet.First()
GridObject.DataSource.DataSet.MoveBy(RowIndex)
# Get the cell by its row and column indexes (zero-based)
def GetCell(GridObject, Row, Col):
# Get the field name
FldName = GridObject.Columns.Items(Col).FieldName
# Activate the row
ActivateRow(GridObject, Row)
# Get the field text
Fld = GridObject.DataSource.DataSet.FieldByName(FldName)
return Fld.AsString
# Search for a row by cell value
def SearchCell(GridObject, ColIndex, Value):
r = -1
# Iterate through grid records
for i in range(0, GridObject.DataSource.DataSet.RecordCount):
# Get cell value and comparing it with the sought-for value
if (GetCell(GridObject, i, ColIndex) == Value):
r = i
break
return r
def Main1():
# Obtain the grid object
p = Sys.Process("csdemos")
Grid = p.VCLObject("FrmViewDemo").VCLObject("Panel2").VCLObject("DBGrid1")
# Search
if( SearchCell(Grid, 1, "Papadopoulos") != - 1):
Log.Message("Found")
else:
Log.Message("Not Found")
VBScript
' Activates a row by its index (zero-based)
Sub ActivateRow(GridObject, RowIndex)
Call GridObject.DataSource.DataSet.First()
Call GridObject.DataSource.DataSet.MoveBy(RowIndex)
End Sub
' Getting the cell by its row and column indexes (zero-based)
Function GetCell(GridObject, Row, Col)
' Getting the field name
FldName = GridObject.Columns.Items(Col).FieldName
' Activating the row
Call ActivateRow(GridObject, Row)
' Getting the field text
Set Fld = GridObject.DataSource.DataSet.FieldByName(FldName)
GetCell = Fld.AsString
End Function
' Searching for a row by cell value
Function SearchCell(GridObject, ColIndex, Value)
SearchCell = -1
' Iterating through grid records
For i = 0 To GridObject.DataSource.DataSet.RecordCount - 1
' Getting cell value and comparing it with the sought-for value
If GetCell(GridObject, i, ColIndex) = Value Then
SearchCell = i
Exit For
End If
Next
End Function
Sub Main
' Obtaining the grid object
Set p = Sys.Process("csdemos")
Set Grid = p.VCLObject("FrmViewDemo").VCLObject("Panel2").VCLObject("DBGrid1")
' Searching
If SearchCell(Grid, 1, "Papadopoulos") <> -1 Then
Log.Message("Found")
Else
Log.Message("Not found")
End If
End Sub
DelphiScript
// Activate a row by its index (zero-based)
procedure ActivateRow(GridObject, RowIndex);
begin
GridObject.DataSource.DataSet.First();
GridObject.DataSource.DataSet.MoveBy(RowIndex);
end;
// Get the cell by its row and column indexes (zero-based)
function GetCell(GridObject, Row, Col);
var
FldName, Fld : OleVariant;
begin
// Get the field name
FldName := GridObject.Columns.Items[Col].FieldName;
// Activate the row
ActivateRow(GridObject, Row);
// Get the field text
Fld := GridObject.DataSource.DataSet.FieldByName[FldName];
Result := Fld.AsString;
end;
// Search for a row by cell value
function SearchCell(GridObject, ColIndex, Value);
var
i : OleVariant;
begin
Result := -1;
// Iterate through grid records
for i := 0 to GridObject.DataSource.DataSet.RecordCount - 1 do
begin
// Get cell value and comparing it with the sought-for value
if GetCell(GridObject, i, ColIndex) = Value then
begin
Result := i;
Exit;
end;
end;
end;
procedure Main;
var
p, Grid : OleVariant;
begin
// Obtain the grid object
p := Sys.Process('csdemos');
Grid := p.VCLObject('FrmViewDemo').VCLObject('Panel2').VCLObject('DBGrid1');
// Search
if SearchCell(Grid, 1, 'Papadopoulos') <> -1 then
Log.Message('Found')
else
Log.Message('Not Found');
end;
C++Script, C#Script
// Activate a row by its index (zero-based)
function ActivateRow(GridObject, RowIndex)
{
GridObject["DataSource"]["DataSet"]["First"]();
GridObject["DataSource"]["DataSet"]["MoveBy"](RowIndex);
}
// Get the cell by its row and column indexes (zero-based)
function GetCell(GridObject, Row, Col)
{
var FldName, Fld;
// Get the field name
FldName = GridObject["Columns"]["Items"](Col)["FieldName"];
// Activate the row
ActivateRow(GridObject, Row);
// Get the field text
Fld = GridObject["DataSource"]["DataSet"]["FieldByName"](FldName);
return Fld["AsString"];
}
// Search for a row by cell value
function SearchCell(GridObject, ColIndex, Value)
{
var i, r;
r = -1;
// Iterate through grid records
for(i = 0; i < GridObject["DataSource"]["DataSet"]["RecordCount"]; i++)
{
// Get cell value and comparing it with the sought-for value
if (GetCell(GridObject, i, ColIndex) == Value)
{
r = i;
break;
}
}
return r;
}
function Main()
{
var p, Grid;
// Obtain the grid object
p = Sys["Process"]("csdemos");
Grid = p["VCLObject"]("FrmViewDemo")["VCLObject"]("Panel2")["VCLObject"]("DBGrid1");
// Search
if( SearchCell(Grid, 1, "Papadopoulos") != -1)
Log["Message"]("Found");
else
Log["Message"]("Not Found");
}
As you can see, to activate a row, we called two methods of the grid’s dataset: First
and MoveBy
. That is, locating a record requires two steps: we choose the first record and then move the selection to the specified distance. Using this technique guarantees that the selection procedure will work in both filtered and non-filtered datasets.
If the dataset is not filtered, you can activate grid rows by using the grid’s vertical scroll bar. When displaying the data stored in a non-filtered dataset, the TDBGrid control sets the minimum position of the vertical scroll bar to 1 and the maximum position to the number of dataset records. By specifying the scroll box position you can activate the desired row by its index.
To get a scripting interface to the grid’s vertical scroll bar, use the VScroll
property of the scripting object that corresponds to the TDBGrid control. This property is provided by TestComplete. It returns the ScrollBar
object corresponding to the vertical scroll bar of the control. To set the scroll bar’s position, use the Pos
property of the ScrollBar
object. The following code demonstrates how you can use this property:
JavaScript, JScript
// Activate a row by its index (zero-based)
function ActivateRowByScrollBar (GridObj, RowIndex)
{
GridObj.VScroll.Pos = RowIndex + 1;
}
Python
# Activate a row by its index (zero-based)
def ActivateRowByScrollBar (GridObj, RowIndex):
GridObj.VScroll.Pos = RowIndex + 1
VBScript
' Activate a row by its index (zero-based)
Sub ActivateRowByScrollBar (GridObj, RowIndex)
GridObj.VScroll.Pos = RowIndex + 1
End Sub
DelphiScript
// Activate a row by its index (zero-based)
procedure ActivateRowByScrollBar (GridObj, RowIndex);
begin
GridObj.VScroll.Pos := RowIndex + 1;
end;
C++Script, C#Script
// Activate a row by its index (zero-based)
function ActivateRowByScrollBar (GridObj, RowIndex)
{
GridObj["VScroll"]["Pos"] = RowIndex + 1;
}
Note: | Since the minimum scroll bar position is 0 and the row index is zero-based, we increased the RowIndex parameter by 1 when assigning it to the Pos property. |
We would like to note once again that this approach only works if the TDBGrid displays data of a non-filtered dataset.
Which Approach to Choose
We described two variants of the searching procedure. One of these variants uses the Locate
method and another one iterates through the rows of the grid to find the desired row.
In general, the approach that uses the Locate
method provides a faster search. If the dataset has indexes, the Locate
method will search using these indexes. However, the method analyzes data stored in the database fields and this may cause problems, which can affect your decision on using the method.
Since the Locate
method checks data stored in the database fields, you have to be aware of the field data type and specify the appropriate data as a search value. Else, an error will occur. For instance, if the field holds an integer value and you specify a string, you will get an error message during the script execution.
Note that the fields’s data may differ from the data you see in the grid cells: VCL includes special events, which let programmers change the field text to be displayed in visual controls. So, the TDBGrid
control may display the modified text rather than the data stored in the field. For instance, a field may store an integer value (say, 3), but the grid may display the string other than “3”, because the event handler can change the displayed text to something like “3 book(s)” or “3 user(s)”. Please remember this when specifying the sought-for values for the Locate
method.
The second variant of the search procedure iterates through the grid records and analyzes the field’s text, so it does not depend on the field type and on the TField
object’s events that change the displayed text. However, the iteration approach functions a lot slower than the Locate
method. So, you can use it when you need to search for data within the field’s text.
Note that developers change the cell text using events of the TField
and TDBGrid
objects. The iteration approach does not depend on the TField
event handlers. However, it will not help if developers modify the cell values using events of the TDBGrid control. To search for records in this case, you will have to use the Locate
method of the TDataset
object.
See Also
Working With Borland TDBGrid
Iterating Through Rows in Borland TDBGrid
Obtaining and Setting Cell Values in Borland TDBGrid