紧急求救:关于动态报表的换页(100分)

  • 主题发起人 主题发起人 Tblue
  • 开始时间 开始时间
T

Tblue

Unregistered / Unconfirmed
GUEST, unregistred user!
我编写一个打印程序,根据返回至StringGrid中的值,动态生成打印报表,方法是定义
一个二维的QRLabel数组,动态生成在rbdetail 的Band上,但由于不是根据Table或query,
所以QuickReport不能自动换页,在BeforePrint事件中,我加入:
if (j<>0) and ((j mod 22)=0) then
quickRep1.NewPage;
//j为行数
但编译通过后,运行时系统提示非法调用NewPage,我又根据以前gaqizh提供的一个方法,在
QuickRep中加入QRGroup,然后在其中放入QRMemo,设置QRMemo的autoStretch属性为true,
可是还是不行,因为任务比较紧,所以本人万分焦急,急盼热心同仁不吝赐教,万分感激!
 
BEFOREPRINT事件是在整个报表开始打印前发生的.
我认为,应该在DETAILBAND的BEFOREPRINT中添入
换页程序.
 
与其在打印过程中控制,不如换一个角度,在打印外控制,
下面是我的参考思路:
相关Table(Query).First;
while not(相关Table(Query).EOF)do
begin
...
刷新数据;
if 判断=True then
QuickRep.Print;
...
相关Table(Query).Next;
end;
 
我可能没说清楚,
PowerKen:我是根据返回到StringGrid中的数据来打印,并不通过本地的Table或query.
yunshang:我在BeforePrint中加入了NewPage,但并不成功;
 
我做的一个报表程序,没问题.
unit print;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
QuickRpt, Qrctrls, ExtCtrls, StdCtrls;
type
TForm1 = class(TForm)
QuickRep1: TQuickRep;
DetailBand1: TQRBand;
QRSubDetail1: TQRSubDetail;
ChildBand2: TQRChildBand;
QRLabel1: TQRLabel;
QRLabel2: TQRLabel;
QRLabel4: TQRLabel;
Button1: TButton;
QRLabel5: TQRLabel;
ChildBand1: TQRChildBand;
QRLabel3: TQRLabel;
QRShape1: TQRShape;
procedure QuickRep1BeforePrint(Sender: TCustomQuickRep;
var PrintReport: Boolean);
procedure QuickRep1NeedData(Sender: TObject;
var MoreData: Boolean);
procedure DetailBand1BeforePrint(Sender: TQRCustomBand;
var PrintBand: Boolean);
procedure QRSubDetail1NeedData(Sender: TObject;
var MoreData: Boolean);
procedure QRSubDetail1BeforePrint(Sender: TQRCustomBand;
var PrintBand: Boolean);
procedure Button1Click(Sender: TObject);
procedure ChildBand2BeforePrint(Sender: TQRCustomBand;
var PrintBand: Boolean);
procedure ChildBand1BeforePrint(Sender: TQRCustomBand;
var PrintBand: Boolean);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;

var
Form1: TForm1;
implementation
{$R *.DFM}
var
InnDCount:Integer;
InnSCount:Integer;
InnDSum:Integer;
InnSSum:Integer;
InnTotal:Integer;
InnPageNo:Integer;
procedure TForm1.QuickRep1BeforePrint(Sender: TCustomQuickRep;
var PrintReport: Boolean);
begin
DetailBand1.Height:=0;
QRSubDetail1.Height:=0;
ChildBand1.Height:=0;
ChildBand2.Height:=0;
InnDCount:=0;
InnDSum:=0;
InnTotal:=0;
end;

procedure TForm1.QuickRep1NeedData(Sender: TObject;
var MoreData: Boolean);
begin
InnDCount:=InnDCount+1;
if InnDCount<=10
then
MoreData:=True
else
MoreData:=False;
InnSCount:=0;
InnSSum:=0;
ChildBand1.Height:=0;
end;

procedure TForm1.DetailBand1BeforePrint(Sender: TQRCustomBand;
var PrintBand: Boolean);
begin
DetailBand1.Height:=32;
QRLabel1.Caption:=IntToStr(InnDCount);
InnDSum:=InnDsum+InnDCount;
if 32-InnPageNo<7 then
//one page has 32 rows , one group occupy 7 rows
begin
QuickRep1.NewPage;
InnPageNo:=0;
end
else
InnPageNo:=InnPageNo+1;
end;

procedure TForm1.QRSubDetail1NeedData(Sender: TObject;
var MoreData: Boolean);
begin
InnSCount:=InnSCount+1;
if InnSCount<=5
then
MoreData:=True
else
MoreData:=False;
end;

procedure TForm1.QRSubDetail1BeforePrint(Sender: TQRCustomBand;
var PrintBand: Boolean);
begin
QRSubDetail1.Height:=32;
QRLabel2.Caption:=IntToStr(InnSCount);
InnSSum:=InnSSum+InnSCount;
InnTotal:=InnTotal+InnSCount;
InnPageNo:=InnPageNo+1;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
QuickRep1.Preview;
end;

procedure TForm1.ChildBand2BeforePrint(Sender: TQRCustomBand;
var PrintBand: Boolean);
begin
if (InnDCount=10) and (InnSCount=5) then
begin
ChildBand2.Height:=32;
QRLabel4.Caption:=IntToStr(InnDSum);
QRLabel5.Caption:=IntToStr(InnTotal);
InnPageNo:=InnPageNo+1;
end;
end;

procedure TForm1.ChildBand1BeforePrint(Sender: TQRCustomBand;
var PrintBand: Boolean);
begin
if InnSCount=5 then
begin
ChildBand1.Height:=32;
QRLabel3.Caption:=IntToStr(InnSSum);
InnPageNo:=InnPageNo+1;
end;
end;

end.
 
我的源程序:
unit QRBRep;
interface
uses Windows, SysUtils, Messages, Classes, Graphics, Controls,
StdCtrls, ExtCtrls, Forms, Quickrpt, QRCtrls;
type
TQRBRep1 = class(TQuickRep)
QRBand1: TQRBand;
detailBand1: TQRBand;
QRLabel1: TQRLabel;
QRGroup1: TQRGroup;
QRMemo1: TQRMemo;
procedure QRBRepBeforePrint(Sender: TCustomQuickRep;
var PrintReport: Boolean);
procedure QRBRepNeedData(Sender: TObject;
var MoreData: Boolean);
procedure detailBand1BeforePrint(Sender: TQRCustomBand;
var PrintBand: Boolean);
private
public
end;

var
QRBRep1: TQRBRep1;
QRLabel: array of array of TQRLabel;
QRShape: array of array of TQRShape;
xzjlst: integer;
implementation
uses QRBank1, Unit1;
{$R *.DFM}
var
inPage: integer;
procedure TQRBRep1.QRBRepBeforePrint(Sender: TCustomQuickRep;
var PrintReport: Boolean);
var
i,j: integer;
begin
SetLength(QRLabel,xzjlsn+2,8);
//xzjlsn为全局变量,为要打印的StringGrid行数
SetLength(QRShape,xzjlsn+2,8);
xzjlst:=1;
for j:=0 to xzjlsndo
begin
for i:=0 to 7do
begin
QRShape[j,i]:=TQRShape.Create(QRBRep1);
with QRShape[j,i]do
begin
Parent:=DetailBand1;
Left:=i*92;
Top:=j*24;
Height:=25;
Width:=93;
Enabled:=True;
Visible:=True;
end;
QRLabel[j,i]:=TQRLabel.Create(QRBRep1);
with QRLabel[j,i]do
begin
Parent:=DetailBand1;
Left:=i*92+2;
Top:=j*24+6;
Height:=16;
Width:=90;
Alignment:=TaCenter;
AutoSize:=True;
Caption:='';
Enabled:=True;
Visible:=True;
end;
end;
******************
这里加入
if (j<>0) and ((j mod 22)=0) then
quickRep1.NewPage;
//运行时出现非法调用错误
****************************
end;
QRLabel[0,0].Caption:='序号';
QRLabel[0,1].Caption:='帐号';
QRLabel[0,2].Caption:='销帐日期';
QRLabel[0,3].Caption:='话费月份';
QRLabel[0,4].Caption:='话费';
QRLabel[0,5].Caption:='上次余额';
QRLabel[0,6].Caption:='本次余额';
QRLabel[0,7].Caption:='滞纳金';
xzjlst:=1;
end;


procedure TQRBRep1.QRBRepNeedData(Sender: TObject;
var MoreData: Boolean);
var
i,j: Integer;
begin
if xzjlst>xzjlsn then
begin
MoreData:=False;
exit;
end
else
begin
MoreData:=True;
for j:=1 to xzjlsndo
for i:=0 to 7do
QRLabel[j,i].Caption:='';
for j:=1 to xzjlsndo
begin
if xzjlst>xzjlsn then
break;
for i:=0 to 7do
begin
QRLabel[j,i].Caption:=QRBankForm.StringGrid1.Cells[i,j];
end;
Inc(xzjlst);
end;
end;
end;
**********************
如在这里加入以下程序:可以换页,但打印内容全出现在最后一页,
而前面页为空
procedure TQRBRep1.detailBand1BeforePrint(Sender: TQRCustomBand;
var PrintBand: Boolean);
begin
inpage:=1;
While inpage<=xzjlsndo
begin
if ((inpage mod 22)=0) then

QRBRep1.NewPage;
InPage:=InPage+1;
end;
**************************************
end;
end.
 
谢谢yunshang的热心,但我在detailBand中加入NewPage,仍然不行,
内容都会打在最后一页,而前面几页为空,用临时表是个折中办法,
这种方法在数据量大时太慢,并且也不够灵活,而且我已经按现在的
思路写了好几个这样的打印程序,希望最好能用这种或更简洁的方法实现,
希望大家多多帮助,不甚感激!
 
>>我已经按现在的思路写了好几个这样的打印程序
您的思路是错误的,照您的程序看,您把所有待打印的数据均生成了
一个QRLabel输出,正确的做法是在DetailBand中只生成8个QRLabel,
在OnNeedData事件中赋值,在BeforePrint中控制每页打印的行数。
也可以先生成一整页的表样,比如22行的表格,然后将DetailBand
的ForceNewPage设为True,即可控制分页,还能解决补充空行的问题。
下面将你的程序按照办法2修改了一下:
unit QRBRep;
interface
uses Windows, SysUtils, Messages, Classes, Graphics, Controls,
StdCtrls, ExtCtrls, Forms, Quickrpt, QRCtrls;
type
TQRBRep1 = class(TQuickRep)
QRBand1: TQRBand;
detailBand1: TQRBand;
QRLabel1: TQRLabel;
QRGroup1: TQRGroup;
QRMemo1: TQRMemo;
procedure QRBRepBeforePrint(Sender: TCustomQuickRep;
var PrintReport: Boolean);
procedure QRBRepNeedData(Sender: TObject;
var MoreData: Boolean);
private
public
end;

var
QRBRep1: TQRBRep1;
QRLabel: array of array of TQRLabel;
QRShape: array of array of TQRShape;
xzjlst: integer;
implementation
uses QRBank1, Unit1;
{$R *.DFM}

procedure TQRBRep1.QRBRepBeforePrint(Sender: TCustomQuickRep;
var PrintReport: Boolean);
var
i,j: integer;
begin

{
SetLength(QRLabel,xzjlsn+2,8);
//xzjlsn为全局变量,为要打印的StringGrid行数
SetLength(QRShape,xzjlsn+2,8);
}
SetLength(QRLabel,22+1,8);
// xzjlsn为StringGrid的行数,而此处应该是生成每页打印的行数,
SetLength(QRShape,22+1,8);
// 从您的程序看,应该是22行,另加一个标题行
xzjlst:=1;
// xzjlst是StringGrid的当前打印行号
for j:=0 to 22do
// 见上
begin
for i:=0 to 7do
begin
QRShape[j,i]:=TQRShape.Create(QRBRep1);
with QRShape[j,i]do
begin
Parent:=DetailBand1;
Left:=i*92;
Top:=j*24;
Height:=25;
Width:=93;
Enabled:=True;
Visible:=True;
end;
QRLabel[j,i]:=TQRLabel.Create(QRBRep1);
with QRLabel[j,i]do
begin
Parent:=DetailBand1;
Left:=i*92+2;
Top:=j*24+6;
Height:=16;
Width:=90;
Alignment:=TaCenter;
AutoSize:=True;
Caption:='';
Enabled:=True;
Visible:=True;
end;
end;
{
******************
这里加入
if (j<>0) and ((j mod 22)=0) then
quickRep1.NewPage;
//运行时出现非法调用错误
****************************
}
end;
QRLabel[0,0].Caption:='序号';
QRLabel[0,1].Caption:='帐号';
QRLabel[0,2].Caption:='销帐日期';
QRLabel[0,3].Caption:='话费月份';
QRLabel[0,4].Caption:='话费';
QRLabel[0,5].Caption:='上次余额';
QRLabel[0,6].Caption:='本次余额';
QRLabel[0,7].Caption:='滞纳金';
xzjlst:=1;
end;


procedure TQRBRep1.QRBRepNeedData(Sender: TObject;
var MoreData: Boolean);
var
i,j: Integer;
begin
if xzjlst > xzjlsn then
// xzjlsn为全局变量,为要打印的StringGrid行数
MoreData:=False
else
begin
MoreData:=True;
for j:=1 to 22do
// 同上
begin
for i:=0 to 7do
begin

if xzjlst > xzjlsn then

QRLabel[j,i].Caption := ''
else
QRLabel[j,i].Caption:=QRBankForm.StringGrid1.Cells[i,xzjlst];
// 打印当前行对应的数据
end;
end;

Inc(xzjlst);
end;
end;

end;

end.

Good Luck !
 
谢谢liuly的热心帮助,我顺便再劳烦一句,如果在一张报表上同时打印两个
完全不同的StringGrid,有没有比较好的办法?
 
基本原理不是一样的吗?
生成两个不同的表,再分别赋值。
 
你的意思是用组合报表Add Report吗?
我是想打完StringGrid1的内容,接下来
打StringGrid2的内容,好象这样的话在
BeforePrint中不好预先控制,用迭加
报表的方法应该是可以的,但不知可否
在一个报表中这样实现?(我好象太罗嗦了,
本来早该接受答案了)
 
好了,一切都OK了,感谢各位热心朋友!
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部