Iterating Through Rows in Developer Express QuantumGrid

Applies to TestComplete 14.81, last modified on May 04, 2021

Iterating through grid rows means accessing rows is a series, one by one. You may need to iterate through QuantumGrid rows if you need to locate a particular row in the grid, export the grid data to a file or perform the same set of operations on each row.

QuantumGrid can display data in several nested levels. Each grid level can have one or more views, which displays the data in a table, banded, card or other form. You can determine the number of views on a particular grid level using the wViewCount property of the DevExpressQuantumGrid or DevExpressQuantumGridLevel object. To specify that you are working with data of a specific view, you can pass the view’s zero-based index or its caption in the View parameter of the DevExpressQuantumGridLevel properties or methods.

To determine the number of rows in a particular grid view, you can use the wRowCount property. Once you have determined the number of rows in a view, you can iterate through them in a loop. Since the numeration of rows is zero-based, index of the first row is 0, and index of the last row is wRowCount-1. On each loop iteration, you can perform the needed actions with the current row. For example, you can modify values in its cells or save them to a file. For more information on how to obtain or modify grid cell values, see Obtaining and Setting Cell Values in Developer Express QuantumGrid.

If the grid control displays data of multiple nested tables, then after processing a data row you may need to process its child data. To access a child level, use the wChildLevel property. You can then process a child level in the same way as the root level; by iterating through its views and their rows. That is, the algorithm of processing the QuantumGrid data implies that it is recursive.

In order for TestComplete to be able to perform these actions, the following conditions must be met: Note also, that the compiler can exclude methods and properties that are not called in the application’s source code from the application’s binary code, so these methods and properties are unavailable to TestComplete (see Object Properties, Fields and Methods That Are Unavailable to TestComplete). To solve the problem, make sure that the desired methods and properties are used in the application’s source code. For instance, you can add a virtual method to your application that calls the desired methods and properties (the compiler does not exclude virtual methods).

When testing Developer Express QuantumGrid controls, use specific methods and properties of the corresponding DevExpressQuantumGrid object. You can call these methods and properties from your keyword tests, as well as from scripts. This topic describes how to work with an object’s properties and methods from your scripts. However, when testing a QuantumGrid control from your keyword test, you can use the same methods and properties calling them from keyword test operations. For more information, see Keyword Tests Basic Operations.

Below is a script sample that demonstrates how you can iterate through the QuantumGrid rows using the mentioned properties. The script saves grid data along with view captions and column names to an XML file. It processes the data of the root grid level as well as child levels. Note that the routine only exports the actual grid data and does not save the grid’s grouping state.

Example

View description

JavaScript

function Main ()
{
  var p, Grid, FileName;

  // Obtain the grid object
  p = Sys.Process("MySampleApp");
  Grid = p.VCLObject("FormName").VCLObject("GridName");

  // Export the grid data to a file
  FileName = "C:\\GridData.xml";
  ExportToXml (Grid, FileName);
  Log.File (FileName, "Exported grid data.");
}

function ExportToXml (Grid, FileName)
{
  Indicator.PushText ("Exporting the grid data to a file...");

  // Create a text file and open it for writing
  let Overwrite = true;
  let Unicode = true;
  let fso = getActiveXObject("Scripting.FileSystemObject");
  let XmlFile = fso.CreateTextFile (FileName, Overwrite, Unicode);

  // Write the root tag
  XmlFile.WriteLine ("<?xml version=\"1.0\"?>");
  XmlFile.WriteLine ("<grid>");

  ExportLevel (Grid, XmlFile, "  ");

  // Close the root tag
  XmlFile.WriteLine ("</grid>");
  // Close the file
  XmlFile.Close();

  Indicator.PopText();
}

function ExportLevel (Level, XmlFile, indent)
{
  var ViewCaption, ColCaption, CellValue, CellText;

  for (let ViewIndex=0; ViewIndex<Level.wViewCount; ViewIndex++)
  {
    // Write the opening tag
    ViewCaption = ReplaceSpecialChars (Level.wView(ViewIndex)); // Replace special symbols
    XmlFile.WriteLine (indent + "<view caption=\"" + ViewCaption + "\">");

    // Export columns info
    XmlFile.WriteLine (indent + "  <columns>");
    for (let j=0; j<Level.wColumnCount(ViewIndex); j++)
    {
      ColCaption = ReplaceSpecialChars (Level.wColumn(j, ViewIndex)); // Replace special symbols
      XmlFile.WriteLine (indent + "    <column>" + ColCaption + "</column>");
    }
    XmlFile.WriteLine (indent + "  </columns>");  

    // Export the row data
    XmlFile.WriteLine (indent + "  <rows>");
    for (let i=0; i<Level.wRowCount(ViewIndex); i++)
    {
      // Write the opening tag
      XmlFile.WriteLine (indent + "    <row>");
      for (let j=0; j<Level.wColumnCount(ViewIndex); j++)
      {
        CellValue = Level.wValue(i, j, ViewIndex);
        CellText = ReplaceSpecialChars(aqConvert.VarToStr(CellValue)); // Replace special symbols
        // Write cell values
        XmlFile.WriteLine (indent + "      <cell>" + CellText + "</cell>");
      }
      // Check if the row has child data
      if (!(strictEqualLevel.wChildLevel(i, ViewIndex)), null)
      {
        XmlFile.WriteLine (indent + "      <childlevel>");
        // Export child level data
        ExportLevel (Level.wChildLevel(i, ViewIndex), XmlFile, indent + "        ");
        XmlFile.WriteLine (indent + "      </childlevel>");
      }
      // Write the ending tag
      XmlFile.WriteLine (indent + "    </row>");
    }
    XmlFile.WriteLine (indent + "  </rows>");

    // Write the ending tag
    XmlFile.WriteLine (indent + "</view>");
  }
}

// Replaces special characters in the specified string
function ReplaceSpecialChars (str)
{
  let s = aqString.Replace (str, "&", "&amp;", true);
  s = aqString.Replace (s, "<", "&lt;", true);
  s = aqString.Replace (s, ">", "&gt;", true);
  s = aqString.Replace (s, "\"", "&quot;", true);
  s = aqString.Replace (s, "'", "&apos;", true);
  return s;
}

JScript

function Main ()
{
  var p, Grid, FileName;

  // Obtain the grid object
  p = Sys.Process("MySampleApp");
  Grid = p.VCLObject("FormName").VCLObject("GridName");

  // Export the grid data to a file
  FileName = "C:\\GridData.xml";
  ExportToXml (Grid, FileName);
  Log.File (FileName, "Exported grid data.");
}

function ExportToXml (Grid, FileName)
{
  Indicator.PushText ("Exporting the grid data to a file...");

  // Create a text file and open it for writing
  var Overwrite = true;
  var Unicode = true;
  var fso = new ActiveXObject ("Scripting.FileSystemObject");
  var XmlFile = fso.CreateTextFile (FileName, Overwrite, Unicode);

  // Write the root tag
  XmlFile.WriteLine ("<?xml version=\"1.0\"?>");
  XmlFile.WriteLine ("<grid>");

  ExportLevel (Grid, XmlFile, "  ");

  // Close the root tag
  XmlFile.WriteLine ("</grid>");
  // Close the file
  XmlFile.Close();

  Indicator.PopText();
}

function ExportLevel (Level, XmlFile, indent)
{
  var ViewIndex, ViewCaption, ColCaption, i, j, CellValue, CellText;

  for (ViewIndex=0; ViewIndex<Level.wViewCount; ViewIndex++)
  {
    // Write the opening tag
    ViewCaption = ReplaceSpecialChars (Level.wView(ViewIndex)); // Replace special symbols
    XmlFile.WriteLine (indent + "<view caption=\"" + ViewCaption + "\">");

    // Export columns info
    XmlFile.WriteLine (indent + "  <columns>");
    for (j=0; j<Level.wColumnCount(ViewIndex); j++)
    {
      ColCaption = ReplaceSpecialChars (Level.wColumn(j, ViewIndex)); // Replace special symbols
      XmlFile.WriteLine (indent + "    <column>" + ColCaption + "</column>");
    }
    XmlFile.WriteLine (indent + "  </columns>");  

    // Export the row data
    XmlFile.WriteLine (indent + "  <rows>");
    for (i=0; i<Level.wRowCount(ViewIndex); i++)
    {
      // Write the opening tag
      XmlFile.WriteLine (indent + "    <row>");
      for (j=0; j<Level.wColumnCount(ViewIndex); j++)
      {
        CellValue = Level.wValue(i, j, ViewIndex);
        CellText = ReplaceSpecialChars(aqConvert.VarToStr(CellValue)); // Replace special symbols
        // Write cell values
        XmlFile.WriteLine (indent + "      <cell>" + CellText + "</cell>");
      }
      // Check if the row has child data
      if (Level.wChildLevel(i, ViewIndex) != null)
      {
        XmlFile.WriteLine (indent + "      <childlevel>");
        // Export child level data
        ExportLevel (Level.wChildLevel(i, ViewIndex), XmlFile, indent + "        ");
        XmlFile.WriteLine (indent + "      </childlevel>");
      }
      // Write the ending tag
      XmlFile.WriteLine (indent + "    </row>");
    }
    XmlFile.WriteLine (indent + "  </rows>");

    // Write the ending tag
    XmlFile.WriteLine (indent + "</view>");
  }
}

// Replaces special characters in the specified string
function ReplaceSpecialChars (str)
{
  var s = aqString.Replace (str, "&", "&amp;", true);
  s = aqString.Replace (s, "<", "&lt;", true);
  s = aqString.Replace (s, ">", "&gt;", true);
  s = aqString.Replace (s, "\"", "&quot;", true);
  s = aqString.Replace (s, "'", "&apos;", true);
  return s;
}

Python

def Main ():

  # Obtain the grid object
  p = Sys.Process("MySampleApp")
  Grid = p.VCLObject("FormName").VCLObject("GridName")

  # Export the grid data to a file
  FileName = "C:\\GridData.xml"
  ExportToXml (Grid, FileName)
  Log.File (FileName, "Exported grid data.")

def ExportToXml (Grid, FileName):
  Indicator.PushText ("Exporting the grid data to a file...")

  # Create a text file and open it for writing
  Overwrite = True
  Unicode = True
  fso = Sys.OleObject ["Scripting.FileSystemObject"]
  XmlFile = fso.CreateTextFile (FileName, Overwrite, Unicode)

  # Write the root tag
  XmlFile.WriteLine ("<?xml version=\"1.0\"?>")
  XmlFile.WriteLine ("<grid>")

  ExportLevel (Grid, XmlFile, "  ")

  # Close the root tag
  XmlFile.WriteLine ("</grid>")
  # Close the file
  XmlFile.Close()

  Indicator.PopText()

def ExportLevel (Level, XmlFile, indent):

  for ViewIndex in range(0, Level.wViewCount-1):
    # Write the opening tag
    ViewCaption = ReplaceSpecialChars (Level.wView[ViewIndex]) # Replace special symbols
    XmlFile.WriteLine (indent + "<view caption=\"" + ViewCaption + "\">")

    # Export columns info
    XmlFile.WriteLine (indent + "  <columns>")
    for j in range(0, Level.wColumnCount[ViewIndex]-1):
      ColCaption = ReplaceSpecialChars (Level.wColumn[j, ViewIndex]) # Replace special symbols
      XmlFile.WriteLine (indent + "    <column>" + ColCaption + "</column>")
    XmlFile.WriteLine (indent + "  </columns>") 

    # Export the row data
    XmlFile.WriteLine (indent + "  <rows>")
    for i in range(0, Level.wRowCount(ViewIndex)-1):
      # Write the opening tag
      XmlFile.WriteLine (indent + "    <row>")
      for j in range(0, Level.wColumnCount(ViewIndex)-1):
        CellValue = Level.wValue[i, j, ViewIndex]
        CellText = ReplaceSpecialChars(aqConvert.VarToStr(CellValue)) # Replace special symbols
        # Write cell values
        XmlFile.WriteLine (indent + "      <cell>" + CellText + "</cell>")
      # Check if the row has child data
      if (Level.wChildLevel[i, ViewIndex] != None):
        XmlFile.WriteLine (indent + "      <childlevel>")
        # Export child level data
        ExportLevel (Level.wChildLevel[i, ViewIndex], XmlFile, indent + "        ")
        XmlFile.WriteLine (indent + "      </childlevel>")
      # Write the ending tag
      XmlFile.WriteLine (indent + "    </row>")
    XmlFile.WriteLine (indent + "  </rows>")

    # Write the ending tag
    XmlFile.WriteLine (indent + "</view>")

# Replaces special characters in the specified string
def ReplaceSpecialChars (str):
  s = aqString.Replace (str, "&", "&amp;", True)
  s = aqString.Replace (s, "<", "&lt;", True)
  s = aqString.Replace (s, ">", "&gt;", True)
  s = aqString.Replace (s, "\"", "&quot;", True)
  s = aqString.Replace (s, "'", "&apos;", True)
  return s

VBScript

Sub Main
  Dim p, Grid, FileName

  ' Obtain the grid object
  Set p = Sys.Process("MySampleApp")
  Set Grid = p.VCLObject("FormName").VCLObject("GridName")

  ' Export the grid data to a file
  FileName = "C:\\GridData.xml"
  Call ExportToXml (Grid, FileName)
  Call Log.File (FileName, "Exported grid data.")
End Sub

Sub ExportToXml (Grid, FileName)
  Dim fso, XmlFile, Overwrite, Unicode

  Indicator.PushText ("Exporting the grid data to a file...")

  ' Create a text file and open it for writing
  Overwrite = True
  Unicode = True
  Set fso = CreateObject ("Scripting.FileSystemObject")
  Set XmlFile = fso.CreateTextFile (FileName, Overwrite, Unicode)

  ' Write the root tag
  Call XmlFile.WriteLine ("<?xml version=""1.0""?>")
  XmlFile.WriteLine ("<grid>")

  'Grid.BeginUpdate
  Call ExportLevel (Grid, XmlFile, "  ")
  'Grid.EndUpdate

  ' Close the root tag
  XmlFile.WriteLine ("</grid>")
  ' Close the file
  XmlFile.Close

  Indicator.PopText
End Sub

Sub ExportLevel (Level, XmlFile, indent)
  Dim ViewIndex, ViewCaption, ColCaption, i, j, CellValue, CellText

  For ViewIndex = 0 To Level.wViewCount - 1
    ' Write the opening tag
    ViewCaption = ReplaceSpecialChars (Level.wView(ViewIndex)) ' Replace special symbols
    Call XmlFile.WriteLine (indent & "<view caption=""" & ViewCaption & """>")

    ' Export columns info
    XmlFile.WriteLine (indent & "  <columns>")
    For j = 0 To Level.wColumnCount(ViewIndex) - 1
      ColCaption = ReplaceSpecialChars (Level.wColumn(j, ViewIndex)) ' Replace special symbols
      XmlFile.WriteLine (indent & "    <column>" & ColCaption & "</column>")
    Next
    XmlFile.WriteLine (indent & "  </columns>")  

    ' Export the row data
    XmlFile.WriteLine (indent & "  <rows>")
    For i = 0 To Level.wRowCount(ViewIndex) - 1
      ' Write the opening tag
      XmlFile.WriteLine (indent & "    <row>")
      For j = 0 To Level.wColumnCount(ViewIndex) - 1
        CellValue = Level.wValue(i, j, ViewIndex)
        CellText = ReplaceSpecialChars(aqConvert.VarToStr(CellValue)) ' Replace special symbols
        ' Write cell values
        XmlFile.WriteLine (indent & "      <cell>" & CellText & "</cell>")
      Next
      ' Check if the row has child data
      If Not (Level.wChildLevel(i, ViewIndex) Is Nothing) Then
        XmlFile.WriteLine (indent & "      <childlevel>")
        ' Export child level data
        Call ExportLevel (Level.wChildLevel(i, ViewIndex), XmlFile, indent & "        ")
        XmlFile.WriteLine (indent & "      </childlevel>")
      End If
      ' Write the ending tag
      XmlFile.WriteLine (indent & "    </row>")
    Next
    XmlFile.WriteLine (indent & "  </rows>")

    ' Write the ending tag
    XmlFile.WriteLine (indent & "</view>")
  Next
End Sub

' Replaces special characters in the specified string
Function ReplaceSpecialChars (str)
  Dim s
  s = aqString.Replace (str, "&", "&amp;", True)
  s = aqString.Replace (s, "<", "&lt;", True)
  s = aqString.Replace (s, ">", "&gt;", True)
  s = aqString.Replace (s, """", "&quot;", True)
  s = aqString.Replace (s, "'", "&apos;", True)
  ReplaceSpecialChars = s
End Function

DelphiScript

procedure ExportToXml (Grid, FileName); forward;
procedure ExportLevel (Level, XmlFile, indent); forward;
function ReplaceSpecialChars (str); forward;

procedure Main;
var p, Grid, FileName : OleVariant;
begin
  // Obtain the grid object
  p := Sys.Process('MySampleApp');
  Grid := p.VCLObject('FormName').VCLObject('GridName');

  // Export the grid data to a file
  FileName := 'C:\GridData.xml';
  ExportToXml (Grid, FileName);
  Log.File (FileName, 'Exported grid data.');
end;

procedure ExportToXml (Grid, FileName);
var fso, XmlFile, Overwrite, Unicode: OleVariant;
begin
  Indicator.PushText ('Exporting the grid data to a file...');

  // Create a text file and open it for writing
  Overwrite := true;
  Unicode := true;
  fso := Sys.OleObject ('Scripting.FileSystemObject');
  XmlFile := fso.CreateTextFile (FileName, Overwrite, Unicode);

  // Write the root tag
  XmlFile.WriteLine ('<?xml version="1.0"?>');
  XmlFile.WriteLine ('<grid>');

  //Grid.BeginUpdate;
  ExportLevel (Grid, XmlFile, '  ');
  //Grid.EndUpdate;

  // Close the root tag
  XmlFile.WriteLine ('</grid>');
  // Close the file
  XmlFile.Close;

  Indicator.PopText();
end;

procedure ExportLevel (Level, XmlFile, indent);
var ViewIndex, ViewCaption, ColCaption, i, j, CellValue, CellText : OleVariant;
begin
  for ViewIndex := 0 to Level.wViewCount - 1 do
  begin
    // Write the opening tag
    ViewCaption := ReplaceSpecialChars (Level.wView[ViewIndex]); // Replace special symbols
    XmlFile.WriteLine (indent + '<view caption="' + ViewCaption + '">');

    // Export columns info
    XmlFile.WriteLine (indent + '  <columns>');
    for j := 0 to Level.wColumnCount[ViewIndex] - 1 do
    begin
      ColCaption := ReplaceSpecialChars (Level.wColumn[j, ViewIndex]); // Replace special symbols
      XmlFile.WriteLine (indent + '    <column>' + ColCaption + '</column>');
    end;
    XmlFile.WriteLine (indent + '  </columns>');  

    // Export the row data
    XmlFile.WriteLine (indent + '  <rows>');
    for i := 0 to Level.wRowCount[ViewIndex] - 1 do
    begin
      // Write the opening tag
      XmlFile.WriteLine (indent + '    <row>');
      for j := 0 to Level.wColumnCount[ViewIndex] - 1 do
      begin
        CellValue := Level.wValue[i, j, ViewIndex];
        CellText := ReplaceSpecialChars(aqConvert.VarToStr(CellValue)); // Replace special symbols
        // Write cell values
        XmlFile.WriteLine (indent + '      <cell>' + CellText + '</cell>');
      end;
      // Check if the row has child data
      if Level.wChildLevel[i, ViewIndex] <> nil then
      begin
        XmlFile.WriteLine (indent + '      <childlevel>');
        // Export child level data
        ExportLevel (Level.wChildLevel[i, ViewIndex], XmlFile, indent + '        ');
        XmlFile.WriteLine (indent + '      </childlevel>');
      end;
      // Write the ending tag
      XmlFile.WriteLine (indent + '    </row>');
    end;
    XmlFile.WriteLine (indent + '  </rows>');

    // Write the ending tag
    XmlFile.WriteLine (indent + '</view>');
  end;
end;

// Replaces special characters in the specified string
function ReplaceSpecialChars (str);
var s : OleVariant;
begin
  s := aqString.Replace (str, '&', '&amp;', true);
  s := aqString.Replace (s, '<', '&lt;', true);
  s := aqString.Replace (s, '>', '&gt;', true);
  s := aqString.Replace (s, '"', '&quot;', true);
  s := aqString.Replace (s, '''', '&apos;', true);
  Result := s;
end;

C++Script, C#Script

function Main ()
{
  var p, Grid, FileName;

  // Obtain the grid object
  p = Sys["Process"]("MySampleApp");
  Grid = p["VCLObject"]("FormName")["VCLObject"]("GridName");

  // Export the grid data to a file
  FileName = "C:\\GridData.xml";
  ExportToXml (Grid, FileName);
  Log["File"](FileName, "Exported grid data.");
}

function ExportToXml (Grid, FileName)
{
  Indicator["PushText"]("Exporting the grid data to a file...");

  // Create a text file and open it for writing
  var Overwrite = true;
  var Unicode = true;
  var fso = new ActiveXObject ("Scripting.FileSystemObject");
  var XmlFile = fso["CreateTextFile"](FileName, Overwrite, Unicode);

  // Write the root tag
  XmlFile["WriteLine"]("<?xml version=\"1.0\"?>");
  XmlFile["WriteLine"]("<grid>");

  ExportLevel (Grid, XmlFile, "  ");

  // Close the root tag
  XmlFile["WriteLine"]("</grid>");
  // Close the file
  XmlFile["Close"]();

  Indicator["PopText"]();
}

function ExportLevel (Level, XmlFile, indent)
{
  var ViewIndex, ViewCaption, ColCaption, i, j, CellValue, CellText;

  for (ViewIndex=0; ViewIndex<Level["wViewCount"]; ViewIndex++)
  {
    // Write the opening tag
    ViewCaption = ReplaceSpecialChars (Level["wView"](ViewIndex)); // Replace special symbols
    XmlFile["WriteLine"](indent + "<view caption=\"" + ViewCaption + "\">");

    // Export columns info
    XmlFile["WriteLine"](indent + "  <columns>");
    for (j=0; j<Level["wColumnCount"](ViewIndex); j++)
    {
      ColCaption = ReplaceSpecialChars (Level["wColumn"](j, ViewIndex)); // Replace special symbols
      XmlFile["WriteLine"](indent + "    <column>" + ColCaption + "</column>");
    }
    XmlFile["WriteLine"](indent + "  </columns>");  

    // Export the row data
    XmlFile["WriteLine"](indent + "  <rows>");
    for (i=0; i<Level["wRowCount"](ViewIndex); i++)
    {
      // Write the opening tag
      XmlFile["WriteLine"](indent + "    <row>");
      for (j=0; j<Level["wColumnCount"](ViewIndex); j++)
      {
        CellValue = Level["wValue"](i, j, ViewIndex);
        CellText = ReplaceSpecialChars(aqConvert["VarToStr"](CellValue)); // Replace special symbols
        // Write cell values
        XmlFile["WriteLine"](indent + "      <cell>" + CellText + "</cell>");
      }
      // Check if the row has child data
      if (Level["wChildLevel"](i, ViewIndex) != null)
      {
        XmlFile["WriteLine"](indent + "      <childlevel>");
        // Export child level data
        ExportLevel (Level["wChildLevel"](i, ViewIndex), XmlFile, indent + "        ");
        XmlFile["WriteLine"](indent + "      </childlevel>");
      }
      // Write the ending tag
      XmlFile["WriteLine"](indent + "    </row>");
    }
    XmlFile["WriteLine"](indent + "  </rows>");

    // Write the ending tag
    XmlFile["WriteLine"](indent + "</view>");
  }
}

// Replaces special characters in the specified string
function ReplaceSpecialChars (str)
{
  var s = aqString["Replace"](str, "&", "&amp;", true);
  s = aqString["Replace"](s, "<", "&lt;", true);
  s = aqString["Replace"](s, ">", "&gt;", true);
  s = aqString["Replace"](s, "\"", "&quot;", true);
  s = aqString["Replace"](s, "'", "&apos;", true);
  return s;
}

See Also

Working With Developer Express QuantumGrid
Searching for Records in Developer Express QuantumGrid
Obtaining and Setting Cell Values in Developer Express QuantumGrid
wRowCount Property (Specific to DevExpressQuantumGrid Controls)
wViewCount Property (Specific to Developer Express QuantumGrid Controls)
wChildLevel Property (Specific to Developer Express QuantumGrid Controls)

Highlight search results