How to loop through records on a cxgrid - Delphi xe2

Sharpie picture Sharpie · Dec 10, 2014 · Viewed 8.2k times · Source

How do you loop through a cxgrids records? i.e. make delphi program go through/check each record in the cxgrid from top to bottom.

I have a cxgrid which is displaying records from a tadquery which is talking to a database table if this helps in anyway.

Answer

MartynA picture MartynA · Dec 10, 2014

Sample code to do this for a TcxGridDBTableView in a TcxGrid, and also to iterate an DataSet below. Both of these samples will work regardless of whether the DataSet is filtered or not.

The sample for the TcxGrid assumes you've pulled the grid from the palette, added a TcxDBTableView to it, added the dataset's columns to it and left all grid properties in the Object Inspector at their defaults, except the KeyFieldNames of the TableView, which needs setting to the DataSet's primary key, in my case "FilesID". This is so as to be able to identify the dataset record for a given row in the TableView - you obtain the key value, ID, for the row like so:

      ID := cxGrid1DBTableView1.DataController.GetRecordId(TopRowIndex + Row);

The ID value is then used by the call to CDS1.Locate() to retrieve the record.

The TBookmark is used to note the current CDS record before the operation and to return to it afterwards. The calls to DisableControls and EnableControls are to prevent the cxGrid (and any other DB-aware controls connected to the CDS) from being changed while the operation is in progress.

procedure TForm1.IterateVisibleGridRows;
var
  BM : TBookmark;
  TopRowIndex : Integer;
  VisibleCount : Integer;
  Row : Integer;
  ID : Integer;
  Controller : TcxGridTableController;
  ViewInfo : TcxGridTableViewInfo;
begin
  BM := CDS1.GetBookmark;
  try

    Controller := cxGrid1DBTableView1.Controller;
    ViewInfo := TcxGridTableViewInfo(Controller.ViewInfo);

    TopRowIndex := Controller.TopRowIndex;
    VisibleCount := ViewInfo.RecordsViewInfo.VisibleCount;

    CDS1.DisableControls;

    Row := 0;
    while Row < VisibleCount do begin
      ID := cxGrid1DBTableView1.DataController.GetRecordId(TopRowIndex + Row);
      if CDS1.Locate('FilesID', ID, []) then begin
        // Do what you want here
      end;
      Inc(Row);
    end;

  finally
    CDS1.GotoBookmark(BM);
    CDS1.FreeBookmark(BM);
    CDS1.EnableControls;
  end;
end;

Btw, I know this is not what you asked, but if you want to iterate a dataset without doing it using a TcxGrid, it's actually much simpler:

procedure IterateDataSetRows(DataSet : TDataSet);
var
  BM : TBookmark;
begin
  BM := CDS1.GetBookmark;
  try
    // delete the following 2 lines and the one in the finally block if you don't want a "Wait" cursor
    Screen.Cursor := crSqlWait;
    Screen.ActiveForm.Update;

    DataSet.DisableControls;
    DataSet.First;

    while not DataSet.Eof do begin
        // Do what you want here
      DataSet.Next;
    end;

  finally
    DataSet.GotoBookmark(BM);
    DataSet.FreeBookmark(BM);
    DataSet.EnableControls;
    Screen.Cursor := crDefault;
  end;
end;