|
作者:刘建华
Delphi程序执行时实时生成报表
当前,在软件开发工具中,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'''' [1] [2] [3] [4] 下一页 |