目前,在軟體開發工具中,Delphi以其控制多、物件導向程式設計功能強、程式碼執行速度快和簡單易用等特點,結合視覺化開發環境和當前最快的編譯器技術,已成為全球公認的快速應用開發工具,正被愈來愈多的程式設計人員所採用。使用Delphi可以編寫各種Windows應用程序,尤其是開發資料庫資訊管理系統有其獨特的優點。在資料庫資訊管理系統的開發的過程中,我們常常需要列印很多報表,用Delphi設計複雜報表是一件比較煩鎖的事件,它沒有Visual FoxPRo中那麼簡便。但由於Delphi中設計報表採用的也是控件,因此,我們可以在程式執行時直接建立所需的報表控件來即時產生報表,而且,產生的報表樣工可以由程式控制來決定。例如,我們在資料庫資訊查詢時,查詢出來的結果資訊結構一般是不固定的,假如我們要將查詢結果列印出來,只設計一種報表格式是不行的,為所有可能的結果資訊設計一種報表格式也不是一種很好的解決辦法。為了解決這樣一個問題,我們可以採用即時產生報表技術。本文的目的就是透過一個實例向大家詳細介紹怎樣即時產生報表。
本例所將設計一個列印對話框,該對話框包括TQickRep控件和一些報表樣式控制控件,其它窗體外觀如下圖所示:
1、 控制功能說明
QuickRep:TQuickRep 它包括列標頭(HB:TQRBand)、細節(DB:TQRBand)、頁腳(FB:TQRBand)、總結(SB:TQRBand)帶區,並且細節、頁腳、總結中沒有包括一個TQRLabel 、TQRExpr或TDBText控件,主要是在程式執行時建立,列標頭帶區中包括Title(TQRLabel)用於報表標題;QRSQL: TQRLabel用於查詢條件,這兩個控制項的Caption屬性在程式執行時可任意變更。為了能夠讓QuickRep不顯示出來,將其置於Panel1(Tpanel)的後面,並將Panel1擴展到整個窗體;
Query:TQuery SQL語句控制項,程式將根據Query傳回的結果來產生報表。因此,在建立這個窗體時,一定要將Query.SQL屬性指定一條SQL語句;
在上述視窗中「紙張」和「頁面設定」兩欄所包含的控制項是對QuickRep.Page屬性的控制,程式執行時變更它們會直接改變QuickRep控制項對應的屬性值,這可以透過OnChange或OnExit事件代碼完成;
「列印內容設定」欄中的標題是指定報表的標題(TT:TEdit),其值與QuickRep.ReportTitle和Title.Caption一致,可以任意變更;「列印查詢條件」複選框指定是否列印查詢條件,此複選框的選取否直接控制QRSQL.Caption是否為空;「表列對齊方式」由一組選項按鈕組成,它主要用於報表產生時細節內容的對齊方式,它的變更控制變數RD1 (Byte)的值(0自動對齊,1中間對齊,2左邊對齊);「表列列印寬度」由一組選項按鈕組成,主要用於在產生報表格式時列值的寬度,它的更改控制變量RD2(Byte)的值(0自動寬度, 1相同寬度,2限制最大寬度),當選取1相同寬度,2限制最大寬度時要求輸入寬度,單位為像素;「統計方式」指出報表是否包含頁尾(FB:TQRBAND)和總和(SB:TQRBAND )帶區。
2、 程序說明
程式定義瞭如下類型:
TQRLabelName=array of TQRLabel;
TQRDBTextName=array of TQRDBText;
TQRShapeName=array of TQRShape;
TQRExpName=array of TQRExpr;
上述類型為動態數組類型,資料的每個元素為一個類別。在即時建立報表控制項時,要建立的控制項個數是不確定的且控制名稱也不能確定,用動態數組是比較好的解決辦法,也就是可以任意指定資料的維數,又不用自己管理記憶體分配問題,還有利於報表包含控制項的釋放與處理。程式也宣告了上述類型的變數如下:
CHBName:TQRLabelName;
DBName:TQRDBTextName;
CHBShape,DBShape,FBShape,SumShape:TQRShapeName;
FBName,SumName:TQRExpName;
這些數組變數將在窗體建立時根據Query返回的字段結果分配內存,每一個字段對就數組的一個元素。
程式執行過程:窗體在建立並顯示時,就對本窗體建立初始化操作。在OnCreate事件中將QuickRep.Page屬性的對應值顯示出來,在OnShow事件中執行Query.Open操作,並根據傳回結果指派控制項數組變數空間。表單建立後,按一下「產生」按鈕產生報表(忽略備註欄位和相片欄位),然後可按一下「列印」和「預覽」進行列印或預覽報表。當產生報表後又更改了設置,必須重新產生報表。如果Query回傳的結果集欄位太多,產生報表時有可能紙張礦小不能將產生全部報表,可調整報表紙張大小,再產生報表。關閉窗體時,將釋放已建立的控制項。
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;//列標頭帶區中列標題控製件類別動態陣列
TQRDBTextName=array of TQRDBText; //細節帶區中列標題控製件類別動態陣列
TQRShapeName=array of TQRShape; //線條控製件類別動態數組
TQRExpName=array of TQRExpr; //統計控製件類別動態陣列
TPrintForm = class(TForm)
GroupBox1: TGroupBox;
Label5: TLabel;
BtnSet: TbitBtn;//「設定」按鈕控件
BtnCancel: TBitBtn;// “關閉”按鈕控件
Panel1: TPanel;
BtnPrint: TBitBtn;// “列印”按鈕控件
BtnPrview: TBitBtn;// “預覽”按下控制鈕
QuickRep: TQuickRep;// 快速報表控件
HB: TQRBand;// “列標頭”帶區控件
Title: TQRLabel;// 報表標題控件
QRE1: TQRExpr;// 列標頭帶區中「頁碼」控件
QRE2: TQRExpr;//列標頭帶區中「日期」控件
Panel2: TPanel;
Label1: TLabel;
R1: TRadioButton;//“ 縱向列印”控件
R2: TRadioButton;// “橫向列印”控件
GroupBox4: TGroupBox;
TT: TEdit;// 標題輸入框控件
Label2: TLabel;
SR: TCheckBox;// “列印查詢條件”控件
Label3: TLabel;
Image1: TImage;//顯示縱向列印影像
Image2: TImage;//顯示橫向列印影像
QRSQL: TQRLabel;// 列標頭帶區中用於顯示「查詢條件」控件
GroupBox2: TGroupBox;
Label7: TLabel;
Label8: TLabel;
Label9: TLabel;
Label10: TLabel;
Label11: TLabel;
Label12: TLabel;
Label13: TLabel;
PageSpace: TEdit;// 欄間距輸入框控件
PageTop: TEdit;// 頁邊距上輸入框控件
PageBottom: TEdit; // 頁邊距下輸入框控件
PageLeft: TEdit; // 頁邊距左輸入框控件
PageRight: TEdit; // 頁邊距右輸入框控件
PageDlux: TCheckBox; // “雙面列印”控制項
PageCol: TEdit; // 分欄輸入框控件
Pages: TEdit; // 列印份數輸入框控件
PaperH: TEdit; // 紙張長度輸入框控件
PaperW: TEdit;//紙張寬度輸入框控件
Label4: TLabel;
Label6: TLabel;
Ps: TComboBox;//紙張型號列錶框控件
Query: TQuery;//SQL查詢控件
DB: TQRBand;// “細節”帶區控件
CrtRep: TBitBtn; // “生成”按鈕控件
Label14: TLabel;
Label15: TLabel;
Panel3: TPanel;
Wdauto: TRadioButton; // “自動寬度”控件
Wdall: TRadioButton; // “相同寬度”控件
Wdmax: TRadioButton; // “限制最在寬度”控件
Label16: TLabel;
ColWd: TEdit; // 列寬輸入框控件
Panel4: TPanel;
DJAUTO: TRadioButton; // “自動對齊”控件
DJCENTER: TRadioButton; // “中間中齊”控件
DJLEFT: TRadioButton; // “左邊對齊”控件
FB: TQRBand; // 頁腳帶區控件
Label17: TLabel;
Panel5: TPanel;
TJ1: TCheckBox; // “每頁統計”控件
TJ2: TCheckBox; // “統計總和”控件
SB: TQRBand; // 總和帶區控件
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;//定義列標頭帶區控制項名稱動態陣列名
DBName:TQRDBTextName; //定義細節帶區控制項名稱動態陣列名
CHBShape,DBShape,FBShape,SumShape:TQRShapeName; //定義線條控制項動態陣列名
FBName,SumName:TQRExpName; //定義頁尾(FBNAME)和總和帶區(SUMNAME)控制項名稱動態陣列名
DJ:TAlignment;//列對齊方式(taLeftJustify, taRightJustify, taCenter)
Rd1,Rd2:Byte;//用於保存表格對齊方式(RD1)和列印寬度(RD2)狀態變數名
public
{ Public declarations }
CXTJ,BT:String;//CXTJ存放查詢條件,BT存放報表標題
//由上一級視窗指定
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所列出的紙張類型
var
PrintForm: TPrintForm;
implementation
{$R *.DFM}
procedure TPrintForm.FormCreate(Sender: TObject);
//將QuickRep.Page屬性以及其它屬性值顯示出來
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列錶框顯示紙張類型
if QuickRep.Page.PaperSize=PaperSize[I] then begin
PS.ItemIndex:=I;
Break;
end;
//判斷紙張寬度是否可以更改,只有紙張類型為自訂(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;
//交換紙張寬度和長度的值
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);//標題更改事件處理
begin
QuickRep.ReportTitle:=TT.Text;
Title.Caption:=TT.Text;
Bt:=TT.Text;
end;
procedure TPrintForm.DTClick(Sender: TObject);//列印查詢條件複選框事件
begin
QRSQL.Enabled:=SR.Checked;
end;
procedure TPrintForm.BtnPrviewClick(Sender: TObject);//預覽按鈕點選事件
begin
QuickRep.Preview;
end;
procedure TPrintForm.BtnSetClick(Sender: TObject); //設定按鈕點選事件
begin
QuickRep.PrinterSetup;
end;
procedure TPrintForm.PsChange(Sender: TObject);//紙張類型改變事件
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);//紙張寬度和長度改變事件
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;//設定標題
ClearRep(); //清除已經建立的物件;
if Sr.Checked then QrSQL.Caption:=CXTJ else QRSQL.Caption:=';//是否印出查詢條件?
CHBtp:=HB.Height-17;//建立的控制項在帶區中的頂部位置
CHBlf:=0; //建立的控制項在帶區中的左邊位置
ObWidth:=0; //建立的控制項的寬度
for I := 0 to Query.FieldCount-1 do //根據Query回傳字段數建立控件
begin
if (Query.Fields[I].DataType<>ftBlob) And (Query.Fields[I].DataType<>ftMemo) then
begin //忽略備註字段和相片字段
L:=Query.Fields[I].DataSize-1;//L=欄位寬度(位元組)-1
case Rd1 of //根據所選的對齊方式設定控制項的對齊方式
0: if L<=10 then Dj:=taCenter else DJ:=taLeftJustify;
//自動對齊:欄位小於等於10居中對齊,否則左邊對齊
1: Dj:=taCenter;//居中對齊
2: DJ:=taLeftJustify;//左邊對齊
end;
case Rd2 of //根據所選的清單寬度設定報表列寬度
0: begin
//自動寬度:如果L>14則寬度ObWidth=14+(L-14)/2;如果ObWidth
//的寬度不能顯示列標題,則ObWidth=列標題寬度;如果欄位類型
//為日期型、貨幣型和浮點數型,則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 //限制最大寬度:先以自動寬度計算再判斷寬度是否超最大值,
//如果超過則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:='紙張寬度不夠,請更改紙張尺寸。 ';
MessageBox(Handle,DlgMes,Cap_Inf,Ico_Inf);
break;
end
else begin
CHBShape[I]:=TQRShape.Create(HB);//建立列標頭帶區線控件
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); //建立列標題控件
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); //建立細節帶區線條控件
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); //建立細節帶區控件
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 //是否建立頁腳帶區?
FBShape[I]:=TQRShape.Create(FB); //建立頁腳帶區線條控件
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 //如果欄位類型為數值類型則建立
FBNAME[I]:=TQRExpr.Create(FB); //建立頁腳帶區控件
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 //是否建立總和帶區?
SumShape[I]:=TQRShape.Create(SB); //建立總和帶區線控件
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 //如果欄位類型為數值類型則建立
SumNAME[I]:=TQRExpr.Create(SB); //建立總和帶區控件
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;//目前欄位處理完成,往右一個欄位寬度
end;
end;
end;
CrtRep.Enabled:=False;//禁上產生按鈕
BtnPrint.Enabled:=not CrtRep.Enabled;允許列印銨鈕
BtnPrview.Enabled:=BtnPrint.Enabled;允許預覽按鈕
if Tj1.Checked then begin //如果建立了頁腳帶區,則將頁腳帶區中前兩列更改
FBNAME[0].Expression:=''頁合計'';
FBNAME[1].Expression:='COUNT+'行'';
end;
if Tj1.Checked then begin //如果建立了總和帶區,則將總和帶區中前兩列更改
SumNAME[0].Expression:=''總計'';
SumNAME[1].Expression:='COUNT+'行'';
end;
//調整列標頭帶區內的日期及頁碼列印位置
QRE2.Left:=HB.Width-Qre2.Width;
QRSQL.Left:=QRE1.Width+10;
QRSQL.Width:= QRE2.Left-10-QRSQL.Left;
QuickRep.DataSet:=Query; //為QuickRep指定資料集,該句一定不能少
Screen.Cursor:=crDefault;
end;
procedure TPrintForm.ClearRep();//清除生成報表格式時所建立的控制項
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;//設定標題
//控制項名稱數組分配空間
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);//對齊方式改變事件處理
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);
//報表列印開始新頁事件處理,頁腳帶區中的統計值清空
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、 呼叫對話框舉例:
首先在將要呼叫的窗體中的USES語句中包含PrintDlg單元,然後可以用以下程式碼呼叫:
if not assigned(PrintForm) then PrintForm:=TPrintForm.Create(application);
PrintForm.Query.SQL.Assign(Query.SQL);
//如果呼叫窗體不包含Query控制項,可直接設定SQL語句的值
PrintForm.Bt:=報表標題;
PrintForm.Caption:=窗體標題;
PrintForm.CXTJ:=查詢條件;
PrintForm.ShowModal;
5、 結束語
此程式關鍵是CreateReport事件過程和動態控制項名稱的處理。由於編幅所限,有些內容沒有說明,希望讀者自行體會。對於一般的報表生成,此程式能夠滿足要求。
本人有最新版本,功能更強,有需要的朋友可寄email給我,一定郵的。