如何在master detail clientdatasets Delphi中维护排序顺序?

如何在master detail clientdatasets Delphi中维护排序顺序?,delphi,master-detail,tclientdataset,Delphi,Master Detail,Tclientdataset,我在公共字段“upn”上安排了两张CD作为主细节。 它们都由针对SQLite数据库运行查询的独立sql位提供。 主SQL按另一个字段对其记录进行排序。 详细信息SQL首先按“upn”对其数据进行排序,然后按另一个字段“x”对其数据进行排序 如果删除主-详细信息关系,“详细信息”数据集将按照sql确定的正确排序顺序显示记录 但是,一旦我重新创建主详细信息链接,尽管主详细信息关系可以根据upn正确地过滤详细信息记录,但详细信息数据在“x”上的排序顺序将丢失(尽管主详细信息的顺序仍然正确)。我真的说不

我在公共字段“upn”上安排了两张CD作为主细节。 它们都由针对SQLite数据库运行查询的独立sql位提供。 主SQL按另一个字段对其记录进行排序。 详细信息SQL首先按“upn”对其数据进行排序,然后按另一个字段“x”对其数据进行排序

如果删除主-详细信息关系,“详细信息”数据集将按照sql确定的正确排序顺序显示记录

但是,一旦我重新创建主详细信息链接,尽管主详细信息关系可以根据upn正确地过滤详细信息记录,但详细信息数据在“x”上的排序顺序将丢失(尽管主详细信息的顺序仍然正确)。我真的说不出细节出现的顺序,它似乎是随机的

你知道发生了什么吗?我怎样才能使细节以正确的顺序出现

其他可能有用的信息

主详图在设计时通过在详图CD中设置值进行设置,如下所示

DataSouce1.Dataset = CDS_Master
CDS_Detail.mastersource = datasource1 (which is pointing at CDS_Master)
CDS_Detail.MasterFields = upn
CDS_Detail.IndexFieldNames = upn

此外,由于这里描述的CDS错误,我在细节CDS中设置了PacketRecords=-1,您可以通过添加索引按任何顺序对细节行进行排序,尽管从性能角度来看,确保索引中的第一个字段与主数据集中的键字段相匹配通常会更好

下面是一个快速示例,它添加了两个“客户”记录,以及一个虚拟的联系人日志。它将在详细信息表中显示联系人(我使用了两个
TDBGrid
s,每个都连接到
TDataSource
,而后者又连接到
TClientDataSet
)。为了清晰起见,其他一切都是在代码中完成的。请注意,首先筛选客户机记录,使其仅与主记录(ClientDataSet1)中的当前ID匹配,然后在详细信息网格中按日期顺序排序:

procedure TForm1.FormCreate(Sender: TObject);
begin
  ClientDataSet1.FieldDefs.Add('ID', ftInteger);
  ClientDataSet1.FieldDefs.Add('CustName', ftString, 25);
  ClientDataSet1.CreateDataSet;
  ClientDataSet1.Open;
  ClientDataSet1.AppendRecord([1, 'Smith Co.']);
  ClientDataSet1.AppendRecord([2, 'Jones Bros Inc.']);
  ClientDataSet1.IndexFieldNames := 'CustName';

  ClientDataSet2.FieldDefs.Add('ID', ftInteger);
  ClientDataSet2.FieldDefs.Add('Contacted', ftDate);
  ClientDataSet2.FieldDefs.Add('Notes', ftString, 50);
  ClientDataSet2.CreateDataSet;
  ClientDataSet2.Open;
  ClientDataSet2.AppendRecord([1, EncodeDate(2014, 10, 1), 'First contact.']);
  ClientDataSet2.AppendRecord([1, EncodeDate(2014, 10, 3), 'Called again.']);

  // Intentionally added out of sequence, so effect of index will be clear.
  ClientDataSet2.AppendRecord([2, EncodeDate(2014, 9, 1), 'Order placed.']);
  ClientDataSet2.AppendRecord([2, EncodeDate(2014, 8, 15), 'Initial call.']);

  // Note indexing on both ID and Contacted fields.
  ClientDataSet2.IndexFieldNames := 'ID;Contacted';
  ClientDataSet2.MasterSource := DataSource1;
  ClientDataSet2.MasterFields := 'ID';
end;
正如您所指出的,您需要使客户机行按降序显示,您需要做更多的工作。首先,必须在首次创建ClientDataSet时创建索引。在这里,我修改了上面的代码。要在设计时执行此操作,请打开
TClientDataSet.IndexDefs
属性,然后手动在其中添加索引,并设置相同的属性。(将其更改为降序的属性是
TIndexDefs.Options
标志
ixDescending


两个问题:a)在“CDS_Detail.IndexFieldNames[:]=upn”中,您提到的字段x如何?b) CDS\U Detail中x的字段类型是否与其数据库表中的对应列一致?不要将Detail.IndexFieldNames设置为仅
'upn'
。将其设置为
'upn;而不是x'
。这将首先按
upn
进行排序,以使与master的匹配更容易,然后在upn内按“x”进行排序。如果你需要,我可以用一个例子来给出答案。1)“x”只是datail数据中的另一个字段,它不参与主-细节关系。2)我没有在CD中明确设置数据类型-我很少这样做。碰巧字段“x”(不是它的真名)是整数。@Ken。是的,尽管主控中没有字段“x”。索引字段名称中的字段数是否可以大于主字段中的字段数?我认为他们必须在数量、顺序和类型上进行匹配哇,MartynA说你是一个期望值是对的。你做得比我在设计页面上点击要快!非常感谢。呃,现在你能改变它,使细节排序下降,这可以在设计时完成吗?谢谢你,帮助我很多!
ClientDataSet1.FieldDefs.Add('ID', ftInteger);
ClientDataSet1.FieldDefs.Add('CustName', ftString, 25);
ClientDataSet1.CreateDataSet;
ClientDataSet1.Open;
ClientDataSet1.AppendRecord([1, 'Smith Co.']);
ClientDataSet1.AppendRecord([2, 'Jones Bros Inc.']);
ClientDataSet1.IndexFieldNames := 'CustName';

ClientDataSet2.FieldDefs.Add('ID', ftInteger);
ClientDataSet2.FieldDefs.Add('Contacted', ftDate);
ClientDataSet2.FieldDefs.Add('Notes', ftString, 50);
with ClientDataSet2.IndexDefs.AddIndexDef do
begin
  Name := '';
  Fields := 'Id;Contacted';
  Options := [ixDescending];
end;
ClientDataSet2.CreateDataSet;
ClientDataSet2.Open;
// Append data to ClientDataSet2 as above in first example