一个QUICKREPOT的打印问题,110分!(110分)

  • 主题发起人 主题发起人 王鸣
  • 开始时间 开始时间

王鸣

Unregistered / Unconfirmed
GUEST, unregistred user!
由于种种原因,我想用两个FORM(里面的TQuickRep有不同的布局),打印时候,第一页用FORM (1)
,以后的打印页 全部用FORM(2),即中间在打印完第一页后,切换到第二个 模板 进行打印

:原因----之所以这样做,主要因为在打印过程中,第一页的PAGEFOOTER和其余页的PAGEFOOTER 不同,
而我用一个FORM(打印模板),运行时,动态的改变 PAGEFOOTER属性,想让不同的页显示不同
的PAGEFOOTER ,目的总是达不到,只好退而求其次,所以才有了最上面的想法。

-------我的问题大概如此,如果哪位朋友有解决整个问题的更好的思路,那就更好了!
 
如果只是改变文字的话,可以在 PageFooter 上放置一个 QRLabel ,当 EndPage 时动态改变 Caption 。
 
如果仅仅是PageFooter的内容不同,可放两套控件A1与A2,当打第一页时
设A1.Enabled=True,A2.Enabled=False,从第二页开始反之
这方法虽然不好也只有退而求其次了
 
来迟了,Dogruo方法正确,做两脚板,在A1控件的AfterPrint事件写
A1.Enabled=False;
A2.Enabled=True;
写就行了
 
谢谢三位朋友的回答,但问题可能比你们感觉麻烦的多,三位的方法我都曾用过,都没效果:
1,不是仅仅变换一个Label的问题,而是两个高度和内容不一样的表格。
2。后两位的方法我也曾用过,但这没用。由于第二页的脚板(表格PAGEFOOTER)的高度较小,
应该可以打印较多的记录, 而上面的方法就不能动态反映这个变化,而且还牵涉到最后一页
PAGEFOOTER不能显示的情况!
---这个问题我曾与 dq 较深的讨论过,但还没有有效的办法。
实在不行,还是请诸位帮忙想一想用两个 模板 进行切换的方法罢。
希望 dq 也能继续帮忙!
 
怪了,难道 quickreport 真的解决不了这个问题,还是 大富翁 上没有人会?
其实就是 第一页的pagefooter与第二页开始的 所有页的 pagefooter 不同(主要是这个
“不同”较大而已,除了Lable外,还有较为复杂一点的表格,仅为如此)而已,以及其中
必然的牵涉到的每行的记录数不同的问题阿!
如果真是如此,那简直太“悲哀”了。
我希望这不是事实,静等 大家的“声音”!
 
to 王鸣:
我的email收到了吗?我好象忘了一点,就是要用到OnNeedData控制。
如果你决定用两个QuickRep的话,我再说详细些吧——

在Form上放一个TQRCompositeReport控件,在它的OnAddReports事件里——

procedure TForm1.QRCompositeReport1AddReports(Sender: TObject);
begin

with QRCompositeReport1.Reportsdo

begin

Add(QuickRep1);
Add(QuickRep2);//我这里两个QuickRep是放在一个Form上的
end;

end;


预览时候调用QRCompositeReport1.Preview;


把第二个QuickRep的DataSet置为空,在它的OnNeedData事件中控制记录指针的移动和结束——

procedure TForm1.QuickRep2NeedData(Sender: TObject;
var MoreData: Boolean);
begin

if not Query1.Eof then
Query1.Next;
MoreData := not Query1.Eof;
end;


定义一个全局变量记录第一页最后一条记录的位置——

var
Rec: TBookMark;

在第一个QuickRep的OnEndPage事件里——

Rec := Query1.GetBookMark;//记录当前记录位置
Query1.Last;//结束第一个QuickRep的生成过程


在第二个QuickRep的BeforePrint事件里——

Query1.GotoBookMark(Rec);//返回刚才记下的上一条记录的位置
Query1.Prior;//这一句和下面一句看起来很奇怪,但如果不这样做,会在第二页打出最后一条记录并丢掉一条记录:(
QuickRep2.CurrentY := Round(QuickRep2.Page.TopMargin * 10 + ColumnHeaderBand1.Size.Height);

在第二个QuickRep的AfterPrint事件里释放BookMark——

Query1.FreeBookmark(Rec);

你再试试吧。另外提醒一点,第二张报表不要放TitleBand。

——不过用两个报表实在不能说是个好办法,还是再听听别人的意见吧。
 
to dq:
关键时候还得是你,提供最好的帮助,再次感谢!
你的方法基本成功,有了很大的进展,中间还有一点小问题:
1、>>QuickRep2.CurrentY := Round(QuickRep2.Page.TopMargin * 10 + ColumnHeaderBand1.Size.Height);
这一句用上反而有点问题,注释掉,反而能行,(目前情况是如此)。
2、尽管一再留心 第二个报表 打印开始时的记录数,并用了 “书签”,但是第二页开始打印时
依然是从头开始打印, 开来好像 书签 没有起作用。
----情况大致如此,我继续调试,有了新情况再跟你说罢!

 
>>第二页开始打印时依然是从头开始打印
关键是我在上面说的“把第二个QuickRep的DataSet置为空”!
你这样做了吗?你在QuickRep2.OnNeedData里设个断点,看能不能截下来?
如果QuickRep2.DataSet不为空的话是不会触发OnNeedData事件的;那样默认的是从头打到尾的。

>>这一句用上反而有点问题,注释掉,反而能行
不会吧:),我在没加这句之前看到的情况是第二页打出了第一张报表的ColumnHeader和最后一条记录。
加上这一句是为了让第二张报表的第一条记录覆盖掉那最后一条记录。
不过既然你说能行了,那就这样吧,看来QuickReport是有些奇怪:)
 
to dq:
修改成功,
真是不好意思,我自己的失误,麻烦你又解释了一遍,我犯的错误如下:
1。第二个QuickRep的DataSet没置为空,由于我不懂 TqrcompositeReport的用法,当时设了
dataset(现在改为 空),而且为所有的TQRDBText也都设了dataset(现在 没有改变)。
2。列的表头 我以前用的是 pageheaderband 而没有用 columnheader 故没有出现你说的必须加如下一行的情况:
>>QuickRep2.CurrentY := Round(QuickRep2.Page.TopMargin * 10 + ColumnHeaderBand1.Size.Height);
后来我改用pageheaderband ,就出现了你 说得那种情况。于是用上你那一句,但QuickRep2.CurrentY 获得
的值太小,把pageheaderband也覆盖了, 我于是改了一下句子如下(加大了一下数值):
QuickRep1.CurrentY := Round(QuickRep1.Page.TopMargin * 10 + ColumnHeaderBand1.Size.Height+120);
120是我慢慢 试出来的!有没有什么问题?
现在打印基本成功,一大半功劳在你,我很诚恳,如有问题,我再向你请教!
最后,我希望你能给我解释一下TqrcompositeReport的用法,他是如何合成两个报表的?他的
工作流程是什么?
“打印”分类里,我还有一个问题:Tadotable的表清空方法?如有兴趣你可以进去回答一下!
谢谢!
 
1.>>而且为所有的TQRDBText也都设了dataset
——这是对的,不要改它,不然就没有数据了:)

2.>>120是我慢慢 试出来的!有没有什么问题?
恐怕会有问题,虽然预览的时候可能正好对上,但打印的时候就难说了。
应该改成——
QuickRep2.CurrentY := Round(QuickRep2.Page.TopMargin * 10 + PageHeaderBand1.Size.Height);
——这样比较精确,这句话的意思就是把输出的垂直位置退回到正确显示第一条记录的位置,
如果在第二页上你的DetailBand之上只有一个PageHeader,
那么DetailBand里第一条记录的Y座标就应该是报表的顶边距(QuickRep2.Page.TopMargin)
加上PageHeader的高度(PageHeaderBand1.Size.Height);只不过它们在QuickRep生成过程中
的单位不一致,顶边距要乘以10才行。

至于TQRCompositeReport的用法,我也是参考了Delphi的Demo的。
具体流程就说不上了,帮助里对它实在是语焉不详:(
不过我觉得它最重要的就是OnAddReports事件了,只要这个事件用对了就行:)
 
可以放两个PageFooter ,再控制打印其中的一个就ok了
 
to dq:
程序打印又有了一点小问题:
1。当打印只有一条记录的表时,显示的事第二个报表,(但我估计其实质是第二个表把第一个表
给覆盖了),我认为关键在这一句:
Rec := Query1.GetBookMark;//记录当前记录位置
Query1.Last;//结束第一个QuickRep的生成过程
虽然指针指到最后一条,但表示还有一个记录,所以会重开一页,但第二页被我们用下一句:
QuickRep2.CurrentY := Round(QuickRep2.Page.TopMargin * 10 + PageHeaderBand1.Size.Height);
调用给覆盖了。并且 如果对此句 我不加 120 的话,CurrentY 太小,把columnheader也覆盖了
我现在已改为 columnheaderband 没有用pageheaderband了。
2,并发性 错误,打开一个 多记录得到表后,再打开一个 三四个记录的表后,出现
"invalid Tbookmark",而我在打印后,已经用Query1.FreeBookmark(Rec)了;我估计又是指针指向
最后一条时,中间转换 时 出了 问题!
以上你以为呢?

 
怪我糊涂,其实在GotoBookMark之后马上就可以FreeBookMark了。

之所以会出现这样的问题是因为当记录少的时候,各相关事件发生的顺序和预想的逻辑对不上,
你在几个事件里设几个断点看一下就知道问题所在了。这时候第一张表的OnEndPage根本没执行!

你看能不能通过Prepare得到结论只有一页的话,就调用QuickRep1的预览或打印,否则用CompositeReport。
比如在预览的时候这样写——

QuickRep1.Prepare;
if QuickRep1.QRPrinter.PageCount = 1 then
QuickRep1.Preview
else
QRCompositeReport1.Preview;
 
to dq: 谢谢你的及时回答!
根据你最后的建议,修改运行后,程序基本上又能够 正常运行。
我正在进行测试,有什么其他情况,我再跟你说吧!
 
多人接受答案了。
 
后退
顶部