-->

How to sort a ClientDataSet on a calculated field?

2019-05-10 19:48发布

问题:

I'm trying to sort a ClientDataSet on a calculated boolean field, but for some reason the data is not sorted. I have a boolean field named Highlight with FieldKind set to fkInternalCalc, and an index defined like this:

IndexDefs[0].DescFields = 'Highlight';
IndexDefs[0].Fields = 'Highlight;PatNo';
IndexDefs[0].Name = 'PatNo';
IndexDefs[0].Options = [ixDescending];

and obviously I have set my client dataset's IndexName to 'PatNo'. When I run my application, the data in the CDS is sorted on PatNo field only. Any thoughts?

回答1:

Ime, indexing a ClientDatasSet on a compound index including an fkInternalCalc field works fine.

The code below works in D7 and XE6, and with Midas.Dll version ten years apart, giving

So, unless there was some kind of regression in XE2, I would suspect the problem reported was in something at the OP's end.

 // tested with:
//  midas.dll 7.1.1692.668 30 August 2004
//  midas.dll 20.0.16277.1276  16 June 2014

procedure TForm1.SetUp;
var
  Field : TField;
  i : Integer;
begin
  Field := TIntegerField.Create(Self);
  Field.FieldName := 'PatNo';
  Field.FieldKind := fkData;
  Field.Index := 0;
  Field.DataSet := CDS;

  Field := TBooleanField.Create(Self);
  Field.FieldName := 'HighLight';
  Field.FieldKind := fkInternalCalc;
  Field.Index := 1;
  Field.DataSet := CDS;

  CDS.OnCalcFields := CDSCalcFields;

  CDS.CreateDataSet;
  for i := 1 to 10 do begin
    CDS.Insert;
    CDS.FieldByName('PatNo').AsInteger := i;
    CDS.Post;
  end;
end;

procedure TForm1.CDSCalcFields(DataSet: TDataSet);
var
  Value : Integer;
begin
  Value := DataSet.FieldByName('PatNo').AsInteger;
  DataSet.FieldByName('Highlight').AsBoolean := Odd(Value);
end;

const
  scIndexName = 'PatNo';
  scHighlight = 'Highlight';

procedure TForm1.AddHLIndex;
var
  IndexDef : TIndexDef;
begin
  IndexDef := TIndexDef.Create(CDS.IndexDefs, scIndexName, 'Highlight;PatNo', [ixDescending]);
  IndexDef.DescFields := scHighlight;
  CDS.IndexName := scIndexName;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  AddHLIndex;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  SetUp;
end;