繁体   English   中英

FastReport(RAD Studio XE7 C ++ Builder)-如何创建求和公式?

[英]FastReport (RAD Studio XE7 C++ Builder) - How do you create a sum formula?

我正在将Embarcadero RAD Studio XE7和C ++ Builder与FastReport 5一起使用。我创建了一个非常简单的FastReport,它将表中的一些值相加并打印出总计。 我无法正确获得sum公式的语法,因此,它不断抛出访问冲突错误。

要在RAD Studio XE7中重现此问题:

  1. 打开RAD Studio XE7并转到文件->新建-> VCL表单应用程序-C ++ Builder
  2. 将一个名为ClientDataSet1的TClientDataSet组件拖到窗体上。 将一个名为frxReport1的TfrxReport组件拖到窗体上。 将一个名为frxDBDataset1的TfrxDBDataset拖到窗体上。
  3. 将一个名为Button1的TButton拖到窗体上,然后双击以创建OnClick事件处理程序。
  4. 将以下行添加到Button1Click事件处理程序中:

     // Create a simple dataset. ClientDataSet1->FieldDefs->Clear(); ClientDataSet1->FieldDefs->Add("ID", ftInteger, 0, false); ClientDataSet1->FieldDefs->Add("Status", ftString, 10, false); ClientDataSet1->FieldDefs->Add("Created", ftDate, 0, false); ClientDataSet1->FieldDefs->Add("Volume", ftInteger, 0, false); try { ClientDataSet1->CreateDataSet(); } catch(Exception& e) { ShowMessage("ERROR: '" + e.Message + "'"); return; } ClientDataSet1->Open(); for (int i = 0; i < 10; ++i) { ClientDataSet1->Append(); ClientDataSet1->FieldByName("ID")->AsInteger = i; ClientDataSet1->FieldByName("Status")->AsString = "Code" + String(i); ClientDataSet1->FieldByName("Created")->AsDateTime = Now(); ClientDataSet1->FieldByName("Volume")->AsInteger = Random(1000); try { ClientDataSet1->Post(); } catch(Exception& e) { ShowMessage("ERROR: '" + e.Message + "'"); ClientDataSet1->Close(); return; } } // Dataset created successfully, now create Fast Report that outputs that dataset frxReport1->Clear(); frxDBDataset1->DataSet = (TDataSet*)ClientDataSet1; frxReport1->DataSets->Add(frxDBDataset1); 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 = "Generic Report"; 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 = "DataBand"; 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 = ClientDataSet1->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 total TfrxBand* FooterBand = new TfrxFooter(Page); FooterBand->CreateUniqueName(); FooterBand->Top = DataBand->Top + DataBand->Height; FooterBand->Height = HeaderBand->Height; TfrxMemoView* totals = new TfrxMemoView(FooterBand); totals->Top = 0; totals->Left = 0; totals->Height = 20; totals->Align = baWidth; bool is_error = false; try { // ALL OF THESE LINES CAUSE THE ACCESS VIOLATION // Create a summation function that displays the volume total totals->Text = "Totals: [Sum(<ClientDataSet1.Volume>, MyDataBand, 1)]"; //totals->Text = "Totals: [Sum(<ClientDataSet1.'volume'>,MyDataBand,1)]"; //totals->Text = "Totals: [Sum(<ClientDataSet1.\\"volume\\">,MyDataBand,1)]"; //totals->Text = "Totals: [Sum(<ClientDataSet1.""volume"">,MyDataBand,1)]"; //totals->Text = "Totals: [Sum(<ClientDataSet1.''volume''>,MyDataBand,1)]"; //totals->Text = "Totals: [Sum(<ClientDataSet1.\\'volume\\'>,MyDataBand,1)]"; } catch(Exception& e) { ShowMessage("ERROR: '" + e.Message + "'"); is_error = true; } if (!is_error) { frxReport1->ShowReport(true); } ClientDataSet1->Close(); ShowMessage("Program complete!"); 
  5. 编译并运行程序。 try块中的代码将引发访问冲突。 为什么会这样呢? 创建求和公式的正确语法是什么?

更新:

我通过显式设置frxDBDataset1的名称来修改代码:

    frxReport1->Clear();
    frxDBDataset1->DataSet = (TDataSet*)ClientDataSet1;
    frxDBDataset1->Name = "frxDBDataset1"; // line added
    frxReport1->DataSets->Add(frxDBDataset1);

我还将公式行更改为以下内容:

    totals->Text = "Totals: [Sum(<frxDBDataset1.\"Volume\">, DataBand, 1)]";

但是,我仍然遇到访问冲突。

下面的链接示例能够毫无问题地运行,其中包括我们之前评论的修改。

https://www.dropbox.com/s/6grmajvoy9ijxfh/SO_test1.7z?dl=0

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM