當(dāng)前,在軟件開(kāi)發(fā)工具中,Delphi以其控件多、面向?qū)ο缶幊坦δ軓?qiáng)、代碼執(zhí)行速度快和簡(jiǎn)單易用等特點(diǎn),結(jié)合可視化開(kāi)發(fā)環(huán)境和當(dāng)前最快的編譯器技術(shù),已成為全球公認(rèn)的快速應(yīng)用開(kāi)發(fā)工具,正被愈來(lái)愈多的編程人員所采用。使用Delphi可以編寫(xiě)各種Windows應(yīng)用程序,尤其是開(kāi)發(fā)數(shù)據(jù)庫(kù)信息管理系統(tǒng)有其獨(dú)特的優(yōu)勢(shì)。在數(shù)據(jù)庫(kù)信息管理系統(tǒng)的開(kāi)發(fā)的過(guò)程中,我們經(jīng)常需要打印輸出很多報(bào)表,用Delphi設(shè)計(jì)復(fù)雜報(bào)表是一件比較煩鎖的事件,它沒(méi)有Visual FoxPRo中那樣簡(jiǎn)便。但由于Delphi中設(shè)計(jì)報(bào)表采用的也是控件,因此,我們可以在程序執(zhí)行時(shí)直接建立所需的報(bào)表控件來(lái)實(shí)時(shí)生成報(bào)表,而且,生成的報(bào)表樣工可以由程序控制來(lái)決定。例如,我們?cè)跀?shù)據(jù)庫(kù)信息查詢(xún)時(shí),查詢(xún)出來(lái)的結(jié)果信息結(jié)構(gòu)一般是不固定的,假如我們要將查詢(xún)結(jié)果打印出來(lái),只設(shè)計(jì)一種報(bào)表格式是不行的,為所有可能的結(jié)果信息都設(shè)計(jì)一種報(bào)表格式也不是一種很好的解決辦法。為了解決這樣一個(gè)問(wèn)題,我們可以采用實(shí)時(shí)生成報(bào)表技術(shù)。本文的目的就是通過(guò)一個(gè)實(shí)例向大家詳細(xì)介紹怎樣實(shí)時(shí)生成報(bào)表。
本例所將設(shè)計(jì)一個(gè)打印對(duì)話(huà)框,該對(duì)話(huà)框包括TQickRep控件和一些報(bào)表樣式控制控件,其它窗體外觀如下圖所示:
1、 控件功能說(shuō)明
QuickRep:TQuickRep 它包括列標(biāo)頭(HB:TQRBand)、細(xì)節(jié)(DB:TQRBand)、頁(yè)腳(FB:TQRBand)、總結(jié)(SB:TQRBand)帶區(qū),并且細(xì)節(jié)、頁(yè)腳、總結(jié)中沒(méi)有包括一個(gè)TQRLabel、TQRExpr或TDBText控件,主要是在程序執(zhí)行時(shí)建立,列標(biāo)頭帶區(qū)中包括Title(TQRLabel)用于報(bào)表標(biāo)題;QRSQL: TQRLabel用于查詢(xún)條件,這兩個(gè)控件的Caption屬性在程序執(zhí)行時(shí)可任意更改。為了能夠讓QuickRep不顯示出來(lái),將其置于Panel1(Tpanel)的后面,并將Panel1擴(kuò)展到整個(gè)窗體;
Query:TQuery SQL語(yǔ)句控件,程序?qū)⒏鶕?jù)Query返回的結(jié)果來(lái)生成報(bào)表。因此,在建立這個(gè)窗體時(shí),一定要將Query.SQL屬性指定一條SQL語(yǔ)句;
在以上窗體中“紙張”和“頁(yè)面設(shè)置”兩欄所包括的控件是對(duì)QuickRep.Page屬性的控制,程序執(zhí)行時(shí)更改它們會(huì)直接改變QuickRep控件相應(yīng)的屬性值,這可以通過(guò)OnChange或OnExit事件代碼完成;
“打印內(nèi)容設(shè)置”欄中的標(biāo)題是指定報(bào)表的標(biāo)題(TT:TEdit),其值與QuickRep.ReportTitle和Title.Caption一致,可以任意更改;“打印查詢(xún)條件”復(fù)選框指定是否打印查詢(xún)條件,該復(fù)選框的選取否直接控制QRSQL.Caption是否為空;“表列對(duì)齊方式”由一組選項(xiàng)按鈕組成,它主要用于報(bào)表生成時(shí)細(xì)節(jié)內(nèi)容的對(duì)齊方式,它的更改控制變量RD1(Byte)的值(0自動(dòng)對(duì)齊,1中間對(duì)齊,2左邊對(duì)齊);“表列打印寬度”由一組選項(xiàng)按鈕組成,主要用于在生成報(bào)表格式時(shí)列值的寬度,它的更改控制變量RD2(Byte)的值(0自動(dòng)寬度,1相同寬度,2限制最大寬度),當(dāng)選中1相同寬度,2限制最大寬度時(shí)要求輸入寬度,單位為像素;“統(tǒng)計(jì)方式”指出報(bào)表是否包含頁(yè)腳(FB:TQRBAND)和總和(SB:TQRBAND)帶區(qū)。
2、 程序說(shuō)明
程序定義了如下類(lèi)型:
TQRLabelName=array of TQRLabel;
TQRDBTextName=array of TQRDBText;
TQRShapeName=array of TQRShape;
TQRExpName=array of TQRExpr;
上述類(lèi)型為動(dòng)態(tài)數(shù)組類(lèi)型,數(shù)據(jù)的每個(gè)元素為一個(gè)類(lèi)。在實(shí)時(shí)建立報(bào)表控件時(shí),要建立的控件個(gè)數(shù)是不確定的且控制名稱(chēng)也不能確定,用動(dòng)態(tài)數(shù)組是一個(gè)比較好的解決辦法,即可以任意指定數(shù)據(jù)的維數(shù),又不用自己管理內(nèi)存分配問(wèn)題,還有利于報(bào)表包含控件的釋放與處理。程序還聲明了上述類(lèi)型的變量如下:
CHBName:TQRLabelName;
DBName:TQRDBTextName;
CHBShape,DBShape,FBShape,SumShape:TQRShapeName;
FBName,SumName:TQRExpName;
這些數(shù)組變量將在窗體建立時(shí)根據(jù)Query返回的字段結(jié)果分配內(nèi)存,每一個(gè)字段對(duì)就數(shù)組的一個(gè)元素。
程序執(zhí)行過(guò)程:窗體在建立并顯示時(shí),就對(duì)本窗體建立初始化操作。在OnCreate事件中將QuickRep.Page屬性的相應(yīng)值顯示出來(lái),在OnShow事件中執(zhí)行Query.Open操作,并根據(jù)返回結(jié)果分配控件數(shù)組變量空間。窗體建立后,單擊“生成”按鈕生成報(bào)表(忽略備注字段和相片字段),然后可單擊“打印”和“預(yù)覽”進(jìn)行打印或者預(yù)覽報(bào)表。當(dāng)產(chǎn)生報(bào)表后又更改了設(shè)置,必須重新生成報(bào)表。如果Query返回的結(jié)果集字段太多,生成報(bào)表時(shí)有可能紙張礦小不能將生成全部報(bào)表,可調(diào)整報(bào)表紙張大小,再生成報(bào)表。當(dāng)關(guān)閉窗體時(shí),將釋放建立的控件。
3、 源程序清單及注釋
unit PrintDlg;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Buttons, ExtCtrls, Spin, QuickRpt,QRPrntr,printers, Qrctrls,
Db, DBTables, ComCtrls,SysIni;
type
TQRLabelName=array of TQRLabel;//列標(biāo)頭帶區(qū)中列標(biāo)題控制件類(lèi)動(dòng)態(tài)數(shù)組
TQRDBTextName=array of TQRDBText; //細(xì)節(jié)帶區(qū)中列標(biāo)題控制件類(lèi)動(dòng)態(tài)數(shù)組
TQRShapeName=array of TQRShape; //線(xiàn)條控制件類(lèi)動(dòng)態(tài)數(shù)組
TQRExpName=array of TQRExpr; //統(tǒng)計(jì)控制件類(lèi)動(dòng)態(tài)數(shù)組
TPrintForm = class(TForm)
GroupBox1: TGroupBox;
Label5: TLabel;
BtnSet: TbitBtn;//“設(shè)置”按鈕控件
BtnCancel: TBitBtn;// “關(guān)閉”按鈕控件
Panel1: TPanel;
BtnPrint: TBitBtn;// “打印”按鈕控件
BtnPrview: TBitBtn;// “預(yù)覽”按控件鈕
QuickRep: TQuickRep;// 快速報(bào)表控件
HB: TQRBand;// “列標(biāo)頭”帶區(qū)控件
Title: TQRLabel;// 報(bào)表標(biāo)題控件
QRE1: TQRExpr;// 列標(biāo)頭帶區(qū)中“頁(yè)碼”控件
QRE2: TQRExpr;//列標(biāo)頭帶區(qū)中“日期”控件
Panel2: TPanel;
Label1: TLabel;
R1: TRadioButton;//“ 縱向打印”控件
R2: TRadioButton;// “橫向打印”控件
GroupBox4: TGroupBox;
TT: TEdit;// 標(biāo)題輸入框控件
Label2: TLabel;
SR: TCheckBox;// “打印查詢(xún)條件”控件
Label3: TLabel;
Image1: TImage;//顯示縱向打印圖像
Image2: TImage;//顯示橫向打印圖像
QRSQL: TQRLabel;// 列標(biāo)頭帶區(qū)中用于顯示“查詢(xún)條件”控件
GroupBox2: TGroupBox;
Label7: TLabel;
Label8: TLabel;
Label9: TLabel;
Label10: TLabel;
Label11: TLabel;
Label12: TLabel;
Label13: TLabel;
PageSpace: TEdit;// 欄間距輸入框控件
PageTop: TEdit;// 頁(yè)邊距上輸入框控件
PageBottom: TEdit; // 頁(yè)邊距下輸入框控件
PageLeft: TEdit; // 頁(yè)邊距左輸入框控件
PageRight: TEdit; // 頁(yè)邊距右輸入框控件
PageDlux: TCheckBox; // “雙面打印”控件
PageCol: TEdit; // 分欄輸入框控件
Pages: TEdit; // 打印份數(shù)輸入框控件
PaperH: TEdit; // 紙張長(zhǎng)度輸入框控件
PaperW: TEdit;//紙張寬度輸入框控件
Label4: TLabel;
Label6: TLabel;
Ps: TComboBox;//紙張型號(hào)列表框控件
Query: TQuery;//SQL查詢(xún)控件
DB: TQRBand;// “細(xì)節(jié)”帶區(qū)控件
CrtRep: TBitBtn; // “生成”按鈕控件
Label14: TLabel;
Label15: TLabel;
Panel3: TPanel;
Wdauto: TRadioButton; // “自動(dòng)寬度”控件
Wdall: TRadioButton; // “相同寬度”控件
Wdmax: TRadioButton; // “限制最在寬度”控件
Label16: TLabel;
ColWd: TEdit; // 列寬輸入框控件
Panel4: TPanel;
DJAUTO: TRadioButton; // “自動(dòng)對(duì)齊”控件
DJCENTER: TRadioButton; // “中間中齊”控件
DJLEFT: TRadioButton; // “左邊對(duì)齊”控件
FB: TQRBand; // 頁(yè)腳帶區(qū)控件
Label17: TLabel;
Panel5: TPanel;
TJ1: TCheckBox; // “每頁(yè)統(tǒng)計(jì)”控件
TJ2: TCheckBox; // “統(tǒng)計(jì)總和”控件
SB: TQRBand; // 總和帶區(qū)控件
procedure FormCreate(Sender: TObject);
procedure RadioButtonClick(Sender: TObject);
procedure PageDluxClick(Sender: TObject);
procedure PageColChange(Sender: TObject);
procedure PageSpaceExit(Sender: TObject);
procedure PagesChange(Sender: TObject);
procedure PageTopExit(Sender: TObject);
procedure PageBottomExit(Sender: TObject);
procedure PageLeftExit(Sender: TObject);
procedure PageRightExit(Sender: TObject);
procedure TTExit(Sender: TObject);
procedure DTClick(Sender: TObject);
procedure BtnPrviewClick(Sender: TObject);
procedure BtnSetClick(Sender: TObject);
procedure PsChange(Sender: TObject);
procedure PaperChange(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormDestroy(Sender: TObject);
procedure CreateReport(Sender: TObject);
procedure SRClick(Sender: TObject);
procedure ClearRep();
procedure FormShow(Sender: TObject);
procedure PaperSizeChg(Sender: TObject);
procedure DJChage(Sender: TObject);
procedure WdChage(Sender: TObject);
procedure QuickRepStartPage(Sender: TCustomQuickRep);
procedure BtnPrintClick(Sender: TObject);
private
{ Private declarations }
CHBName:TQRLabelName;//定義列標(biāo)頭帶區(qū)控件名動(dòng)態(tài)數(shù)組名
DBName:TQRDBTextName; //定義細(xì)節(jié)帶區(qū)控件名動(dòng)態(tài)數(shù)組名
CHBShape,DBShape,FBShape,SumShape:TQRShapeName; //定義線(xiàn)條控件動(dòng)態(tài)數(shù)組名
FBName,SumName:TQRExpName; //定義頁(yè)腳(FBNAME)和總和帶區(qū)(SUMNAME)控件名動(dòng)態(tài)數(shù)組名
DJ:TAlignment;//列對(duì)齊方式(taLeftJustify, taRightJustify, taCenter)
Rd1,Rd2:Byte;//用于保存表列對(duì)齊方式(RD1)和打印寬度(RD2)狀態(tài)變量名
public
{ Public declarations }
CXTJ,BT:String;//CXTJ存放查詢(xún)條件,BT存放報(bào)表標(biāo)題
//由上一級(jí)窗體指定
end;
const
PaperSize:array[0..26] of TQRPaperSize=(A3, A4, A4Small, A5, B4, B5, Letter,
LetterSmall, Tabloid, Ledger, Legal,Statement, Executive, Folio,
Quarto, qr10X14, qr11X17, Note, Env9, Env10, Env11, Env12,
Env14, CSheet, DSheet, ESheet, Custom);
//QuickRep所列出的紙張類(lèi)型
var
PrintForm: TPrintForm;
implementation
{$R *.DFM}
procedure TPrintForm.FormCreate(Sender: TObject);
//將QuickRep.Page屬性以及其它屬性值顯示出來(lái)
var
I:Byte;
begin
PageCol.Text:=IntToStr(QuickRep.Page.Columns);
PageSpace.Text:=FormatFloat('0.00',QuickRep.Page.ColumnSpace);
PageTop.Text:=FormatFloat('0.00',QuickRep.Page.TopMargin);
PageBottom.Text:=FormatFloat('0.00',QuickRep.Page.BottomMargin);
PageLeft.Text:=FormatFloat('0.00',QuickRep.Page.LeftMargin);
PageRight.Text:=FormatFloat('0.00',QuickRep.Page.RightMargin);
PageSpace.Text:=FormatFloat('0.00',QuickRep.page.ColumnSpace);
R1.Checked:=QuickRep.Page.Orientation=poPortrait;
Image1.Visible:=R1.Checked;
R2.Checked:=QuickRep.Page.Orientation=poLandscape;
Image2.Visible:=R2.Checked;
PageDlux.Checked:=QuickRep.PrinterSettings.Duplex;
Pages.Text:=IntToStr(QuickRep.PrinterSettings.Copies);
PaperH.Text:=FormatFloat('0.00',QuickRep.Page.Length);
PaperW.Text:=FormatFloat('0.00',QuickRep.Page.Width);
For I:=0 to 26 do //PS列表框顯示紙張類(lèi)型
if QuickRep.Page.PaperSize=PaperSize[I] then begin
PS.ItemIndex:=I;
Break;
end;
//判斷紙張寬度是否可以更改,只有紙張類(lèi)型為自定義(Ps.ItemIndex=26)才能更改
PaperH.Enabled:=Ps.ItemIndex=26;
PaperW.Enabled:=Ps.ItemIndex=26;
end;
procedure TPrintForm.RadioButtonClick(Sender: TObject);
//紙張方向改變事件處理
var
S:String;
begin
Image1.Visible:=R1.Checked;
Image2.Visible:=R2.Checked;
if R1.Checked then
QuickRep.Page.Orientation:=poPortrait
else
QuickRep.Page.Orientation:=poLandscape;
//交換紙張寬度和長(zhǎng)度的值
S:=PaperH.Text;
PaperH.Text:=PaperW.Text;
PaperW.Text:=S;
if (Ps.ItemIndex=26) or (Ps.ItemIndex=0) then begin
QuickRep.Page.Width:=StrToFloat(PaperW.Text);
QuickRep.Page.Length:=StrToFloat(PaperH.Text);
end;
end;
procedure TPrintForm.PageDluxClick(Sender: TObject);
begin
QuickRep.PrinterSettings.Duplex:=PageDlux.Checked;
end;
procedure TPrintForm.PageColChange(Sender: TObject);
begin
if StrToInt(PageCol.Text)<1 then PageCol.Text:='1';
QuickRep.Page.Columns:=StrToInt(PageCol.Text);
end;
procedure TPrintForm.PageSpaceExit(Sender: TObject);
begin
QuickRep.Page.ColumnSpace:=StrToFloat(PageSpace.Text);
end;
procedure TPrintForm.PagesChange(Sender: TObject);
begin
if StrToInt(Pages.Text)<1 then Pages.Text:='1';
QuickRep.PrinterSettings.Copies:=StrToInt(Pages.Text);
end;
procedure TPrintForm.PageTopExit(Sender: TObject);
begin
QuickRep.Page.TopMargin:=StrToFloat(PageTop.Text);
end;
procedure TPrintForm.PageBottomExit(Sender: TObject);
begin
QuickRep.Page.BottomMargin:=StrToFloat(PageBottom.Text);
end;
procedure TPrintForm.PageLeftExit(Sender: TObject);
begin
QuickRep.Page.LeftMargin:=StrToFloat(PageLeft.Text);
end;
procedure TPrintForm.PageRightExit(Sender: TObject);
begin
QuickRep.Page.RightMargin:=StrToFloat(PageRight.Text);
end;
procedure TPrintForm.TTExit(Sender: TObject);//標(biāo)題更改事件處理
begin
QuickRep.ReportTitle:=TT.Text;
Title.Caption:=TT.Text;
Bt:=TT.Text;
end;
procedure TPrintForm.DTClick(Sender: TObject);//打印查詢(xún)條件復(fù)選框事件
begin
QRSQL.Enabled:=SR.Checked;
end;
procedure TPrintForm.BtnPrviewClick(Sender: TObject);//預(yù)覽按鈕單擊事件
begin
QuickRep.Preview;
end;
procedure TPrintForm.BtnSetClick(Sender: TObject); //設(shè)置按鈕單擊事件
begin
QuickRep.PrinterSetup;
end;
procedure TPrintForm.PsChange(Sender: TObject);//紙張類(lèi)型改變事件
begin
QuickREp.Page.PaperSize:=PaperSize[Ps.ItemIndex];
PaperH.Text:=FormatFloat('0.00',QuickRep.Page.Length);
PaperW.Text:=FormatFloat('0.00',QuickRep.Page.Width);
PaperH.Enabled:=Ps.ItemIndex=26;
PaperW.Enabled:=Ps.ItemIndex=26;
CrtRep.Enabled:=True;
BtnPrint.Enabled:=not CrtRep.Enabled;
BtnPrview.Enabled:=BtnPrint.Enabled;
end;
procedure TPrintForm.PaperChange(Sender: TObject);//紙張寬度和長(zhǎng)度改變事件
begin
QuickRep.Page.Width:=StrToFloat(PaperW.Text);
QuickRep.Page.Length:=StrToFloat(PaperH.Text);
end;
procedure TPrintForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caFree;
end;
procedure TPrintForm.FormDestroy(Sender: TObject);
begin
ClearRep;
PrintForm:=nil;
end;
procedure TPrintForm.CreateReport(Sender: TObject);//生成按鈕單擊事件
Var
I,L:Byte;
CHBtp,CHBlf,Cd,ObWidth:Word;
begin
Screen.Cursor:=crHourGlass;
Title.Caption:=Bt;//設(shè)置標(biāo)題
ClearRep(); //清除已經(jīng)建立的對(duì)象;
if Sr.Checked then QrSQL.Caption:=CXTJ else QRSQL.Caption:=';//是否打印查詢(xún)條件?
CHBtp:=HB.Height-17;//建立的控件在帶區(qū)中的頂部位置
CHBlf:=0; //建立的控件在帶區(qū)中的左邊位置
ObWidth:=0; //建立的控件的寬度
for I := 0 to Query.FieldCount-1 do //根據(jù)Query返回字段數(shù)建立控件
begin
if (Query.Fields[I].DataType<>ftBlob) And (Query.Fields[I].DataType<>ftMemo) then
begin //忽略備注字段和相片字段
L:=Query.Fields[I].DataSize-1;//L=字段寬度(字節(jié))-1
case Rd1 of //根據(jù)選擇的對(duì)齊方式設(shè)置控件的對(duì)齊方式
0: if L<=10 then Dj:=taCenter else DJ:=taLeftJustify;
//自動(dòng)對(duì)齊:字段小于等于10居中對(duì)齊,否則左邊對(duì)齊
1: Dj:=taCenter;//居中對(duì)齊
2: DJ:=taLeftJustify;//左邊對(duì)齊
end;
case Rd2 of //根據(jù)選擇的列表寬度設(shè)置報(bào)表列寬度
0: begin
//自動(dòng)寬度:如果L>14則寬度ObWidth=14+(L-14)/2;如果ObWidth
//的寬度不能顯示列標(biāo)題,則ObWidth=列標(biāo)題寬度;如果字段類(lèi)型
//為日期型、貨幣型和浮點(diǎn)數(shù)型,則ObWidth=65
if L>14 then L:=14+(L-14) div 2;
ObWidth:=L*6;
L:=Length(Query.Fields[I].DisplayName);
if ObWidth<L*6 then ObWidth:=L*6;
ObWidth:=ObWidth+2;
if (Query.Fields[I].DataType=ftDateTime) or
(Query.Fields[I].DataType=ftFloat) or
(Query.Fields[I].DataType=ftCurrency) then ObWidth:=65;
end;
1: if ColWd.Text<>' then ObWidth:=StrToInt(ColWd.Text)
else ObWidth:=100;//相同寬度:ObWidth=輸入寬度值
2: begin //限制最大寬度:首先按自動(dòng)寬度計(jì)算再判斷寬度是否超最大值,
//如果超過(guò)則ObWidth=最大寬度輸入值
if ColWd.Text<>' then Cd:=StrToInt(ColWd.Text)
else Cd:=200;
ObWidth:=L*6;
if ObWidth>Cd then ObWidth:=Cd;
ObWidth:=ObWidth+2;
if (Query.Fields[I].DataType=ftDateTime) or
(Query.Fields[I].DataType=ftFloat) or
(Query.Fields[I].DataType=ftCurrency) then ObWidth:=65;
end;
end;
if CHBlf+ObWidth>=HB.Width then begin //建立控件>紙寬?
DlgMes:='紙張寬度不夠,請(qǐng)更改紙張尺寸。';
MessageBox(Handle,DlgMes,Cap_Inf,Ico_Inf);
break;
end
else begin
CHBShape[I]:=TQRShape.Create(HB);//建立列標(biāo)頭帶區(qū)線(xiàn)條控件
CHBShape[I].Parent:=HB;
CHBShape[I].Top:=CHBtp;
CHBShape[I].Left:=CHBlf;
CHBShape[I].Width:=ObWidth+1;
CHBShape[I].Height:=17;
CHBNAME[I]:=TQRLabel.Create(HB); //建立列標(biāo)題控件
CHBNAME[I].Parent:=HB;
CHBNAME[I].Top:=CHBtp+2;
CHBNAME[I].Left:=CHBlf+1;
CHBNAME[I].AutoSize:=False;
CHBNAME[I].Width:=ObWidth-1;
CHBNAME[I].Alignment:=taCenter;
CHBNAME[I].Caption:=Query.Fields[I].DisplayName;//取字段作為列名
CHBNAME[I].BringToFront;
DBShape[I]:=TQRShape.Create(DB); //建立細(xì)節(jié)帶區(qū)線(xiàn)條控件
DBShape[I].Parent:=DB;
DBShape[I].Top:=-1;
DBShape[I].Left:=CHBlf;
DBShape[I].Width:=ObWidth+1;
DBShape[I].Height:=17;
DBNAME[I]:=TQRDBText.Create(DB); //建立細(xì)節(jié)帶區(qū)控件
DBNAME[I].Parent:=DB;
DBNAME[I].ParentReport:=QuickRep;
DBNAME[I].Top:=2;
DBNAME[I].Left:=CHBlf+2;
DBNAME[I].AutoSize:=False;
DBNAME[I].Width:=ObWidth-3;
DBNAME[I].Height:=13;
DBNAME[I].Alignment:=Dj;
DBNAME[I].DataSet:=Query;
DBNAME[I].DataField:=Query.Fields[I].FieldName;
DBNAME[I].BringToFront;
if Tj1.Checked then begin //是否建立頁(yè)腳帶區(qū)?
FBShape[I]:=TQRShape.Create(FB); //建立頁(yè)腳帶區(qū)線(xiàn)條控件
FBShape[I].Parent:=FB;
FBShape[I].Top:=0;
FBShape[I].Left:=CHBlf;
FBShape[I].Width:=ObWidth+1;
FBShape[I].Height:=17;
if (Query.Fields[I].DataType=ftFloat) or
(Query.Fields[I].DataType=ftCurrency) or (I<2) then
begin //如果字段類(lèi)型為數(shù)值類(lèi)型則建立
FBNAME[I]:=TQRExpr.Create(FB); //建立頁(yè)腳帶區(qū)控件
FBNAME[I].Parent:=FB;
FBNAME[I].ParentReport:=QuickRep;
FBNAME[I].Top:=3;
FBNAME[I].Left:=CHBlf+2;
FBNAME[I].AutoSize:=False;
FBNAME[I].Width:=ObWidth-3;
FBNAME[I].Height:=13;
FBNAME[I].Alignment:=taCenter;
FBNAME[I].Expression:='SUM(QUERY.'+Query.Fields[I].FieldName+')';
FBNAME[I].BringToFront;
end;
end;
if Tj2.Checked then begin //是否建立總和帶區(qū)?
SumShape[I]:=TQRShape.Create(SB); //建立總和帶區(qū)線(xiàn)條控件
SumShape[I].Parent:=SB;
SumShape[I].Top:=0;
SumShape[I].Left:=CHBlf;
SumShape[I].Width:=ObWidth+1;
SumShape[I].Height:=17;
if (Query.Fields[I].DataType=ftFloat) or
(Query.Fields[I].DataType=ftCurrency) or (I<2) then
begin //如果字段類(lèi)型為數(shù)值類(lèi)型則建立
SumNAME[I]:=TQRExpr.Create(SB); //建立總和帶區(qū)控件
SumNAME[I].Parent:=SB;
SumNAME[I].ParentReport:=QuickRep;
SumNAME[I].Top:=3;
SumNAME[I].Left:=CHBlf+2;
SumNAME[I].AutoSize:=False;
SumNAME[I].Width:=ObWidth-3;
SumNAME[I].Height:=13;
SumNAME[I].Alignment:=taCenter;
SumNAME[I].Expression:='SUM(QUERY.'+Query.Fields[I].FieldName+')';
SumNAME[I].BringToFront;
end;
end;
CHBlf:=CHBlf+ObWidth;//當(dāng)前字段處理完成,往右一個(gè)字段寬度
end;
end;
end;
CrtRep.Enabled:=False;//禁上生成按鈕
BtnPrint.Enabled:=not CrtRep.Enabled;允許打印銨鈕
BtnPrview.Enabled:=BtnPrint.Enabled;允許預(yù)覽按鈕
if Tj1.Checked then begin //如果建立了頁(yè)腳帶區(qū),則將頁(yè)腳帶區(qū)中前兩列更改
FBNAME[0].Expression:=''頁(yè)合計(jì)'';
FBNAME[1].Expression:='COUNT+'行'';
end;
if Tj1.Checked then begin //如果建立了總和帶區(qū),則將總和帶區(qū)中前兩列更改
SumNAME[0].Expression:=''總計(jì)'';
SumNAME[1].Expression:='COUNT+'行'';
end;
//調(diào)整列標(biāo)頭帶區(qū)中的日期及頁(yè)碼打印位置
QRE2.Left:=HB.Width-Qre2.Width;
QRSQL.Left:=QRE1.Width+10;
QRSQL.Width:= QRE2.Left-10-QRSQL.Left;
QuickRep.DataSet:=Query; //為QuickRep指定數(shù)據(jù)集,該句一定不能少
Screen.Cursor:=crDefault;
end;
procedure TPrintForm.ClearRep();//清除生成報(bào)表格式時(shí)建立的控件
Var
I:Byte;
begin
For I:=0 to Query.FieldCount-1 do begin
if Assigned(CHBShape[I]) then begin CHBShape[I].Free;CHBShape[I]:=nil;end;
if Assigned(CHBNAME[I]) then begin CHBNAME[I].Free;CHBNAME[I]:=nil;end;
if Assigned(DBShape[I]) then begin DBShape[I].Free;DBShape[I]:=nil;end;
if Assigned(DBNAME[I]) then begin DBNAME[I].Free;DBNAME[I]:=nil;end;
if Assigned(FBShape[I]) then begin FBShape[I].Free;FBShape[I]:=nil;end;
if Assigned(FBNAME[I]) then begin FBNAME[I].Free;FBNAME[I]:=nil;end;
if Assigned(SumShape[I]) then begin SumShape[I].Free;SumShape[I]:=nil;end;
if Assigned(SumNAME[I]) then begin SumNAME[I].Free;SumNAME[I]:=nil;end;
end;
end;
procedure TPrintForm.SRClick(Sender: TObject);
begin
if Sr.Checked then QrSQL.Caption:=CXTJ else QRSQL.Caption:=';
end;
procedure TPrintForm.FormShow(Sender: TObject); //窗體顯示事件
begin
Query.Active:=True;//打印SQL
TT.Text:=Bt;
QuickRep.ReportTitle:=Bt;//設(shè)置標(biāo)題
//控件名數(shù)組分配空間
SetLength(CHBNAME,Query.FieldCount);
SetLength(CHBShape,Query.FieldCount);
SetLength(DBNAME,Query.FieldCount);
SetLength(DBShape,Query.FieldCount);
SetLength(FBNAME,Query.FieldCount);
SetLength(FBShape,Query.FieldCount);
SetLength(SumNAME,Query.FieldCount);
SetLength(SumShape,Query.FieldCount);
end;
procedure TPrintForm.PaperSizeChg(Sender: TObject);
begin
CrtRep.Enabled:=True;
BtnPrint.Enabled:=not CrtRep.Enabled;
BtnPrview.Enabled:=BtnPrint.Enabled;
end;
procedure TPrintForm.DJChage(Sender: TObject);//對(duì)齊方式改變事件處理
var
Chg:Byte;
begin
if Djauto.Checked then Chg:=0
else if DjCenter.Checked then Chg:=1
else Chg:=2;
if Chg<>Rd1 then begin PaperSizeChg(nil);Rd1:=Chg;end;
end;
procedure TPrintForm.WdChage(Sender: TObject);//寬度改變事件處理
var
Chg:Byte;
begin
if Wdauto.Checked then Chg:=0
else if Wdall.Checked then begin
Chg:=1;
if ColWd.Text=' then ColWd.Text:='100';
end
else begin
Chg:=2;
if ColWd.Text=' then ColWd.Text:='200';
end;
if Chg<>Rd2 then begin PaperSizeChg(nil);Rd2:=Chg;end;
ColWd.Enabled:=Chg<>0;
end;
procedure TPrintForm.QuickRepStartPage(Sender: TCustomQuickRep);
//報(bào)表打印開(kāi)始新頁(yè)事件處理,頁(yè)腳帶區(qū)中的統(tǒng)計(jì)值清空
Var
I:Byte;
begin
if Tj1.Checked then
For I:=0 to Query.FieldCount-1 do
if Assigned(FBNAME[I]) then FBNAME[I].Reset;
end;
procedure TPrintForm.BtnPrintClick(Sender: TObject);
begin
QuickRep.Print;
end;
end.
4、 調(diào)用對(duì)話(huà)框舉例:
首先在將要調(diào)用的窗體中的USES語(yǔ)句中包含PrintDlg單元,然后可以用如下代碼調(diào)用:
if not assigned(PrintForm) then PrintForm:=TPrintForm.Create(application);
PrintForm.Query.SQL.Assign(Query.SQL);
//如果調(diào)用窗體不包含Query控件,可直接設(shè)置SQL語(yǔ)句的值
PrintForm.Bt:=報(bào)表標(biāo)題;
PrintForm.Caption:=窗體標(biāo)題;
PrintForm.CXTJ:=查詢(xún)條件;
PrintForm.ShowModal;
5、 結(jié)束語(yǔ)
此程序關(guān)鍵是CreateReport事件過(guò)程和動(dòng)態(tài)控件名稱(chēng)的處理。由于編幅所限,有些內(nèi)容沒(méi)有說(shuō)明,希望讀者自行體會(huì)。對(duì)于一般的報(bào)表生成,此程序能夠滿(mǎn)足要求。
本人有最新版本,功能更強(qiáng),有需要的朋友可發(fā)郵件給我,一定郵的。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注