如何使用C ++ Builder在FastReport中实现“sum”聚合函数

时间:2014-03-04 05:04:18

标签: c++builder fastreport

我正在使用Embarcadero RAD Studio XE5与C ++ Builder和FastReport 4.13.2。我创建了一个带有TfrxFooter波段的FastReport,它包含一个聚合“sum”函数,用于累加预安装的BCDEMOS示例数据库的employee.db表中所有行的“Salary”字段。这是一个非常简单的求和函数,但它在尝试显示报表时不断抛出访问冲突。

要在Embarcadero RAD Studio XE5中重现此问题:

  1. 创建新的C ++ Builder VCL表单应用程序。
  2. 将名为ADOConnection1的TADOConnection组件拖到窗体上。将其LoginPrompt值设置为“False”。在ConnectionStrings属性下,选择“使用数据链接文件”,然后单击“浏览”。导航到BCDEMOS.udl文件(应位于“Common Files”文件夹中)。
  3. 将名为ADODataSet1的TADODataSet组件拖到窗体上。将其连接设置为“ADOConnection1”。将其CommandText属性设置为“select * from employee;”并将其“已连接”属性设置为True。这应该创建与示例数据库的可靠连接。
  4. 将名为Button1的TButton拖到窗体上。双击该按钮以启动OnClick事件处理程序。
  5. 在OnClick事件处理程序中,粘贴以下代码:

    TfrxReport* frxReport1 = new TfrxReport(NULL);
    frxReport1->Clear();
    
    TfrxDBDataset* frxDBDataset1 = new TfrxDBDataset(NULL);
    frxReport1->DataSets->Add(frxDBDataset1);
    frxDBDataset1->DataSet = ADODataSet1;
    
    // UserName is required for aggregate functions
    frxDBDataset1->UserName = "ADODataSet1";
    
    TfrxDataPage* DataPage = new TfrxDataPage(frxReport1);
    DataPage->CreateUniqueName();
    
    TfrxReportPage* Page = new TfrxReportPage(frxReport1);
    Page->CreateUniqueName();
    
    // set sizes of fields, paper and orientation to defaults
    Page->SetDefaults();
    Page->Orientation = poPortrait;
    
    TfrxReportTitle* HeaderBand = new TfrxReportTitle(Page);
    HeaderBand->CreateUniqueName();
    HeaderBand->Top = 0;
    HeaderBand->Height = 20;
    
    TfrxMemoView* Memo = new TfrxMemoView(HeaderBand);
    Memo->CreateUniqueName();
    Memo->Text = "Report of Employee Table";
    Memo->SetBounds(0, 0, 200, 20);
    
    TfrxHeader* ColumnHeaderBand;
    ColumnHeaderBand = new TfrxHeader(Page);
    ColumnHeaderBand->CreateUniqueName();
    ColumnHeaderBand->Top = HeaderBand->Top + HeaderBand->Height;
    ColumnHeaderBand->Height = 20;
    
    TfrxMasterData* DataBand = new TfrxMasterData(Page);
    DataBand->Name = "MyDataBand";
    DataBand->DataSet = frxDBDataset1;
    DataBand->Top = ColumnHeaderBand->Top + ColumnHeaderBand->Height;
    DataBand->Height = 20;
    
    TfrxMemoView* mField;
    for (int i = 0; i < DataBand->DataSet->FieldsCount(); ++i)
    {
      const String fieldname = ADODataSet1->Fields->Fields[i]->FieldName;
    
      mField = new TfrxMemoView(ColumnHeaderBand);
      mField->CreateUniqueName();
      mField->SetBounds(i * 100, 0, 100, 20);
      mField->Text = fieldname;
      mField->HAlign = haCenter;
    
      // Now do the actual data
      mField = new TfrxMemoView(DataBand);
      mField->CreateUniqueName();
      mField->DataSet = DataBand->DataSet;
      mField->DataField = fieldname;
      mField->SetBounds(i * 100, 0, 100, 20);
      mField->HAlign = haRight;
    }
    
    // Now do footer band. This will hold the grand total salary amount
    TfrxBand* FooterBand = new TfrxFooter(Page);
    FooterBand->CreateUniqueName();
    FooterBand->Top = DataBand->Top + DataBand->Height;
    FooterBand->Height = HeaderBand->Height;
    
    TfrxMemoView* GrandTotalSalary = new TfrxMemoView(FooterBand);
    GrandTotalSalary->Top = 0;
    GrandTotalSalary->Left = 0;
    GrandTotalSalary->Height = 20;
    GrandTotalSalary->Align = baWidth;
    
    // Create a summation function that displays
    //   the grand total of every employee's salary
    // THIS LINE CAUSES THE ACCESS VIOLATION (RUNTIME ERROR)
    GrandTotalSalary->Text = "Grand Total Salary: [Sum(<ADODataSet1.'Salary'>,MyDataBand,1)]";
    
    frxReport1->ShowReport(true);
    
    delete frxDBDataset1;
    delete frxReport1;
    
    return;
    
  6. 将此项目转换为Delphi后,我能够使程序成功运行,我可以确认Delphi中的正确语法是:GrandTotalSalary.Text := 'Grand Total Salary: [Sum(<ADODataSet1."Salary">,MyDataBand,1)]';但我需要在C ++ Builder中使用它。我相信问题是公式的简单语法错误,但我不知道正确的C ++语法是什么。

2 个答案:

答案 0 :(得分:1)

我在计算机上找不到BCDEMOS.udl文件,因此我无法重现您的问题。但是,我认为问题在于FastReports会将脚本视为Delphi中的脚本,除非指定了另一种语言。当然,报告中的脚本语言与您用于程序的语言无关。

因此,除非您专门更改报表的脚本语言(并且没有理由除非您不想使用C ++编写脚本),否则Grand Total Salary公式的语法将是相同的,无论是否您正在为您的应用程序使用Delphi或C ++ Builder。

另外,仔细观察单引号和双引号之间的区别。这使我在FastReport脚本中绊倒了几次。是使用单个还是双个是由所选的脚本语言决定的。

答案 1 :(得分:0)

转到项目 - &gt;选项 - &gt;包裹 - &gt;运行时包。将“与运行时包链接”设置为False。

此选项的默认值对于C ++ Builder为True,对于Delphi为False。这解释了为什么等效代码在Delphi中工作,但在C ++ Builder中不起作用。