Problem with "sum" formula in FastReport VCL 5 using C++Builder.
I am using Embarcadero RAD Studio XE7, C++ Builder with FastReport VCL 5. I create a very simple FastReport that adds up some values in a table and prints out a total. I cannot get the syntax for the sum formula correct, and as a result it keeps throwing an access violation error.
Here are the exact steps to reproduce this problem:
- Open RAD Studio XE7 and go to File -> New -> VCL Forms Application - C++Builder.
- Drag a TClientDataSet component named ClientDataSet1 onto the form. Drag a TfrxReport component named frxReport1 onto the form. Drag a TfrxDBDataset named frxDBDataset1 onto the form.
- Drag a TButton named Button1 onto the form, and double-click it to create an OnClick event handler.
- Add the following lines to the Button1Click event handler:
The code in the try block will throw an access violation.
Why is this happening? What is the correct syntax to create the sum formula?
Here are the exact steps to reproduce this problem:
- Open RAD Studio XE7 and go to File -> New -> VCL Forms Application - C++Builder.
- Drag a TClientDataSet component named ClientDataSet1 onto the form. Drag a TfrxReport component named frxReport1 onto the form. Drag a TfrxDBDataset named frxDBDataset1 onto the form.
- Drag a TButton named Button1 onto the form, and double-click it to create an OnClick event handler.
- Add the following lines to the Button1Click event handler:
    // 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!");
- Compile and run the program. Click on the button to create the report.The code in the try block will throw an access violation.
The following error(s) have occured:
Access violation at address 0025452C in module 'fs21.bpl'. Read of address 00000000
Why is this happening? What is the correct syntax to create the sum formula?
Comments
totals->Text = "Totals: [Sum(<ClientDataSet1.\"volume\">, DataBand, 1)]";