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:
    // 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.
wrote:
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

  • gpigpi
    edited 9:00PM
    Use

    totals->Text = "Totals: [Sum(<ClientDataSet1.\"volume\">, DataBand, 1)]";
  • edited 9:00PM
    That also didn't work. I am getting the same error. Here is my revised code:
    void __fastcall TfrFastReportsDemo::Button1Click(TObject *Sender)
    {
        // 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
        {
          // Create a summation function that displays the volume total
          totals->Text = "Totals: [Sum(<ClientDataSet1.\"Volume\">, DataBand, 1)]";
        }
        catch(Exception& e)
        {
          ShowMessage("ERROR: '" + e.Message + "'");
          is_error = true;
        }
    
        if (!is_error)
        {
          frxReport1->ShowReport(true);
        }
    
        ClientDataSet1->Close();
    
        ShowMessage("Program complete!");
      return;
    }
    

Leave a Comment