德尔福Firedac大师详解多项

Posted

技术标签:

【中文标题】德尔福Firedac大师详解多项【英文标题】:Delphi Firedac master details multiple 【发布时间】:2017-02-02 11:41:07 【问题描述】:

我在 2 个 tdbgrid 中显示了 2 个关系主详细信息表。现在 我想在 Tedit 控件中的表格详细信息的行上显示每个字段,但现在我只查看第一组 tedit 中的第一行详细信息。

enter image description here

【问题讨论】:

是的,该项目是 VCL。然后我应该为每一行写一个查询? 我应该为每一行写一个查询吗?是的是VCL "然后我应该为每一行编写一个查询吗?"如果您在我的回答中使用 TDBCtrlGrid,则不需要。 【参考方案1】:

如果这是一个 VCL 项目(而不是 FireMonkey 项目),您可以非常简单地做到这一点。

在表单上放置一个 TDBCtrlGrid 并为详细数据集设置其 DataSource

在 IDE 中,DBCtrlGrid 将显示一系列垂直面板,其中一个为纯灰色,其他为条纹。将 db-aware 控件(如 TDBEdits)放在实心灰色面板上,设置其 DataField 属性,然后编译并运行。 DBCtrlGrid 有一个Orientation 属性,您可以根据自己的喜好将其设置为垂直或水平。

您应该看到,在运行时,DBCtrlGrid 填充了与详细记录一样多的面板实例和它包含的 db 感知组件,最多由 DBCtrlGrid 的 RowCount 属性指定的数量。如果要确保有足够的面板副本,可以尝试将RowCount 值设置为主数据集的RecordCount' of the detail dataset in theAfterScroll` 事件。

另一方面,如果它是一个 FireMonkey (FMX) 项目,因此您需要使用 LiveBindings(没有 TDBCtrlGrids),它可能可以按照与您类似的方式执行此操作会设置控件来显示主数据集的字段,但我从未尝试过。

以下最小的 VCL 项目代码摘录显示了 DBCtrlGrid 的使用;

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, DBCtrls, Grids, DBGrids, DB, DBClient,
  dbcgrids, Mask;

type
  TForm1 = class(TForm)
    cdsMaster: TClientDataSet;
    cdsDetail: TClientDataSet;
    dsMaster: TDataSource;
    dsDetail: TDataSource;
    gMaster: TDBGrid;
    dbnavMaster: TDBNavigator;
    gDetail: TDBGrid;
    dbnavDetail: TDBNavigator;
    DBCtrlGrid1: TDBCtrlGrid;
    DBEdit1: TDBEdit;  // placed in DBCtrlGrid1
    DBEdit2: TDBEdit;  // placed in DBCtrlGrid1
    procedure cdsMasterAfterScroll(DataSet: TDataSet);
    procedure FormCreate(Sender: TObject);
  private
  public
  end;

[...]

procedure TForm1.FormCreate(Sender: TObject);
var
  i,
  j : Integer;
  Field : TIntegerField;
begin
  DBEdit1.DataField := 'MasterID';
  DBEdit2.DataField := 'DetailID';

  Field := TIntegerField.Create(Self);
  Field.FieldName := 'MasterID';
  Field.DataSet := cdsMaster;
  cdsMaster.CreateDataSet;

  Field := TIntegerField.Create(Self);
  Field.FieldName := 'DetailID';
  Field.DataSet := cdsDetail;
  Field := TIntegerField.Create(Self);
  Field.FieldName := 'MasterID';
  Field.DataSet := cdsDetail;

  cdsDetail.MasterSource := dsMaster;
  cdsDetail.MasterFields := 'MasterID';
  cdsDetail.IndexFieldNames := 'MasterID;DetailID';
  cdsDetail.CreateDataSet;

  for i := 1 to 10 do begin
    cdsMaster.InsertRecord([i]);
    for j := 1 to i do
      cdsDetail.InsertRecord([j, i]);
  end;
  cdsMaster.First;
end;

procedure TForm1.cdsMasterAfterScroll(DataSet: TDataSet);
begin
  cdsDetail.DisableControls;
  try
    DBCtrlGrid1.RowCount := cdsDetail.RecordCount;
  finally
    cdsDetail.EnableControls;
  end;
end;

【讨论】:

我与数据库的连接是 Firedac 抱歉 FireDAC 应该没有任何区别,在 VCL 项目中它支持所有 Delphi 的 db-aware 组件,包括 TDBCtrlGrid。 但我没有同时看到它们,我哪里错了? 对不起,我不知道,我看不到你的项目。但是你不需要做任何特别的事情。它对我来说很好——对于一个有 3 个细节的大师,我看到 3 个 DBCtrlGrid 面板和他们的 DBEdits。 SO不赞成截图,否则我会发布一个。参见例如imageen.com/ieforum/topic.asp?TOPIC_ID=2542 抱歉,我使用 dBCtrlGrid 已经有一段时间了,我忘记了它的 RowCount 属性 - 请参阅我的答案的更新。【参考方案2】:

只需在表单上放置一个 TDBEdit,然后设置其 Datafield 属性和详细信息表的 Datasource 属性。

【讨论】:

如果您查看 OP 的屏幕截图,看起来他的主表是患者表,详细信息表是他们的处方表,他似乎已经将 TBEdits 连接到详细信息表. 但这些行仅在第一组 Tedit 上运行。我想查看所有当代 Tedit 中的所有行。即使使用 tdctrlgrid,它也不起作用。有件事让我无法理解 但是您尝试做的事情非常不切实际,因为对于每条新记录,您都需要添加更多的 TDBEdits,并记住一件事......如果您使用的是单向数据集,你不能缓冲多条记录。 @NuCarvignulu:你的 youtube 链接对我不起作用,它给我一条消息“找不到视频”。

以上是关于德尔福Firedac大师详解多项的主要内容,如果未能解决你的问题,请参考以下文章

FIREDAC记录SQL日志

FIREDAC的TFDJSONDataSets和TFDJSONDeltas查询和提交数据

(FireDAC) 连接定义

FireDAC 优势数据库连接类型

Delphi - FireDAC的连接配置

Delphi:从 IBO 迁移到 FireDac