skafinski
skafinski

Reputation: 314

Find next record in sorted TDBGrid

I have TDBGrid on witch I have connected FDQuery. I sort records on fly with use of FDQuery indexes when column title is clicked.

procedure TMainDM.CreateIndexes(AQuery: TFDQuery);
var
  I: Integer;
begin
  try
    AQuery.Indexes.Clear;
    for I := 0 to AQuery.FieldCount - 1 do
    begin
      with AQuery.Indexes.Add do
      begin
        Name := AQuery.Fields[i].FieldName + '_index_asc';
        Fields:= AQuery.Fields[i].FieldName;
        Options:= [soNoCase];
        Active:= True;
      end;
      with AQuery.Indexes.Add do
      begin
        Name := AQuery.Fields[i].FieldName + '_index_desc';
        DescFields:= AQuery.Fields[i].FieldName;
        Fields:= AQuery.Fields[i].FieldName;
        Active:= True;
      end;
    end;
  except
    on E: Exception do
      ErrorLogger('ERROR: TMainDM.CreateIndexes -> ' + E.Message);
  end;
end;

How would I get next record from currently selected? I know that I move to next record of unsorted grid with this:

DBGrid.DataSource.Dataset.Next;

I know that I move to next record in filtered grid with this:

DBGrid.DataSource.Dataset.FindNext;

How can I find next record in sorted list? When I call Next or FindNext I get next record of unsorted grid.

EDIT 1

I had FDQuery property IndexName set to index selected in event OnColumnSort.

if Direction then
  TFDQuery(TaskDataSource.DataSet).IndexName:= Column.FieldName + '_index_asc'
else
  TFDQuery(TaskDataSource.DataSet).IndexName:= Column.FieldName + '_index_desc';

I get result described above. In first code block I create indexes for all fields so they are ready to be called in seconde code block (event OnColumnSort)

EDIT 2

I've changed some code. I put index creation in the event OnColumnSort so there isn't index for every field on start. Query.Next still doesn't work.

procedure TMain.TaskGridColumnSort(Column: TUniDBGridColumn;
  Direction: Boolean);
begin
  try
    TFDQuery(TaskDataSource.DataSet).Indexes.Clear;
    if Direction then
    begin
      with TFDQuery(TaskDataSource.DataSet).Indexes.Add do
      begin
        Name := Column.FieldName + '_index_asc';
        Fields:= Column.FieldName;
        Options:= [soNoCase];
        Active:= True;
      end;
      TFDQuery(TaskDataSource.DataSet).IndexName:= Column.FieldName + '_index_asc';
    end
    else
    begin
      with TFDQuery(TaskDataSource.DataSet).Indexes.Add do
      begin
        Name := Column.FieldName + '_index_desc';
        DescFields:= Column.FieldName;
        Fields:= Column.FieldName;
        //Options:= [soDescending, soNoCase];
        Active:= True;
      end;
      TFDQuery(TaskDataSource.DataSet).IndexName:= Column.FieldName + '_index_desc';
    end;

  except
    on E: Exception do
      MainDM.ErrorLogger('ERROR: TMain.TaskGridColumnSort -> ' + E.Message);
  end;

end;

Upvotes: 0

Views: 584

Answers (2)

skafinski
skafinski

Reputation: 314

FINAL EDIT

I found the problem. Problem was in closing and reopening dataset. So sort (index) lost in Refresh. I solve problem with remembering my index name before I Close dataset and place it back when i Open dataset.

Upvotes: 0

MartynA
MartynA

Reputation: 30715

I think you may be having the same problem as this q:

Indexes don't work in FDQuery

What you need to do is to add the line

AQuery1.IndexName := AIndex.Name;

as the last line before your except block.

Btw, the sorting is nothing to do with the grid, of course. Once the index is properly active, the grid will display in the correct order and calls to AQuery.Next should behave as expected.

Upvotes: 2

Related Questions