用戶在使用數據庫應用程序時經常要生成報表,利用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目錄下。