簡體   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