Delphi XE2 中的 FastReport Master/Detail

FastReport Master/Detail in Delphi XE2

我需要一些帮助在 Fast Reports 中为 Delphi XE2 创建 Master/Detail 报告。

我有一个简单的表单,它接受来自用户的 2 个日期和 2 个时间。然后,我在用于检索数据的表单上有 2 个 Oracle 数据集。当用户按下打印按钮时,程序接受用户的值并将值发送到第一个 oracle 数据集,然后依次检索第一个值,然后将该值与用户接受的值一起发送到第二个数据集打印与检索到的值有关的详细信息。

对于每个数据集,我都有一个相应的 frxDBDataset 组件,然后将其分配给 frxReport1 组件。在报告中,我创建了一个分配给 dataset1 的 Master Band 和一个分配给 datset2 的 Detail Band。当我 运行 我的报告时,数据集 1 带回所有记录,但数据集 2 只带回第一个值的记录,并为数据集 1 中的每条记录复制它。

下面是我要执行的代码:

opr_operator_ods.Close;
opr_operator_ods.SetVariable('DATEFROM', opr_datefrom_dtp.Date);
opr_operator_ods.SetVariable('DATETO', opr_dateto_dtp.Date);
opr_operator_ods.SetVariable('TIMEFROM', opr_timefrom_dtp.Text);
opr_operator_ods.SetVariable('TIMETO', opr_timeto_dtp.Text);
opr_operator_ods.Open;

if opr_operator_ods.RecordCount > 0 then
begin
while not opr_operator_ods.Eof do
begin
opr_operatorcount_ods.Close;
opr_operatorcount_ods.SetVariable('DATEFROM', opr_datefrom_dtp.Date);
opr_operatorcount_ods.SetVariable('DATETO', opr_dateto_dtp.Date);
opr_operatorcount_ods.SetVariable('TIMEFROM', opr_timefrom_dtp.Text);
opr_operatorcount_ods.SetVariable('TIMETO', opr_timeto_dtp.Text);
opr_operatorcount_ods.SetVariable('OPERATOR',
opr_operator_ods.FieldByName('opr_code').AsString);
opr_operatorcount_ods.Open;

while not opr_operatorcount_ods.Eof do
begin
frxReport1.PrepareReport(false);
opr_operatorcount_ods.Next;
end;
frxReport1.PrepareReport(true);
opr_operator_ods.Next;
end;

DecodeDate(opr_datefrom_dtp.Date, tyear, tmonth, tday);
StartDate := '''' + IntToStr(tday) + '/' + IntToStr(tmonth) + '/' + IntToStr(tyear) + '''';
DecodeDate(opr_dateto_dtp.Date, tyear, tmonth, tday);
EndDate :=  '''' + IntToStr(tday) + '/' + IntToStr(tmonth) + '/' + IntToStr(tyear) + '''';

frxReport1.Variables['StartDate'] := StartDate;
frxReport1.Variables['EndDate'] := EndDate;

//frxReport1.PrepareReport(True);
frxReport1.ShowPreparedReport;

如何让第二个数据集移动到下一条记录的值?

此报告在 Delphi 2005 年与 RaveReports6 完美配合,但我们使用了基于代码的表单开发,它更易于使用 'writeln' 进行操作,而不像 Fast Reports 那样直观。

创建预览时,FastReport 会执行类似以下代码的操作:

while not MasterBand.DataSet.Eof do
  begin
    ...Do special FastReport's work :)
    while not DetailBand.DataSet.eof do 
      begin
        ...Do special FastReport's work :)
        DetailBand.DataSet.Next; 
      end;
    MasterBand.DataSet.Next;   
 end;

在您的代码中:

while not opr_operatorcount_ods.Eof do
begin
 frxReport1.PrepareReport(false);
 opr_operatorcount_ods.Next; <-- here opr_operatorcount_ods is in the last position from PrepareReport 
end;  

Data bands可以是master或detail类型,但它们只控制输出页面数据的定位 (顺序和显示次数)。 带中对象显示的数据取决于两个(或多个)数据集之间的关系。 所以你应该建立关系

可以通过多种方式建立关系。 如果你想使用参数,你可以这样做:

  • 放置DataSource组件。

  • 使用 DataSet属性DataSet = opr_operator_ods;

  • 将其连接到数据集 1(opr_operator_ods)
  • 在DataSource.OnDataChange事件中写入:

      opr_operatorcount_ods.Close;
      ......
      //Set parameter(relation between opr_operator(Master) and opr_operatorcount(Detail)   
      opr_operatorcount_ods.Params.ParamByName('opr_code').asString :=   opr_operator_ods.FieldByName('opr_code').AsString);            
      opr_operatorcount_ods.Open;
    

然后准备并打印报告:

procedure Print;
begin
  //Prepare Master dataset ( parameters, close open etc.) like :
  opr_operator_ods.Close;
  opr_operator_ods.SetVariable('DATEFROM', opr_datefrom_dtp.Date); 
  opr_operator_ods.SetVariable('DATETO', opr_dateto_dtp.Date);
  opr_operator_ods.SetVariable('TIMEFROM', opr_timefrom_dtp.Text);
  opr_operator_ods.SetVariable('TIMETO', opr_timeto_dtp.Text);
  opr_operator_ods.Open;
  ... 
  frxReport1.PrepareReport;
  frxReport1.ShowPreparedReport;
end;