【问题标题】:How to implement a "sum" aggregate function in FastReport using C++Builder如何使用 C++Builder 在 FastReport 中实现“sum”聚合函数
【发布时间】:2014-03-04 05:04:18
【问题描述】:

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

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

  1. 创建一个新的 C++ Builder VCL Forms 应用程序。
  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;
    

将此项目转换为Delphi后,我能够让程序成功运行,并且我可以确认Delphi中的正确语法是:GrandTotalSalary.Text := 'Grand Total Salary: [Sum(&lt;ADODataSet1."Salary"&gt;,MyDataBand,1)]';但我需要它才能在C++Builder中工作。我认为问题是公式的简单语法错误,但我不知道正确的 C++ 语法是什么。

【问题讨论】:

    标签: c++builder fastreport


    【解决方案1】:

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

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

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

    【讨论】:

    • Re: BCDEMOS.udl 文件:也可以叫 DBDEMOS.udl。我尝试使用完全相同的 Delphi 代码行,但没有成功。您提到明确指定使用 C++ 作为脚本语言。我以前从未听说过。你是怎样做的?这绝对值得一试。
    • 我所指的脚本语言是在 FastReports 中。您输入到 FastReports 设计器本身的所有代码都是脚本语言。默认为 Delphi,但 C++(和其他)可用 - 它们被选为报表设计器中的一个选项。对于大多数简单的表达式,这可能无关紧要,但是使用单引号还是双引号取决于您选择的(或默认使用的)脚本语言。
    【解决方案2】:

    转到项目 --> 选项 --> 包 --> 运行时包。将“与运行时包的链接”设置为 False。

    此选项的默认值对于 C++Builder 为 True,对于 Delphi 为 False。这就解释了为什么等效代码在 Delphi 中有效,但在 C++Builder 中无效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-07
      • 2020-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多