Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7649885
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 31, 20262026-05-31T11:06:30+00:00 2026-05-31T11:06:30+00:00

I use FastReport and I need to preview/print Grids with more than 1000 rows

  • 0

I use FastReport and I need to preview/print Grids with more than 1000 rows and I have some performances problems.
Typically I use TfrxCrossObject to prepare my grid because the end user may change the grid presentation (used columns, column’s name, size) so I need to have a dynamical print.
I tested a simple grid (16 cols x2000 rows) and it needs more than 10 seconds to present the first preview page.
Any idea to improve performances ?

EDIT :
As said in some answers, the problem is : how to create ‘dynamicaly’ a grid (with same columns names and sizes that I have on screen) in FastReport without using TFrxCrossObject which seems to be not very efficent. I may admit all solutions like using DataSet or enhancing TfrxCrossObject.

The test code :

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  frxClass, StdCtrls, Grids, frxCross;

type
  TForm1 = class(TForm)
    Button1: TButton;
    StringGrid1: TStringGrid;
    frxCrossObject1: TfrxCrossObject;
    frxReport1: TfrxReport;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure frxReport1BeforePrint(c: TfrxReportComponent);
  end;

var
  Form1: TForm1;

implementation
{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
var
  i, j: Integer;
begin
  for i := 1 to 16 do
    for j := 1 to 2000 do
      StringGrid1.Cells[i - 1, j - 1] := IntToStr(i * j);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  frxReport1.ShowReport;
end;

procedure TForm1.frxReport1BeforePrint(c: TfrxReportComponent);
var
  Cross: TfrxCrossView;
  i, j: Integer;
begin
  if c is TfrxCrossView then
  begin
    Cross := TfrxCrossView(c);
    for i := 1 to 16 do
      for j := 1 to 2000 do
        Cross.AddValue([i], [j], [StringGrid1.Cells[i - 1, j - 1]]);
  end;
end;
end.
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-31T11:06:31+00:00Added an answer on May 31, 2026 at 11:06 am

    The CrossTab have many overhead. Here is a UserDataSet version :

    1. Just drop 1 stringgrid, 1 button, 1 frxReport, 1 frxUserDataSet in the form.

    2. Set the frxUserDataSet events, Form OnCreate and Buttom OnClick as below code.

    3. No need to Design Report or set any properties, All will be set or generated at run-time.

    It seems it is faster than the cross-tab version but you need more coding and lost functionality of CrossObject.

    Edit : Add some comments and fix PaperWidth mis-calculation.

    Edit2 : Add a print-friendly version which split data into pages.

    View Friendly version show in 1 single page as the stringgrid :

    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, frxClass, Grids, StdCtrls;
    
    type
      TForm1 = class(TForm)
        Button1: TButton;
        StringGrid1: TStringGrid;
        frxReport1: TfrxReport;
        frxUserDataSet1: TfrxUserDataSet;
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure frxUserDataSet1Next(Sender: TObject);
        procedure frxUserDataSet1GetValue(const VarName: string; var Value: Variant);
        procedure frxUserDataSet1CheckEOF(Sender: TObject; var Eof: Boolean);
        procedure frxUserDataSet1First(Sender: TObject);
      private
        X, Y, TCol, TRow : Integer;
        IsEof : Boolean;
        CW, CH, PF : Double;
        Page : TfrxReportPage;
        MDB : TfrxMasterData;
        Memo : TfrxMemoView;
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      BW : Double;
    begin
      IsEof := False;
      Page.PaperWidth :=  CW * TCol + 20; // EndlessWidth seems not work with band column
      MDB.SetBounds(0,0, CW * PF * TCol, CH * PF);
      MDB.Columns := TCol;
      MDB.ColumnWidth := CW * PF;
      frxReport1.ShowReport;
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    var
      i, j : Integer;
    begin
      CW := 12; // Cell Width in mm
      CH := 5;  // Cell Height in mm
      PF := 3.7794; // Pixie Factor i.e. the conversion of mm to FR component measurement
      TCol := 2000; // Total Column
      TRow := 16; // Total Row
    
      for i := 1 to TRow do
        for j := 1 to TCol do
          StringGrid1.Cells[i - 1, j - 1] := IntToStr(i * j);
    
      frxUserDataSet1.Fields.Text := 'Data';
      frxReport1.Clear;
      frxReport1.DataSets.Add(frxUserDataSet1);
      Page := TfrxReportPage.Create(frxReport1);
      Page.CreateUniqueName;
      Page.TopMargin := 10;
      Page.BottomMargin := 10;
      Page.LeftMargin := 10;
      Page.RightMargin := 10;
      Page.EndlessHeight := True;
      Page.EndlessWidth := True;
      MDB := TfrxMasterData.Create(Page);
      MDB.DataSet := frxUserDataSet1;
      Memo := TfrxMemoView.Create(MDB);
      Memo.SetBounds(0,0,CW * PF,CH * PF);
      Memo.Memo.Text := '[frxUserDataSet1."Data"]';
      Memo.Frame.Typ := [ftLeft, ftRight, ftTop, ftBottom];
    end;
    
    procedure TForm1.frxUserDataSet1CheckEOF(Sender: TObject; var Eof: Boolean);
    begin
      Eof := IsEof;
    end;
    
    procedure TForm1.frxUserDataSet1First(Sender: TObject);
    begin
      X := 0;
      Y := 0;
    end;
    
    procedure TForm1.frxUserDataSet1GetValue(const VarName: string; var Value: Variant);
    begin
      Value := StringGrid1.Cells[X,Y];
    end;
    
    procedure TForm1.frxUserDataSet1Next(Sender: TObject);
    begin
      If Y = TCol - 1 then
      begin
        if X = TRow - 1 then
          IsEof := True;
        Inc(X);
        Y := 0;
      end
      else
        Inc(Y);
    end;
    
    end.
    

    Print-friendly version which is a bit more complex and separate data in different pages for printing :

    unit Unit1;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, frxClass, Grids, StdCtrls;
    
    type
      TForm1 = class(TForm)
        Button1: TButton;
        StringGrid1: TStringGrid;
        frxReport1: TfrxReport;
        frxUserDataSet1: TfrxUserDataSet;
        procedure Button1Click(Sender: TObject);
        procedure FormCreate(Sender: TObject);
        procedure frxUserDataSet1Next(Sender: TObject);
        procedure frxUserDataSet1GetValue(const VarName: string; var Value: Variant);
        procedure frxUserDataSet1CheckEOF(Sender: TObject; var Eof: Boolean);
        procedure frxUserDataSet1First(Sender: TObject);
      private
        X, Y, TCol, TRow, RPP, ColBreak : Integer;
        IsEof : Boolean;
        CW, CH, PF : Double;
        Page : TfrxReportPage;
        MDB : TfrxMasterData;
        Memo : TfrxMemoView;
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    uses Math;
    
    {$R *.dfm}
    
    
    procedure TForm1.Button1Click(Sender: TObject);
    var
      BW : Double;
    begin
      IsEof := False;
      RPP := Ceil((Page.PaperHeight - Page.TopMargin - Page.BottomMargin) / CH) - 1; // Row per page
      ColBreak := RPP; // break to next column
    
      frxReport1.ShowReport;
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    var
      i, j : Integer;
    begin
      CW := 12; // Cell Width in mm
      CH := 5;  // Cell Height in mm
      PF := 3.7794; // Pixil Factor i.e. the conversion of mm to FR component measurement
      TCol := 2000; // Total Column
      TRow := 16; // Total Row
    
      for i := 1 to TRow do
        for j := 1 to TCol do
          StringGrid1.Cells[i - 1, j - 1] := IntToStr(i * j);
    
      frxUserDataSet1.Fields.Text := 'Data';
      frxReport1.Clear;
      frxReport1.DataSets.Add(frxUserDataSet1);
      Page := TfrxReportPage.Create(frxReport1);
      Page.CreateUniqueName;
      Page.TopMargin := 10;
      Page.BottomMargin := 10;
      Page.LeftMargin := 10;
      Page.RightMargin := 10;
      Page.Columns := Ceil(Page.PaperWidth / CW);
      MDB := TfrxMasterData.Create(Page);
      MDB.DataSet := frxUserDataSet1;
      MDB.SetBounds(0,0, CW * PF, CH * PF);
      Memo := TfrxMemoView.Create(MDB);
      Memo.Align := baClient;
      Memo.Memo.Text := '[frxUserDataSet1."Data"]';
      Memo.Frame.Typ := [ftLeft, ftRight, ftTop, ftBottom];
    end;
    
    procedure TForm1.frxUserDataSet1CheckEOF(Sender: TObject; var Eof: Boolean);
    begin
      Eof := IsEof;
    end;
    
    procedure TForm1.frxUserDataSet1First(Sender: TObject);
    begin
      X := 0;
      Y := 0;
    end;
    
    procedure TForm1.frxUserDataSet1GetValue(const VarName: string; var Value: Variant);
    begin
      Value := StringGrid1.Cells[X,Y];
    end;
    
    procedure TForm1.frxUserDataSet1Next(Sender: TObject);
    begin
      If X = TRow - 1 then
      begin
        if Y = TCol - 1 then
          IsEof := True
        else
        begin
          frxReport1.Engine.NewColumn;
          Inc(Y);
          X := ColBreak - RPP;
        end;
      end
      else if (X = ColBreak - 1) then
      begin
        if Y = TCol - 1 then
        begin
          frxReport1.Engine.NewPage;
          ColBreak := ColBreak + RPP;
          Y := 0;
        end
        else
          Inc(Y);
        frxReport1.Engine.NewColumn;
        X := ColBreak - RPP;
      end
      else
        Inc(X);
    end;
    
    end.
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Use case: we have some project meta-data files which we want tracked, but are
I have spent several days so far laying the ground work to use FastReport
use strict; use warnings; use Time::HiRes qw(sleep); use Test::WWW::Selenium; use Test::More no_plan; use Test::Exception;
use Text::Diff; for($count = 0; $count <= 1000; $count++){ my $data_dir=archive/oswiostat/oracleapps.*dat; my $data_file= `ls
use Control::CLI; $cli = new Control::CLI('SSH'); $cli->connect(Host=>'10.10.10.10',Username=>'user',Password=>'pwd'); $cli->waitfor('>'); $cli->print('Show XXXXXXXXXXXXXXXXXXXX| grep Active'); @f=$cli->waitfor('>'); print
Use Elixir and have two entities -- Voter and Candidate -- with many to
use javascript or other method ? have any recommendation?
use warnings; use Test::More; use File::Find::Rule; use Test::File::Find::Rule; my $rule = File::Find::Rule->file->name('*.pl')->not_grep(qr/^\s*use\s+strict;/m, sub {
Use case: You have 2-3 files displayed in your MacVim window(s). You press ctrl+Q
Use case is to have a server connect to thousands of users email accounts

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.