【发布时间】:2014-10-03 01:05:59
【问题描述】:
我正在使用 Embarcadero RAD Studio XE7、C++ Builder 和 FastReport 5。我创建了一个非常简单的 FastReport,它将表格中的一些值相加并打印出一个总数。我无法正确获取求和公式的语法,因此它不断抛出访问冲突错误。
要在 RAD Studio XE7 中重现此问题:
- 打开 RAD Studio XE7 并转到 File -> New -> VCL Forms Application - C++Builder
- 将名为 ClientDataSet1 的 TClientDataSet 组件拖到窗体上。将名为 frxReport1 的 TfrxReport 组件拖到窗体上。将名为 frxDBDataset1 的 TfrxDBDataset 拖到窗体上。
- 将一个名为 Button1 的 TButton 拖到窗体上,然后双击它以创建一个 OnClick 事件处理程序。
-
将以下行添加到 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!"); 编译并运行程序。 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)]";
不过,我仍然遇到访问冲突。
【问题讨论】:
-
两件事:1) Totals 的文本提到了“MyDataBand”,但您的数据带实际上称为“DataBand”。 2)它没有在您的代码中显示数据集的名称。这是 frxDBDataset1 的一个属性。它不必与实际数据集同名。 - 语法,至少我拥有和工作的语法是这样的:[SUM(
,BandName,1)] -
进行这些修改后,我仍然收到访问冲突错误。请参阅上面的更新。
-
你运行的是什么版本的FR?我能够通过一些修改运行程序(所有这些都是我们之前讨论过的),没有任何问题。我正在使用 FR 4.15.5 运行 XE5。
-
我使用的是 FastReport 5.1.5 版。它是 Embarcadero RAD Studio XE7 预装的版本。
标签: c++builder fastreport