DBGrid Column sorting: Field Index out of Range error

DAJMonk
DAJMonk used Ask the Experts™
on
Hello experts,

I'm trying to create code that would allow one to sort ascending/descending on a column in a DBGrid. This needs to work on multiple DBGrids, and especially on forms that have more than one DBGrid.

This is my code so far:

function TForm1.DBGridToggleSort(AFieldName: String; dsGrid: TClientDataSet): boolean;
var
  ix: TIndexDef;
begin
  //Reverse column sorting with each click
  if dsGrid.IndexFieldNames <> '' then
  begin
    //Sort Descending
    dsGrid.IndexFieldNames := '';
    ix := TIndexDef.Create(dsGrid.IndexDefs, AFieldName, AFieldName, [ixDescending]);
    dsGrid.IndexName := ix.Name;
  end
  else
  begin
    //Sort Ascending
    dsGrid.IndexName := '';
    dsGrid.IndexFieldNames := AFieldName;
  end;
end;

In that function, I'm passing the AFieldName (generated from the OnTitleButtonClick event) and the DBGrid's Dataset. It works fine for the most part, on forms with only one DBGrid or on the first DBGrid in a form with multiple DBGrids.

The real problem I'm having is making it work on forms with multiple DBGrids. In those cases, if I pass the dataset from the second or third DBGrid, then I get an EDataBaseError with the message "CDSDataSet: Field Index out of range". I don't get that error if I pass the dataset from the first DBGrid. I can't for the life of me figure out why it won't work with the second or third DBGrid on the form.

Additionally, using the TQuery method is out of the question as the datasets I'm operating here are in the thousands of records, and that method would otherwise overload the database server. So, I appreciate any fresh insights into this problem. Thank you!
-DAJMonk
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
I made the following test, and it worked OK. I inserted 3 ClientDataSets, 3 DataSources and 3 DBGrids in a Form, connected them in normal way (Client->DataSource->Grid), and used following code, and your procedure worked OK, maybe the error is in elsewhere .... in which  line is the error raising exactly?

// Beginning of source code

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Grids, DBGrids, DBClient, DB;

type
  TForm1 = class(TForm)
    DBGrid1: TDBGrid;
    DataSource1: TDataSource;
    DataSource2: TDataSource;
    DataSource3: TDataSource;
    ClientDataSet1: TClientDataSet;
    ClientDataSet2: TClientDataSet;
    ClientDataSet3: TClientDataSet;
    ClientDataSet1Codigo: TIntegerField;
    ClientDataSet1nome: TStringField;
    ClientDataSet2Codigo: TIntegerField;
    ClientDataSet2Teste: TStringField;
    ClientDataSet3codigo: TIntegerField;
    ClientDataSet3naci: TStringField;
    DBGrid2: TDBGrid;
    DBGrid3: TDBGrid;
    procedure DBGrid1TitleClick(Column: TColumn);
    procedure FormCreate(Sender: TObject);
  private
    function DBGridToggleSort(AFieldName: String; dsGrid: TClientDataSet): boolean;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}
function TForm1.DBGridToggleSort(AFieldName: String; dsGrid: TClientDataSet): boolean;
var
  ix: TIndexDef;
begin
 //Reverse column sorting with each click
 if dsGrid.IndexFieldNames <> '' then
 begin
   //Sort Descending
   dsGrid.IndexFieldNames := '';
   ix := TIndexDef.Create(dsGrid.IndexDefs, AFieldName, AFieldName, [ixDescending]);
   dsGrid.IndexName := ix.Name;
 end
 else
 begin
   //Sort Ascending
   dsGrid.IndexName := '';
   dsGrid.IndexFieldNames := AFieldName;
 end;
end;

procedure TForm1.DBGrid1TitleClick(Column: TColumn);
var
  dsGrid: TClientDataSet;
  AFieldName: string;
begin
  dsGrid := (Column.Grid.DataSource.DataSet as TClientDataSet);
  AFieldName := Column.FieldName;
  DBGridToggleSort(AFieldName, dsGrid);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ClientDataSet1.CreateDataSet;
  ClientDataSet2.CreateDataSet;
  ClientDataSet3.CreateDataSet;
  ClientDataSet1.Open;
  ClientDataSet2.Open;
  ClientDataSet3.Open;
end;

end.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial