Search Results for

    Show / Hide Table of Contents

    Bidirectional reports (Delphi)

    Note

    This demo is available in your FlexCel installation at <FlexCel Install Folder>\Demo\Delphi\Modules\20.Reports\42.Bidirectional Reports and also at https:​//​github.​com/​tmssoftware/​TMS-​FlexCel.​VCL-​demos/​tree/​master/​Delphi/​Modules/​20.​Reports/​42.​Bidirectional Reports

    Overview

    In this example we will create a report that grows both horizontally and vertically.

    Concepts

    • Normally ranges in FlexCel reports can't intercept. But there is an exception: If you define a range in the shape of a cross, FlexCel will do a bidirectional report.

    • In Bidirectional reports the row range acts as the master, and the column range as the detail. You can have more than one column range for the same row, but not more than one row range for the same column.

    • In this example we have two different column reports using the same row report. In the first column we show which employees have orders for a given customer, and in the second we show the orders for that customer.

    • Those two columns are conceptually different: In the first we use a column and row dataset which are not related. This will create a square with all the records of the column dataset for the column, and all the records of the row dataset for the rows. In the second column, the column dataset (orders) is related to the row dataset (customers). So the number of columns will be different for each row, depending in how many orders that customer has. FlexCel will insert as many columns as the maximum numbers of orders for any customer.

    • You can look at the User Defined Functions example for another demo on how bidirectional reports work.

    Files

    UMainForm.pas

    unit UMainForm;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics,
      FlexCel.VCLSupport, FlexCel.Core, FlexCel.XlsAdapter, FlexCel.Report, FlexCel.Render,
      {$if CompilerVersion >= 23.0} System.UITypes, {$IFEND}
      ShellApi,
      Controls, Forms, Dialogs, StdCtrls, ExtCtrls;
    
    type
      TMainForm = class(TForm)
        btnCancel: TButton;
        btnGo: TButton;
        SaveDialog: TSaveDialog;
        Label1: TLabel;
        procedure btnCancelClick(Sender: TObject);
        procedure btnGoClick(Sender: TObject);
      private
        procedure RunReport;
        function GetDataPath: string;
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      MainForm: TMainForm;
    
    implementation
    uses IOUtils, DemoOrders;
    
    {$R *.dfm}
    
    procedure TMainForm.btnCancelClick(Sender: TObject);
    begin
      Close;
    end;
    
    procedure TMainForm.btnGoClick(Sender: TObject);
    begin
      RunReport;
    
    end;
    
    function TMainForm.GetDataPath: string;
    begin
      Result := TPath.Combine(TPath.GetDirectoryName(ParamStr(0)), '..\..');
    end;
    
    
    procedure TMainForm.RunReport;
    var
      Report: TFlexCelReport;
    begin
      if not SaveDialog.Execute then exit;
    
      Report := TFlexCelReport.Create(true);
      try
        Report.AddTable('Employees', DemoTables.Employees);
        Report.AddTable('Customers', DemoTables.Customers);
        Report.AddTable('Orders', DemoTables.Orders);
    
        //Orders here has 2 master-detail relationships: With Employees and Customer.
        //We can't represent that with normal delphi master-detail relationships as each
        //detail dataset can have only one master. So we will use FlexCel relationships instead.
        Report.AddRelationship('Employees', 'Orders', 'EmployeeId', 'EmployeeId');
        Report.AddRelationship('Customers', 'Orders', 'CustomerId', 'CustomerId');
    
        Report.Run(
          TPath.Combine(GetDataPath, 'Bidirectional Reports.template.xlsx'),
          SaveDialog.FileName);
      finally
        Report.Free;
      end;
    
      if MessageDlg('Do you want to open the generated file?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
      begin
        ShellExecute(0, 'open', PCHAR(SaveDialog.FileName), nil, nil, SW_SHOWNORMAL);
      end;
    
    
    end;
    
    end.
    
    In This Article
    Back to top FlexCel Studio for VCL and FireMonkey v7.24
    © 2002 - 2025 tmssoftware.com