一.程序说明 本人在日常实际开发应用中,要求实现在同一数据窗口中直观、迅速地对数据库中的数据进行分类、明细查询,同时能够清楚地显示数据关键字的层次关系。这使人很容易想到使用一种类似于Windows的资源管理器的结构来查询数据,这样会使用户查询界面非常友好,查询工作更为方便。此外,实际需求还要求能够将符合当前查询条件的数据(即当前活动窗口)全部转出为Excel文件,以实现更为方便的数据排版、编辑及打印工作,Delphi中的Server组件所提供的Excel控件可以很好地解决这个问题。 本例在制作中使用了1个TreeView控件、1个DataSource控件、1个ADOConnection控件、1个ADOTable控件、1个DBGrid控件、2个ADOQuery控件、1个ExcelApplication控件、1个ExcelWorksheet控件、1个ExcelWorkbook控件、4个Button控件。Delphi版本为6.0,数据库版本为Access2002。 二.实例效果
图1 运行效果图
图2 按所属单位筛选图
图3 按下级节点(车架号)展开图
图4 全部展开图
图5 转出为Excel后截屏图 三.制作步骤 (一)数据库采用Acess2002建立,本例名为CB.MDB,表名为“车辆投保表”,具体结构不再详述。 (二)窗体界面的建立 新建一个窗体,在其上相应添加所需组件(如一、程序说明中所述)。 (三)控件属性设置 1.ADOConnection1:ConnnectionString项目,根据系统引导自动建立,提供程序使用Microsoft.Jet.OLEDB.4.0。本例中数据库为本目录下CB.MDB。 2.ADOTable1:Connection属性选择“ADOConnection1”,TableName选择“车辆投保表”。 3.ADOQuery1:Connection属性选择“ADOConnection1”,SQL项录入以下SQL语句“select distinct 投保单位 from 车辆投保表”。 4.ADOQuery2:Connection属性选择“ADOConnection1”,SQL项录入以下SQL语句“select distinct 车架号 from 车辆投保表 where 投保单位=:TBDW”,同时Parameters项中增加一个名为“TBDW”的变量。 5.DataSource1:DataSet属性设为“ADOTable1”。 6.ExcelApplication1、ExcelWorksheet1、ExcelWorkbook1全部为默认设置。 7.4个Button按钮:Font项设为宋体9号字。 四.源代码及说明 1.FormCreate事件 //本事件定义了系统运行后所形成的资源管理器界面,数据自动由数据表中取出并按要求组织。 Procedure TForm1.FormCreate(Sender: TObject); var Node1:TTreeNode; NodeText1:string; NodeText2:string; begin With TreeView1.Items do Begin Clear; With ADOQuery1 do Begin Active :=True; First; While not eof do Begin //增加一级节点 NodeText1:=FieldValues['投保单位']; Node1:=Add(nil,NodeText1); With ADOQuery2 do Begin //取得属于当前单位的数据集合 Active:=False; Parameters.ParamByName('TBDW').Value:=NodeText1; Active:=True; First; While not eof do Begin //形成二级节点 NodeText2:=FieldValues['车架号']; AddChild(Node1,NodeText2); Next; End; End; Next; End; End End; ADOQuery1.Close ; ADOQuery2.Close ; end; 2.TreeViel1中增加OnClick事件,用于选择节点,并触发ADOTable1的数据过滤事件。 Procedure TForm1.TreeView1Click(Sender: TObject); begin If not ADOTable1.Active Then ADOTABLE1.Active :=True; ADOTable1.Filtered :=False; ADOTable1.Filtered :=True; end; 3.ADOTable1的OnFilterRecord事件 //本事件在TreeView选择不同节点时,将所选值做为ADOTable1的过滤条件传//递过来,系统根据级别对相应字段进行过滤 Procedure TForm1.ADOTable1FilterRecord(DataSet: TDataSet;var Accept: Boolean); begin Case TreeView1.Selected.Level OF 0:Accept:=(ADOTable1.Fields [1].AsString=TreeView1.Selected.Text); 1:Accept:=(ADOTable1.Fields[4].AsString=TreeView1.Selected.Text); End; end; 4.为了方便将DBGrid中的数据转为Excel,本例新定义了一个将DBGrid做为参数的过程,用于完成将DBGrid中数据向Excel转出。(本例截取的是一个系统中的一部分,读者在参考时,可以不用新定义该过程,而将全部的转出过程做少许修改,定义为Button3的Click事件即可)该过程作者将其命名为Excel_App。 Procedure TForm1.Excel_App(DBGrid:TDBgrid); var //定义数据转出时的行列变量,Query变量用于取得DBGrid的DataSet集。 i,row,column:integer; Query:TDataSet; Begin //连接EXCEL,如果未安装Excel,结束程序 Try ExcelApplication1.Connect; Except MessageDlg('是否正确安装了Excel?',mtError,[Mbok],0); Abort; End; //完成工作表连接 ExcelApplication1.Visible[0]:=True; ExcelApplication1.Caption:='数据转出'; ExcelApplication1.Workbooks.Add(Null,0); ExcelWorkbook1.ConnectTo(ExcelApplication1.Workbooks[1]); ExcelWorksheet1.ConnectTo (ExcelWorkbook1.Worksheets[1] as _Worksheet); //开始完成数据导出,设置第一行表头 for i:=1 to DBGrid.FieldCount do Begin ExcelWorksheet1.Cells.Item[1,i]:=DBGrid.Fields[i-1].FieldName; End; //开始导出内容 Query:=DBGrid.DataSource.DataSet; row:=2; With Query do Begin First; While not eof do Begin column:=1; for i:=1 to FieldCount do Begin ExcelWorksheet1.Cells.Item[row,column]:=Fields[i-1].Value; column:=column+1; end; Next; row:=row+1; end; end; //内容导出完成,断开Excel连接 ExcelApplication1.Disconnect; end; 5.Button3的Click事件,运行以上所定义的过程,将DBGrid1做为参数传递给Excel_App。 Procedure TForm1.Button3Click(Sender: TObject); begin Excel_App(DBGrid1); end; 6.Button1的Click事件,完成树形结构展开。 Procedure TForm1.Button1Click(Sender: TObject); begin TreeView1.FullExpand ; end; 7.Button2的Click事件,取消树形展开。 Procedure TForm1.Button2Click(Sender: TObject); begin TreeView1.FullCollapse ; end; 8.Button4的Click事件,关闭窗口。 Procedure TForm1.Button4Click(Sender: TObject); begin Close; end; 至此,全部程序结束。
(作者:李宁)
|