delphi - 如何维护主从客户端数据集Delphi中的排序顺序?

标签 delphi master-detail tclientdataset

我有两个 CDS 在公共(public)字段“upn”上排列为主从。 它们都由针对 SQLite 数据库运行查询的单独 sql 位提供。 主 SQL 按另一个字段对其记录进行排序。 详细 SQL 首先按“upn”排序其数据,然后按另一个字段“x”排序

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

然而,一旦我重新创建主从链接,尽管主从关系可以正确地根据 upn 过滤详细记录,但详细数据会丢失其在“x”上的排序顺序(尽管主从仍处于正确的顺序)。我无法真正判断细节出现的顺序,它看起来是随机的。

知道发生了什么以及如何使详细信息以正确的顺序显示吗?

其他可能有帮助的信息

主详细信息是在设计时通过在详细信息 CDS 中设置值来设置的,如下所示

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

此外,由于此处描述的 CDS 错误 http://forums.devart.com/viewtopic.php?f=28&t=25620我已在详细 CDS 中设置 PacketRecords = -1

最佳答案

您可以通过添加索引来按您想要的任何顺序对详细信息行进行排序,不过从性能角度来看,确保索引中的第一个字段与主数据集中的关键字段相匹配通常会更好。

这是一个简单的示例,添加了一些“客户”记录以及虚拟联系人日志。它将在详细信息表中显示联系人(我使用了两个 TDBGrid,每个都连接到一个 TDataSource,而该 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。)

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

关于delphi - 如何维护主从客户端数据集Delphi中的排序顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26720455/

相关文章:

delphi - 带有 alpha 混合图标的图像列表失去透明度

delphi - 我可以阻止XE8添加System.ImageList吗?

delphi - 为什么在设计时不显示 ClientDataSet 后代的字段?

android - XE5 Android 位图.canvas

delphi - 为什么 TForm.Handle 是 getter 而不是字段?

chalice : Problems with Lazy List

ios - 为什么上面的语句没有被先执行

ios - Xcode 中的 iPad 序列错误

delphi - 在运行时使用 tclientdataset 组件的参数声明事件处理程序的正确方法是什么

database - TClientdataset 的无效参数错误