p> 用戶在使用數據庫應用程序時經常要生成報表,利用Delphi 4的QReport 部件,可以幫助我們快速方便地生成報表。這里以一個設備治理報表為例說明如何用QReport部件與Query部件設計從多個數據表中生成報表。
一、 所用數據庫
這裡用到三個FoXPRo數據表,DLBMK(設備大類編碼)、SBXHK(設備型號及配置)、BMSBK(設備所在部門),存放在D:/SB目錄下。其庫結構如下:
(一) DLBMK 字段名稱字段類型解釋1 DLBH N3 設備大類的編號2 DLMC C20 設備大類的名稱(二)SBXHK 字段名稱字段類型解釋1 XHBM N3 設備型號的編碼2 DLBH N3 同DLBMK中的DLBH字段3 SBXH C30 設備型號4 SBPZ C30 設備配置5 SBSL N3 設備數量(三)BMSBK 字段名稱字段類型解釋1 BMMC C20 部門名稱2 XHBM N3 同SBXHK中的XHBM字段3 SL N3 數量利用這三個數據表,要生成一個只有電腦部有而其他部門沒有的設備型號的情況。
二? 絛蛑械牟考笆糶?/b>
程序中有兩個窗體:主窗體mainForm與報表窗體repForm。主窗體mainForm中有兩個TButton部件,設置如下:
部件屬性及屬性值
PreviewBTn:TButton Caption:預覽
PrintBtn: TButton Caption:打印報表窗體repForm中的部件及屬性設置如下:
部件屬性及屬性值
Query1: TQuery DatabaseName:d:/sb
Active: True
Qrep1: TQuickrep Dataset:query1
TitleBand1: TQRBand BandType:rbTitle
HeadBand1: TQRBand BandType:rbColumnHeader
DrawLeft : True
DrawRight : True
DrawTop : True
DrawBottom : True
DetailBand1: TQRBand BandType:rbDetail
DrawLeft : True
DrawRight : True
DrawTop : True
DrawBottom : True
ChildBand1: TQRChildBand ParentBand:DetailBand1
DrawLeft : True
DrawRight : True
DrawTop : True
DrawBottom : True
TitleLabel: TQRLabel Caption:設備統計表
DlmcLabel: TQRLabel Caption:類別
SbxhLabel: TQRLabel Caption:型號
SbpzLabel: TQRLabel Caption:配置
SbslLabel: TQRLabel Caption:數量
DlmcDBText: TQRDBText Dataset:Query1
Datafield: dlmc
SbxhDBText: TQRDBText Dataset:Query1
Datafield: sbxh
SbpzDBText: TQRDBText Dataset:Query1
Datafield: sbpz
SbslDBText: TQRDBtext Dataset:Query1
Datafield: sbsl
Shape1~9: TQRShape Shape:qrsVertline
Top:0
Width:1
Query1的SQL屬性設置為:
select a.dlbh,a.dlmc,b.sbxh,b.sbpz,b.sbsl
from dlbmk a,sbxhk b
where a.dlbh=b.dlbh and b.xhbm not in
(select xhbm from bmsbk where trim(bmmc)$#@60;$#@62;'電腦部')
order by a.dlbh 設置幾個TQRband部件的DrawLeft、DrawRight、DrawTop、DrawBottom屬性值為True,是為了打印表格邊框及橫線。利用TQRShape部件,是為了打印出表格豎線。 DlmcDBText放置在DetailBand1上,其它幾個TQRDBText部件放置在ChildBand1上,Shape1~3放置在HeadBand1上,Shape4~6放置在DetailBand1上,Shape7~9放置在ChildBand1上。
三、 為程序增加代碼
1. mainForm窗體中的兩個按鈕事件procedure TmainForm.PreviewBtnClick(Sender : TObject)
begin
repForm.Qrep1.Preview;
end;
procedure TmainFormPrintBtnClick(Sender : TObject)
begin
repForm.Qrep1.Print;
end;
2. HeadBand1、DetailBand1及ChildBand1的BeforePrint事件procedure TrepForm.HeadBand1BeforePrint(Sender : TQRCustomBand; Var PrintBand : Boolean)
Begin
Shape1.Height:=HeadBand1.Height;
Shape2.Height:=HeadBand1.Height;
Shape3.Height:=HeadBand1.Height;
End;
procedure TrepForm.DetailBand1BeforePrint(Sender : TQRCustomBand; Var PrintBand : Boolean)
begin
PrintBand:=bh$#@60; $#@62;Query1['dlbh'];
if PrintBand then
begin
bh:=Query1['dlbh'];
Shape4.Height:=DetailBand1.Height;
Shape5.Height:=DetailBand1.Height;
Shape6.Height:=DetailBand1.Height;
end
end;
procedure TrepForm.ChildBand1BeforePrint(Sender : TQRCustomBand; Var PrintBand : Boolean)
Begin
Shape7.Height:=ChildBand1.Height;
Shape8.Height:=ChildBand1.Height;
Shape9.Height:=ChildBand1.Height;
End;
bh應在變量定義部分定義: Var bh : shortint=0;
幾個TQRShape部件的高度(Height)與所在TQRBand 部件保持一致,使豎線打印得整潔。假如在設計階段調整了TQRBand部件的高度,也不會出現豎線斷線或過長的情況。
在DetailBand1的BeforePrint事件中用PrintBand進行控制,可使每個設備大類名稱只需打印一次,而不是每個型號都對應打印一次大類名稱。因為dlbh字段的值都大於0,bh初值設為0使它與任一記錄的dlbh字段的值都不同,以確保第一個大類名稱被打印。這樣就生成了一個從多個數據表中提取數據,並帶有表格線的數據報表。
注:本例工程文件為sbgl.dpr,原程序文件為main.pas和sbrep.pas,若要測試請將dlbmk.dbf、sbxhk.dbf、bmsbk.dbf三個文件放在d:/sb目錄下。