在PB中实现交叉表转Excel表格

软件世界

在PB中,可以用saveas()函数把数据窗口中的数据转为Excel表格的形式。但是要把数据窗口的数据转为精美的Excel表格,还要知道如何用PB完成对Excel表格的操作。交叉表(crosstab风格的数据窗口)是一种比较复杂的数据窗口对象。由于它的列数不固定,给读取合计数据造成困难。本例就是把交叉表转为精美的Excel表格,希望对大家有所帮助。

一、 定义crosstab数据窗口

数据库中的金融机构信息表存有各家金融机构的数据信息(包括金融机构名称代码和机构级别代码)。金融机构名称代码表中存放机构代码和机构名称,机构级别代码表中存放机构级别代码和机构级别名称。以此三个表定义crosstab数据窗口要完成以机构名称为列和机构级别为行的统计金融机构数目的功能。数据窗口的header(1)区存放表格的标题、日期范围。header(3)区存放各列名称。Detail区存放统计数据。Summary区存放汇总数据。Footer区存放报表制作时间和用户名称。

二、实现代码

运行程序时,数据显示如(图1)所示,其中“转存”按钮用来完成把crosstab数据窗口转为Excel表格的功能。程序先用saveas()函数把数据窗口中的数据转为Excel表格的形式,再以OLE对象方式打开Excel表格,增加列合计数据,增加行合计数据,在第一行前增加一行,定义统计时间,再增加一行,定义标题,修改标题属性,定义制表时间和制表人,修改Excel显示格式。其代码如下:

图1
图1

long ii,i,jj,k,kk
int maxlen
string ls_file_name,lefttop,rightbottom, ss
pointer old
oleobject ole1 //定义各变量
old=setpointer(HourGlass!)
ls_file_name=dw_1.object.title.text+
string(today(),'yymmdd')+'.xls' //要转存的Excel表格名称
if fileexists(gs_reportpath+ls_file_name)then // gs_reportpath为全局变量,是表格所在目录if messagebox('警告','文件'+ls_file_name+'已经存在,是否继续!',Question!,YesNo!)=2 then
return
end if
end if
dw_1.saveas(gs_reportpath+ls_file_name,Excel!,true)
this.enabled=false //防止保存两次以上
ole1=create oleobject
if ole1.connecttonewobject("Excel.application")<>0 then
messagebox("通告","OLE连接失败!",exclamation!,ok!)
return
end if
ole1.application.workbooks.open(gs_reportpath+ls_file_name)
ole1.application.WindowState = 3
ole1.application.Windows(1).WindowState = 2 //Excel表格最大化
ole1.application.Workbooks(ls_file_name).Activate
//以下取得每行合计数,写入Excel表格的列合计
j=upperbound(ls_arr)+2 //ls_arr为全局数组变量,存放各机构名称
ole1.application.cells(1,j).value='合计:'
maxlen=0
jj=0
for i=1 to dw_1.rowcount() //dw_1为交叉表的数据窗口
if len(trim(dw_1.getitemstring(i,'orggradename')))>maxlen then maxlen=len(trim(dw_1.getitemstring(i,'orggradename')))
end if
kk=dw_1.getitemnumber(i,'grand_sum_compute_0003')
ole1.application.cells(i+1,j).value=string(kk)
jj=jj+kk
next
ole1.application.cells(i+1,j).value=string(jj) //行的总合计数
ole1.application.Worksheets(1).Columns(1).columnwidth=maxlen//设置第1列宽度
//至此,Excel表格每行合计数写入完毕。以下为增加每列合计数
ii=upperbound(ls_arr) //ls_arr为全局数组变量,存放各机构名称
ole1.application.cells(dw_1.rowcount()+2,j).value=dw_1.getitemnumber(1,'compute_2')
for i=2 to ii
ss='compute_2_'+string(i-1) //computer_2为定义交叉表时的列合计,由于交叉表列
//不固定,列名为:computer_2,computer_2_1,computer_2_2……
ole1.application.cells(dw_1.rowcount()+2,j).value=dw_1.getitemnumber(1,ss)
next
//每列合计数写入完毕。以下修改Excel显示格式
ole1.application.cells(dw_1.rowcount()+2,j).value=string(dw_1,getitemnumber(1,'computer_8')) lefttop="a1"
rightbottom=char(asc('a')+j -1)+string(dw_1.rowcount()+2)
ole1.application.Worksheets(1).Range(lefttop,rightbottom).Borders.LineStyle=1
//设置Excel表格为实线
ole1.application.cells(dw_1.rowcount()+3,1).value="制表时间:" + string(year(today( )+'年'+string(month(today( )+'月'+string(day(today( )+'日'
ole1.application.cells(dw_1.rowcount()+3,j-1).value="制表人:" + usercode
//设置制表时间和制表人
//以下设置Excel标题和统计时间范围
ole1.application.Worksheets(1).Rows(1).Insert //在第1行上方增加一行。
ole1.application.cells(1,1).value= dw_1.object.date.text
ole1.application.Worksheets(1).Rows(1).Insert
ole1.application.cells(1,int(j/2)).value=dw_1.object.title.text
ole1.application.cells(1,int(j/2)).font.size=24 //设置字体大小
ole1.application.cells(1,int(j/2)).font.bold=true //设置为粗体
ole1.application.visible = TRUE //使Excel表格可见
destroy ole1
setpointer(old)
messagebox('提示','转存文件成功!~n~r')
此代码在PowerBuilder 7.0下通过。在本例中,数据窗口用的是交叉表,如果是其他形式的表格,则更为简单。