Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Repeating QRLabels in QuickReport


This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 6 - Last Post: Feb 16, 2016 4:33 AM Last Post By: Robert Triest Threads: [ Previous | Next ]
Benson Eze

Posts: 11
Registered: 3/7/16
Repeating QRLabels in QuickReport  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 9, 2016 11:56 AM
Hi,

I create a simple page with 1 band and two labels and I will like to fill the report with the following info (See the PS: section).

Here I have two QRLabels (RepeatCompany: TQRLabel; RepeatOrderNo: TQRLabel; horizontally placed) in the detail band.

How can I sequentially repeat the QRLabels downward? Using just the two QRLabels to populate the entire report.

Here, the "mycounter : Integer" should take care of downward propagation.

The length of the report is not known before hand. It depends on the outcome of the clause:
"If Amountcaller1 <> 0 then begin"
up to
"If Amountcaller60 <> 0 then begin"

Here, AmountCallers are of the type Integer.

Any help on how to cleverly accomplish this task will be highly appreciated. THANKS!

Regards,
Benson


PS: Info

If AmountCaller1 <> 0 then begin
RepeatCompany.Caption := 'Company1'; RepeatOrderNo.Caption := 'Order1; end;

If AmountCaller2 <> 0 then begin
RepeatCompany.Caption := 'Company2'; RepeatOrderNo.Caption := 'Order2; end;

If AmountCaller3 <> 0 then begin
RepeatCompany.Caption := 'Company3'; RepeatOrderNo.Caption := 'Order3; end;

If AmountCaller4 <> 0 then begin
RepeatCompany.Caption := 'Company4'; RepeatOrderNo.Caption := 'Order4; end;

If AmountCaller5 <> 0 then begin
RepeatCompany.Caption := 'Company5'; RepeatOrderNo.Caption := 'Order5; end;

If AmountCaller6 <> 0 then begin
RepeatCompany.Caption := 'Company6'; RepeatOrderNo.Caption := 'Order6; end;

If AmountCaller7 <> 0 then begin
RepeatCompany.Caption := 'Company7'; RepeatOrderNo.Caption := 'Order7; end;

If AmountCaller8 <> 0 then begin
RepeatCompany.Caption := 'Company8'; RepeatOrderNo.Caption := 'Order8; end;

//And so on.......AmountCaller9 .... AmountCaller60

unit Rptsub;
 
interface
 
uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, DB, DBTables, Qrctrls, quickrpt, ExtCtrls;
 
type
  TfrmReport = class(TForm)
    QuickRep1: TQuickRep;
    DetailBand1: TQRBand;
 
    RepeatCompany: TQRLabel;
    RepeatOrderNo: TQRLabel;
    
    procedure DetailBand1BeforePrint(Sender: TQRCustomBand;
      var PrintBand: Boolean);
  private
    mycounter : Integer;
    { Private declarations }
  public
    { Public declarations }
  end;
 
var
  frmReport: TfrmReport;
 
implementation
 
{$R *.DFM}
 
procedure TfrmReport.DetailBand1BeforePrint(Sender: TQRCustomBand;
  var PrintBand: Boolean);
begin
               //QRLabel: RepeatCompany, RepeatOrderNo are in the detail band
               //Repeating the following
  RepeatCompany.Caption := Company.AsString;  RepeatOrderNo.Caption := OrderNo.AsString;
end;
 
end.
 
Robert Triest

Posts: 687
Registered: 3/24/05
Re: Repeating QRLabels in QuickReport  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 10, 2016 12:49 AM   in response to: Benson Eze in response to: Benson Eze
You should take a look to the Quickreport examples to see how it works.

In short:

Change the way you use you variables. If you have 60 Variables (Amountcaller1 ... Amountcaller60) then
you are not able to loop through start till end. For displaying an unknown number of variables you
need to put them in an array or another list structure.

Maybe your Amountcaller variables are direct database fields?
If so, then you should normalize your tables. Instead of one table
with 60 fields you make 2 tables and normalize your fields.
First table for generic info and the second table for the
details (Amountcaller1.. AmountcallerX)
In this way you can use the tables in Quickreport and loop the
second table from first record untill End Of File while creating
your report rows. Ask more if this is the case..

If you Amountcaller var's are collected from another source, like
Amountcaller1:=myTable.fieldbyname('Amountcaller').AsString; then
you put the variables in an array or another list structure.
(I would take a Stringlist and use the Objects property to store
the information but that's too much for this example.

Example Array:

Type AmountcallerArray : array[1..60, 1..2] of String; //or make a dynamic array..
 
var myAmountcallerArray: AmountcallerArray;
     idxAmountCaller: Integer;
 
  procedure AddAmountcaller(strCompany, strOrder : String);
  Begin
    myAmountcallerArray[idxAmountCaller,1]:=strCompany;
    myAmountcallerArray[idxAmountCaller,2]:=strOrder;
    inc(idxAmountCaller);
  end;
 
begin
  idxAmountCaller:=1;
 
  If AmountCaller1 <> 0 then 
  begin
    AddAmountcaller('Company1', 'Order1');
  end;
 
  If AmountCaller2 <> 0 then 
  begin
    AddAmountcaller('Company2', 'Order2');
  end;
 
  //..etc
end;


Now you can loop through a list (array) and create your Quickreport rows..

Place two TQRbands on the report,
the first as BandType rbColumnHeader
the second as rbDetail.

Put on the first band two labels with your header information, like 'Company' and 'OrderNo'.
Put on the second band two labels, like your RepeatCompany and RepeatOrderNo.

Create the "Before Print" event of TQuickRep.
There you set your loop variable
mycounter := 1;


Create the "OnNeedData" event of TQuickRep
There you handle your data and create the rows.
begin
  MoreData :=myAmountcallerArray[mycounter,1]<>'';
 
  if myAmountcallerArray[mycounter,1 ]<>'' then
  Begin
    RepeatCompany.Caption := myAmountcallerArray[mycounter,1];
    RepeatOrderNo.Caption := myAmountcallerArray[mycounter,2]
  End;
 
  Inc(mycounter);
end;
Benson Eze

Posts: 11
Registered: 3/7/16
Re: Repeating QRLabels in QuickReport  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 10, 2016 6:55 AM   in response to: Robert Triest in response to: Robert Triest
Robert Triest wrote:

Create the "OnNeedData" event of TQuickRep
There you handle your data and create the rows.


Hello Robert,

I thank you very much for the help. Unfortunately, I could not make use of the procedures because I am using QuickReport 5.02 under Delphi5. As you are aware, there is no "OnNeedData" event of TQuickRep in QuickReport 5.02.

Any idea how to utilize the idea you postulated in QuickReport 5.02? Thanks!

Regards,
Benson

Edited by: Benson Eze on Feb 12, 2016 1:32 PM

Robert Triest

Posts: 687
Registered: 3/24/05
Re: Repeating QRLabels in QuickReport  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 10, 2016 12:54 PM   in response to: Benson Eze in response to: Benson Eze
As you are aware, there is no "OnNeedData" event of TQuickRep in QuickReport 5.02.

I'm not sure.. As long as I work with Quickreport (about 1000 years..) there was always
the OnNeedData event to repeat the detail band. Together with the "Moredata" boolean operator
this is the only way I'm aware of doing Quickreport.

If it is realy not the case then you should figure out by examples how to make
the detailband repeating itself.

Any idea how to utilize the idea you postulated in QuickReport 5.02? Thanks!
If AmountVerticalProfile100 <> 0 then begin
RepeatCompany.Caption := 'EditOutputVerticalProfile100'; RepeatOrderNo.Caption := 'EditAmountVerticalProfile100'; end;

To go forward you realy have to put the data in a loopable structure, like a database query, array, TList or record.
Robert Triest

Posts: 687
Registered: 3/24/05
Re: Repeating QRLabels in QuickReport  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 16, 2016 1:00 AM   in response to: Benson Eze in response to: Benson Eze
Checked sources from QuicReport 3 from about 1999..
My feeling is that the implementation was always using the OnNeedData event..

procedure TfrmNeedData.FormCreate(Sender: TObject);
var
  i: integer;
begin
  SomeList := TStringlist.Create;
 
  for i := 0 to 500 do
    SomeList.Add('Line ' + IntToStr(i));
end;
 
procedure TfrmNeedData.QuickRep1BeforePrint(Sender: TCustomQuickRep;
  var PrintReport: Boolean);
begin
  // You must reset your data in the BeforePrint event
  // or when you print from the preview, the report will
  // start with the last value(s)
  CurrentIndex := 0;
end;
 
procedure TfrmNeedData.QuickRep1NeedData(Sender: TObject;
  var MoreData: Boolean);
begin
  // If MoreData is true, then QuickReport will print
  // another detail band.  When you set it to false,
  // the report is done.  
 
  MoreData := (CurrentIndex < SomeList.Count);
 
  if MoreData then
  begin
    QRLabel1.Caption := SomeList[CurrentIndex];
 
    // Here's how to set the progress bar
    QuickRep1.QRPrinter.Progress := (Longint(CurrentIndex) * 100) div SomeList.Count;
  end
  else
    QuickRep1.QRPrinter.Progress := 100;
 
  Inc(CurrentIndex);
end;
 
end.
Benson Eze

Posts: 11
Registered: 3/7/16
Re: Repeating QRLabels in QuickReport  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 16, 2016 2:57 AM   in response to: Robert Triest in response to: Robert Triest
Robert Triest wrote:
Example Array:

Type AmountcallerArray : array[1..60, 1..2] of String; //or make a dynamic array..
 
var myAmountcallerArray: AmountcallerArray;
     idxAmountCaller: Integer;
 
  procedure AddAmountcaller(strCompany, strOrder : String);
  Begin
    myAmountcallerArray[idxAmountCaller,1]:=strCompany;
    myAmountcallerArray[idxAmountCaller,2]:=strOrder;
    inc(idxAmountCaller);
  end;
 
begin
  idxAmountCaller:=1;
 
  If AmountCaller1 <> 0 then 
  begin
    AddAmountcaller('Company1', 'Order1');
  end;
 
  If AmountCaller2 <> 0 then 
  begin
    AddAmountcaller('Company2', 'Order2');
  end;
 
  //..etc
end;

Hello Robert,

I thank you very much for your recent (today's) post.

I have some question about this section of you post. I have not the vaguest idea how to represent the data in an array. According to your array's implementation (:see below), I put the code inside the OnCreate-event of QuickRep. But when I ran the application, nothing happened. Please, can you clear up the ambiguity in this paragraph. Thanks.

Regards,
Benson

 begin
   idxAmountCaller:=1;
 
   If AmountCaller1 <> 0 then 
   begin
     AddAmountcaller('Company1', 'Order1');
   end;
 
   If AmountCaller2 <> 0 then 
   begin
     AddAmountcaller('Company2', 'Order2');
   end;
 
   //..etc
 end;
 
Robert Triest

Posts: 687
Registered: 3/24/05
Re: Repeating QRLabels in QuickReport  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Feb 16, 2016 4:33 AM   in response to: Benson Eze in response to: Benson Eze
Small Example in Attachment forum:

https://forums.embarcadero.com/thread.jspa?threadID=176193&stqc=true

You cannot load this example in Delphi 5 but in the .pas file you can see how it is done..
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02