文章编号:100622475(2002)1020073203
计 算 机 与 现 代 化
JISUANJIYUXIANDAIHUA
总第86期
Delphi动态报表的设计实现
高晓超
(南京航空航天大学计算机科学与工程系,江苏南京 210016)
摘要:介绍Delphi环境中利用Delphi自带控件生成动态报表以及通过Excel自动化技术增强Delphi动态报表处理功能的方法。该方法灵活、简便、实用性强。关键词:动态报表;Delphi;OLE自动化中图分类号:TP399 文献标识码:A
DesignandImplementationofDynamicReportwithDelphi
GAOXiao2chao
(Dep.ofComputerScienceandEngineering,NanjingUniversityofAeronauticsandAstronautics,Nanjing 210016,China)Abstract:IntroducesamethodabouthowtodesigndynamicreportwithDelphicomponentsandExcel.Thismethodisflexible,simpleandpractical.
Keywords:dynamicreport;Delphi;OLEautomation0 引 言
报表是管理信息系统的重要组成部分,在系统实
施和交付使用中,用户在很大程度上是用生成统计报表的方便性和灵活性来评价系统的成功与否。同时,报表的生成也是MIS系统开发中最麻烦的一项工作,国内报表格式复杂多样,用户经常会对报表的生成提出不同的要求,包括报表格式调整、字段的增删、不同的统计要求等,降低了系统的通用性,这一直是使程序员头疼的事。
介绍用PowerBuilder开发动态报表的文章较多,本文介绍如何用Delphi动态选择所需数据,动态生成报表。这种动态方式生成的报表更加灵活,也更加容易做到报表的格式统一。
1 解决方法
一般有两种方法生成动态报表:(1)在程序运行阶段动态生成并执行SQL语句,利用Create方法动态创建控件,设置其Parent属性来设置其容器控件。然后,在程序中根据所选择的数据库表中的数据字段的长度和数目,通过修改控件的大小和位置属性,来控
制控件的大小和外观。该法操作简单,但用户只能对报表进行小的改动。(2)利用Delphi强大的OLE功能,操作Excel对象来实现Excel自动化,由应用程序提取数据传给Excel进行格式加工处理。利用Excel可以制作出几乎任意格式的报表,减轻了开发者的工作量,也增加了软件的通用性;但是同时增加了用户处理数据的工作量。
综合考虑,笔者在系统中采用两者结合的方法,先用Delphi自带的控件生成动态报表供用户预览,如果用户认为只需小的改动(字段宽度、高度、顺序、字体、对齐方式等),则采用方法一继续修改,如果用户认为需大的改动(修改表头、页尾、对数据作进一步处理等),则采用方法二,将数据导入Excel中由用户自行处理。实际应用中,用户定义的动态报表格式往往不只用一次,因此用户可以将报表格式信息保存为模板以备下次使用。
2 主要工作流程
(1)如果已有报表模板满足用户需要,则可以直
接打印输出;否则进行下面步骤;
(2)用户选择报表字段及其排列顺序、查询条件;
收稿日期:2002204212
作者简介:高晓超(19772),男,河北深州人,南京航空航天大学计算机科学与工程系硕士研究生,研究方向:系统软件。
74计 算 机 与 现 代 化2002年第10期
(3)根据用户选择的结果,生成并执行SQL查询Box1中选中了数据库本身就有的表单,则单击“〉〉”
语句,产生动态报表数据集TempSet;
(4)以TempSet为数据源,生成一个显示网格DB2Grid;
(5)让用户选择报表打印方向(横向或纵向),调
按钮即可将该表加入“选中表名”Listbox2中;(2)如果用户要修改现有的报表模板,则只需双击“待选表名”ListBox1中的报表模板名,该模板中的选中表单名、选
中字段、选择条件、排序条件等就会从模板文件中读出,供用户修改。3.2 报表的生成
节网格DBGrid的行列宽度、高度、字体、字段对齐方
式等以决定报表数据的位置;
(6)依照DBGrid的字段名称、宽度、高度、字体和对齐方式等信息生成报表预览;
(7)若需小的修改则转(4),若需大的修改则将TempSet数据导入Excel中,由用户处理;若用户满意
由于报表在预览情况下不能修改,只能在预览前将报表格式设定好。笔者通过实践,利用DBGrid解决了报表格式设置问题。
首先按照控件Query1的SQL语句执行的结果(也就是动态报表数据集TempSet)生成一个显示网格DBGrid。
则保存字段信息和报表格式作为模板,并打印输出。
3 具体实现
下面主要讨论现有报表不能满足用户需要时的情况。3.1 动态报表数据集TempSet的产生
如图1所示,控件Listbox1记录现有报表模板名和数据库中所有表名,Listbox2记录选中输出的表名,对应SQL语句的From部分,Listbox3记录与List2box2选中表名相对应的字段名,Listbox4记录选中输出的字段名,对应SQL语句的Select部分;Edit1记录选择条件,对应SQL语句的Where部分;Combobox2记录所有运算符,Edit2记录排序条件,对应SQL语句的Sortby部分。
然后由用户选择报表标题内容、字体、打印方向(横向或纵向),修改DBGrid控件的字段顺序、对齐方式、字体、行列宽度和高度等属性。DBGrid不只是起到显示数据的作用,而且用户对DBGrid作的调整,例如改变了各字段的排列顺序、显示宽度、高度、字体、对齐方式等,都将直接反映到预览结果中去,也就是说,对于报表的数据内容实现了所见即所得的效果。用户边修改边预览,即可以得到最佳效果,又省去了检验字段是否超出了打印纸范围的过程。
下面的一段示例程序将DBGrid中的数据显示在报表中。至于报表的标题、各列的标题、页脚等信息的打印可以用类似的方法实现,不再赘述。
nowleft:=5;//左边距withquickrep1dobegin
fori:=0toDBGrid1.Columns.Count21dobeginWithTQRDBText.Create(DetailBand1)dobeginLeft:=nowleft;//控件左边距Top:=2;
Parent:=DetailBand1;Autosize:=false;WordWrap:=true;
Font.Assign(DBGrid1.font);//控件字体
alignment:=DBGrid1.Columns[i].Alignment;//对齐方式Width:=DBGrid1.Columns[i].Width;//控件宽度Height:=DetailBand1.Height25;//控件高度Dataset:=Query1;//控件数据源
DataField:=DBGrid1.Columns[i].FieldName;//控件对应字段Visible:=True;
inc(nowleft,Width+5);End;End;
图1 选择报表字段和条件
例如,图1中所示转换为SQL语句就是
Selectemployee.EmpNo,
employee.LastName, employee.FirstName, employee.Salary, customer.Company
Fromemployee.db,customer.db
Whereemployee.EmpNo=customer.CustNoSortbyemployee.EmpNo
需要注意的是:(1)如果用户从“待选表名”List2
2002年第10期 高晓超:Delphi动态报表的设计实现75
3.3 数据导入Excel(4)用网格DBGrid1中各列的宽度调整Excel表
有时报表需要大的修改,有时用户要对报表中的数据作进一步的加工处理,这就要把数据导入Excel中。
首先介绍一下Excel应用程序对象基本的层次结构。Application对象是顶层对象,表示应用程序的当前实例。在Application对象中有Workbooks属性,其中包含每个打开的工作簿的Workbook对象。在Workbook对象中又含有Worksheets属性,其中包含了当前工作簿中每个工作表的Worksheet对象。Work2sheet对象具有Range属性,表示访问工作表内容的基本对象:Range对象。Range对象可以包含一个单元,也可包含整个工作表。例如要选择活动工作表左上角10310可用表达式:Worksheet.Range[′A1′,′J10′]。
也可以用Cells方法将单个单元(Row,Col)作为Range对象取得: Worksheet.Cells(Row,Col)。还可以用Rows和Columns属性返回整行或整列作为Range对象,如要返回第三行作为Range对象:Worksheet.Row[3]。下面是一个应用的例子。(1)将Delphi控件面板的Servers页(Delphi5.0以上版本才有)控件ExcelApplication、ExcelWorkbook和ExcelWorksheet各添加一个到Form上,当运行程序时,Uses语句将自动加入OLEServer和Excel2000单元。
(2)增加新的工作簿,并设置当前工作簿:
ExcelApplication1.Connect;
ExcelApplication1.Workbooks.Add(Null,0);
ExcelWorkbook1.ConnectTo(ExcelApplication1.Workbooks[1]);ExcelWorksheet1.ConnectTo(ExcelWorkbook1.Worksheets[1]asWorksheet);
ExcelWorksheet1.Activate;
格各列宽度:
fori:=1toDBGrid1.Columns.Countdo
ExcelWorksheet1.Columns[i].Width:=DBGrid1.Colums[i].Width;
(5)用网格DBGrid1中的值填充Excel表格:
Query1.First;
fori:=1toQuery1.RecordCountdobeginforj:=1toDBGrid1.Columns.Countdobegin
ExcelWorksheet1.Cells(3+i,j):=DBGrid1.Columns[j21].
Field.asstring;
End;Query1.Next;End;
(6)使Excel应用程序可见,从而用户可以手工修
改报表内容:
ExcelApplication1.Visible[0]:=true;3.4 报表模板的保存及再修改用户定义的动态查询和动态报表格式往往不只使用一次,因此用户可以将字段信息、查询条件、报表格式等信息保存为模板,下次使用时可以直接使用,也可以再次修改,这样既能减少制作报表的工作量,又能保持报表格式的统一。
用INI文件来保存上述信息非常方便,不赘述,仅举一例。例如保存第n个字段项的属性如下:
[Itemn]
FieldName=字段名Width=字段宽度Height=字段高度
4 注意事项
(1)动态生成控件的宽度计算必须放在定义其字
(3)插入报表的标题并使标题跨列居中:
ExcelWorksheet1.Cells(1,1):=′报表标题′;
)+DBGrid1.ExcelWorksheet1.Range[′A1′,Chr(Ord(′A′Columns.Count)+′1′].Select;
WithExcelApplication1.SelectiondobeginHorizontalAlignment:=xlCenter;VerticalAlignment:=xlBottom;WrapText:=False;Orientation:=0;AddIndent:=False;ShrinkToFit:=False;MergeCells:=True;End;
体属性完成后进行。
(2)程序员可以根据用户的实际需求,设置表格线或者取消表格线。
(3)如果要修改QRDBText控件的数据位置,必须先设置其Autosize属性为false,然后才能设置其Alignment属性为所需的左对齐、居中或者右对齐,这一点很容易被忽略。
(4)由于用户可能多次点击预览按钮,因此必须在每次预览事件发生之前,释放上次动态创建的控件。
(5)DBGrid的列号从0开始,Excel的列号从1开始。
(下转第78页)
78常 数
NormalReadOnlyHiddenSystemArchive
计 算 机 与 现 代 化
值
012432
2002年第10期
描 述
一般文件。未设置属性。只读文件。属性为读/写。隐藏文件。属性为读/写。系统文件。属性为读/写。
自上次备份后已经改变的文件。属性为读/写。Iff.AttributesAnd2Then
r=r&″H″
EndIf
)m=MsgBox(r,0,″文件属性信息″EndSub
如果某文件的属性没设只读属性,则可用下列语
句设置只读属性:
f.Attributes=f.Attributes+1
下面的程序代码利用FSO对象模型提供的At2tributes属性来获取文件的各种属性。
PrivateSubCommand3Click()Dimfs,f,r,m
)Setfs=CreateObject(″Scripting.FileSystemObject″)Setf=fs.Getfile(″f:\\why\\xs.dbf″Iff.AttributesAnd32Then
如果某文件的属性已设置了只读属性,则可用下
列语句取消只读属性:
f.Attributes=f.Attributes21
以上程序代码在VB6.0下运行通过。
参考文献:
[1] 魏源源.VisualBasic5.0中文版程序设计教程[M].北
r=r&″A″ ′r变量中存放的是文件的属性
EndIf
Iff.AttributesAnd1Then
京:电子工业出版社,1998.
[2] 张树兵,等.VisualBasic6.0入门与提高[M].北京:清华
r=r&″R″
EndIf
大学出版社,1999.
[3] MicrosoftCorporation.MSDN简体中文版帮助系统[CP/
DK].MicrosoftCorporation,1998.
(上接第75页)
5 结束语
统计报表作为管理信息系统的一个重要组成部
分,贯穿整个系统的需求调研、系统设计和系统开发。从系统需求分析开始,我们对客户要求了解得越多,则报表越容易满足客户要求。本文给出的这种实现动态统计报表的方法,操作简便灵活,可满足用户不
同程度的需要,已成功应用于实际管理信息系统中,并深得用户好评。
参考文献:
[1] 蒋方帅.Delphi5程序员指南[M].北京:人民邮电出版
社,2000.
[2] 曹芝兰,王汉江.基于Delphi+Excel2000制作复杂报表
[J].湖北大学学报,2000,22(4).
因篇幅问题不能全部显示,请点此查看更多更全内容