天天看点

如何将PB的交叉报表转换成EXCEL形式

如何将PB的交叉报表转换成EXCEL形式,用的办法是写一个通用的转换函数

主函数部分:(还用到了PFC的字串处理的一个函数和在本对象中的一个取值函数)

//====================================================================   
  //   [PUBLIC]   Function   uf_data2excel   在   u_data2word   inherited   from   nonvisualobject   
  //--------------------------------------------------------------------   
  //   说明:将数据倒入excel中,支持计算列及显示格式,要求在题头的计算列要写tag值   
  //--------------------------------------------------------------------   
  // 参数1:[value]   datawindow   adw   
  // 说明:数据窗口   
  //--------------------------------------------------------------------   
  //   返回: (INTEGER)   成功返回1,不成功返回0   
  //--------------------------------------------------------------------   
  //   作者: cwl 日期:   2002.03.18   
  //====================================================================   
  //变更日志:020515加入对交叉表倒出的支持(主要是修改了保存题头部分)   
    
  constant   integer   ppLayoutBlank   =   12   
  OLEObject   ole_object   
  ole_object   =   CREATE   OLEObject   
    
  integer   li_ret,li_crosstab=0   
  long   ll_colnum,ll_rownum   
  string   ls_value   
  string   ls_objects,ls_obj,ls_objs[],ls_objtag[]   
  long   ll_pos,ll_len,ll_num   =   0   
  //题头区   
  long   ll_headnum   
  string   ls_head[],ls_headtag[]   
  //合计区   
  long   ll_sumnum,i=1,startpos=1,endpos,li_pos   
  string   ls_sum[],ls_sumtag[],ls_bind,token[],list,ls_temp,ls_crosstabcol   
  n_cst_string   lu_string   //PFC   string处理对象   
    
  li_ret   =   ole_object.ConnectToObject("","Excel.Application")   
  IF   li_ret   <>   0   THEN   
  //如果Excel还没有打开,则新建。   
  li_ret   =   ole_object.ConnectToNewObject("Excel.Application")   
  if   li_ret   <>   0   then   
  MessageBox('OLE错误','OLE无法连接!错误号:'   +   string(li_ret))   
  return   0   
  end   if   
  ole_object.Visible   =   false//不可见   
  END   IF   
    
  if   adw.Object.DataWindow.Processing='4'   then   //交叉表处理   
  adw.Object.DataWindow.Crosstab.StaticMode='true'//将数据静态化   
  li_crosstab=1   
  end   if     
    
  pointer   oldpointer   
  oldpointer   =   SetPointer(HourGlass!)   
    
  //新增一个工作区   
  ole_object.Workbooks.Add   
    
    
    
  ls_objects   =   trim(adw.Describe('datawindow.Objects'))   
  list=ls_objects   
  EndPos =   pos(list,   '~t',   StartPos)   
  //得到对象列表   
  Do   while   (   EndPos   >   0   )   
  token[i]   =   Mid(list,   StartPos,   EndPos   -   StartPos)   
  i   ++   
  StartPos   =   EndPos   +   1     
  EndPos =   pos(list,   '~t',   StartPos)   
  LOOP   
  token[i]   =   Mid(list,   StartPos)   
  ll_rownum=UpperBound(token)   
    
  for   i=1   to   ll_rownum   
  ls_obj   =   token[i]   
  if   ls_obj='title'   then   messagebox('',adw.Describe(ls_obj   +   '.type'))   
  if   lower(adw.Describe(ls_obj   +   '.type'))   =   'column'   or   &   
  lower(adw.Describe(ls_obj   +   '.type'))   =   'compute'   then   
  ls_bind=lower(adw.Describe(ls_obj   +   '.band'))   
  if   ls_bind   =   'detail'   then     
  ll_num   +=   1   
  ls_objs[ll_num]   =   ls_obj   
  if   li_crosstab=0   then   //一般处理   
  ls_objtag[ll_num]   =   adw.Describe(ls_obj   +   '_t.text')   
  elseif   li_crosstab=1   then   //交叉表处理   
  li_pos=lu_string.of_lastpos(ls_obj,'_',len(ls_obj))//找出最后一次出现'_'的位置   
  if   li_pos=0   or   (not   isnumber(mid(ls_obj,li_pos+1)))   then   //不是交叉列   
  ls_objtag[ll_num]   =   adw.Describe(ls_obj   +   '_t.text')   
  else   
  ls_temp=mid(ls_obj,li_pos)   
  ls_crosstabcol=mid(ls_obj,1,li_pos   -   1)//取出交叉列名   
  // messagebox('',ls_crosstabcol+',,,,'+ls_temp)   
  ls_objtag[ll_num]=adw.Describe(   ls_crosstabcol   +   "_t"+ls_temp+".Text"   )//取出交叉表的题头   
  end   if     
  end   if     
  elseif   (ls_bind   =   'summary')   then     
  ll_sumnum   +=   1   
  ls_sum[ll_sumnum]   =   ls_obj   
  ls_sumtag[ll_sumnum]   =   adw.Describe(ls_obj   +   '.tag')   
  else   
  ll_headnum   +=   1   
  ls_head[ll_headnum]   =   ls_obj   
  ls_headtag[ll_headnum]   =   adw.Describe(ls_obj   +   '.tag')   
  end   if     
    
  end   if   
    
  next   
    
  //得到数据窗口数据的列数与行数(行数应该是数据行数   +   2)   
  ll_colnum   =   ll_num   
  ll_rownum   =   adw.rowcount()   +   2   
    
  string   column_name   
  string   ls_colname   
  integer   j,k   
  //写题头   
  for   i=1   to   ll_headnum   
  ls_value   =   ls_headtag[i]   
  if   ls_value<>'?'   then     
  ole_object.cells(1,(i   -   1)*2+1).value   =   ls_value   
  end   if     
  column_name   =   ls_head[i]   
  ls_value=this.uf_getdata(adw,column_name,1)   
  ole_object.cells(1,(i)*2).value   =   ls_value   
  next   
  //写结尾   
  for   i=1   to   ll_sumnum   
  ls_value   =   ls_sumtag[i]   
  if   ls_value<>'?'   then     
  ole_object.cells(ll_rownum+1,(i   -   1)*2+1).value   =   ls_value   
  end   if     
  column_name   =   ls_sum[i]   
  ls_value=this.uf_getdata(adw,column_name,1)   
  ole_object.cells(ll_rownum+1,(i)*2).value   =   ls_value   
  next   
    
  //写标题   
  for   i   =   1   to   ll_colnum   
  //得到标题头的名字   
  ls_value   =   ls_objtag[i]   
  ole_object.cells(2,i).value   =   ls_value   
  next   
  //写数据   
  for   i   =   3   to   ll_rownum   
  for   j   =   1   to   ll_colnum   
  column_name   =   ls_objs[j]   
  ls_value=this.uf_getdata(adw,column_name,i   -   2)   
  ole_object.cells(i,j).value   =   ls_value   
  next   
  next   
    
  SetPointer(oldpointer)   
  ole_object.Visible   =   True   
  ole_object.disconnectobject()   
  DESTROY   ole_object   
    
  return   1   

           

PFC的字串处理函数(可直接改成全局函数就可用了)

//====================================================================   
  //   [PUBLIC]   Function   of_lastpos   在   n_cst_string   inherited   from   n_ccu_base   
  //--------------------------------------------------------------------   
  //   说明:找出一字串在另一串中最后出现的位置   
  //--------------------------------------------------------------------   
  // 参数1:[value]   string   as_source   
  // 说明:源串   
  // 参数2:[value]   string   as_target   
  // 说明:目标串   
  // 参数3:[value]   long   al_start   
  // 说明:开始位置   
  //--------------------------------------------------------------------   
  //   返回: (LONG)   从右数起出现的位置,找不到则返回0   
  //--------------------------------------------------------------------   
    
  Long ll_Cnt,   ll_Pos   
    
  //Check   for   Null   Parameters.   
  IF   IsNull(as_source)   or   IsNull(as_target)   or   IsNull(al_start)   Then   
  SetNull(ll_Cnt)   
  Return   ll_Cnt   
  End   If   
    
  //Check   for   an   empty   string   
  If   Len(as_Source)   =   0   Then   
  Return   0   
  End   If   
    
  //   Check   for   the   starting   position,   0   means   start   at   the   end.   
  If   al_start=0   Then       
  al_start=Len(as_Source)   
  End   If   
    
  //Perform   find   
  For   ll_Cnt   =   al_start   to   1   Step   -1   
  ll_Pos   =   Pos(as_Source,   as_Target,   ll_Cnt)   
  If   ll_Pos   =   ll_Cnt   Then     
  //String   was   found   
  Return   ll_Cnt   
  End   If   
  Next   
    
  //String   was   not   found   
  Return   0
           

得到一个数据窗口列及计算列的准确显示值函数

//====================================================================   
  //   [PUBLIC]   Function   uf_getdata   在   u_data2word   inherited   from   nonvisualobject   
  //--------------------------------------------------------------------   
  //   说明:得到一个数据窗口列及计算列的准确显示值   
  //--------------------------------------------------------------------   
  // 参数1:[value]   datawindow   dw_1   
  // 说明:   
  // 参数2:[value]   string   col   
  // 说明:对象名   
  // 参数3:[value]   integer   row   
  // 说明:行   
  //--------------------------------------------------------------------   
  //   返回: (STRING)   值   
  //--------------------------------------------------------------------   
  //   作者: cwl 日期:   2002.03.18   
  //====================================================================   
  string   ls_edittype,ls_value,ls_format   
  integer   id   
  ls_edittype=lower(dw_1.Describe(col+".Edit.Style"))//得到编缉风格   
  choose   case   ls_edittype   
  case   'ddlb','dddw'//应该得到显示值   
  ls_value=dw_1.describe(   "Evaluate('LookUpDisplay("+col+")   ',"+string(row)+"   )")   
  case   else   
  id=long(dw_1.Describe(col+".id"))   
  ls_format=dw_1.Describe(col+".Format")   
  if   mid(ls_format,1,1)='['   or   ls_format='?'   or   ls_format=''   then   //不作格式处理   
  if   id=0   then   //计算列   
  ls_value=dw_1.Describe("Evaluate(~""   +   dw_1.Describe(col   +   '.expression')&   
  +   "~","+string(row)+")")   
  else   
  ls_value=string(dw_1.object.data[row,id])   
  end   if     
  else   
  if   id=0   then   //计算列   
  ls_value=string(dw_1.Describe("Evaluate('"   +   dw_1.Describe(col   +   '.expression')&   
  +   "',"+string(row)+")"),ls_format)   
  else   
  ls_value=string(dw_1.object.data[row,id],ls_format)   
  end   if     
  end   if   
  end   choose   
  if   isnull(ls_value)   then   ls_value=''   
  return   ls_value
           

注释 

全面控制 Excel

首先创建 Excel 对象,使用ComObj: 
 var ExcelID: Variant; 
 
 ExcelID := CreateOleObject( 'Excel.Application' ); 
 
 1) 显示当前窗口: 
 ExcelID.Visible := True; 
 
 2) 更改 Excel 标题栏: 
 ExcelID.Caption := '应用程序调用 Microsoft Excel'; 
 
 3) 添加新工作簿: 
 ExcelID.WorkBooks.Add; 
 
 4) 打开已存在的工作簿: 
 ExcelID.WorkBooks.Open( 'C:/Excel/Demo.xls' ); 
 
 5) 设置第2个工作表为活动工作表: 
 ExcelID.WorkSheets[2].Activate; 
 或 
 ExcelID.WorksSheets[ 'Sheet2' ].Activate; 
 
 6) 给单元格赋值: 
 ExcelID.Cells[1,4].Value := '第一行第四列'; 
 
 7) 设置指定列的宽度(单位:字符个数),以第一列为例: 
 ExcelID.ActiveSheet.Columns[1].ColumnsWidth := 5; 
 
 8) 设置指定行的高度(单位:磅)(1磅=0.035厘米),以第二行为例: 
 ExcelID.ActiveSheet.Rows[2].RowHeight := 1/0.035; // 1厘米 
 
 9) 在第8行之前插入分页符: 
 ExcelID.WorkSheets[1].Rows[8].PageBreak := 1; 
 
 10) 在第8列之前删除分页符: 
 ExcelID.ActiveSheet.Columns[4].PageBreak := 0; 
 
 11) 指定边框线宽度: 
 ExcelID.ActiveSheet.Range[ 'B3:D4' ].Borders[2].Weight := 3; 
 
 1-左 2-右 3-顶 4-底 5-斜( / ) 6-斜( / ) 
 
 12) 清除第一行第四列单元格公式: 
 ExcelID.ActiveSheet.Cells[1,4].ClearContents; 
 
 13) 设置第一行字体属性: 
 ExcelID.ActiveSheet.Rows[1].Font.Name := '隶书'; 
 ExcelID.ActiveSheet.Rows[1].Font.Color := clBlue; 
 ExcelID.ActiveSheet.Rows[1].Font.Bold := True; 
 ExcelID.ActiveSheet.Rows[1].Font.UnderLine := True; 
 
 14) 进行页面设置: 
 
 a.页眉: 
 ExcelID.ActiveSheet.PageSetup.CenterHeader := '报表演示'; 
 b.页脚: 
 ExcelID.ActiveSheet.PageSetup.CenterFooter := '第&P页'; 
 c.页眉到顶端边距2cm: 
 ExcelID.ActiveSheet.PageSetup.HeaderMargin := 2/0.035; 
 d.页脚到底端边距3cm: 
 ExcelID.ActiveSheet.PageSetup.HeaderMargin := 3/0.035; 
 e.顶边距2cm: 
 ExcelID.ActiveSheet.PageSetup.TopMargin := 2/0.035; 
 f.底边距2cm: 
 ExcelID.ActiveSheet.PageSetup.BottomMargin := 2/0.035; 
 g.左边距2cm: 
 ExcelID.ActiveSheet.PageSetup.LeftMargin := 2/0.035; 
 h.右边距2cm: 
 ExcelID.ActiveSheet.PageSetup.RightMargin := 2/0.035; 
 i.页面水平居中: 
 ExcelID.ActiveSheet.PageSetup.CenterHorizontally := 2/0.035; 
 j.页面垂直居中: 
 ExcelID.ActiveSheet.PageSetup.CenterVertically := 2/0.035; 
 k.打印单元格网线: 
 ExcelID.ActiveSheet.PageSetup.PrintGridLines := True; 
 
 15) 拷贝操作: 
 
 a.拷贝整个工作表: 
 ExcelID.ActiveSheet.Used.Range.Copy; 
 b.拷贝指定区域: 
 ExcelID.ActiveSheet.Range[ 'A1:E2' ].Copy; 
 c.从A1位置开始粘贴: 
 ExcelID.ActiveSheet.Range.[ 'A1' ].PasteSpecial; 
 d.从文件尾部开始粘贴: 
 ExcelID.ActiveSheet.Range.PasteSpecial; 
 
 16) 插入一行或一列: 
 
 a. ExcelID.ActiveSheet.Rows[2].Insert; 
 b. ExcelID.ActiveSheet.Columns[1].Insert; 
 
 
 17) 删除一行或一列: 
 
 a. ExcelID.ActiveSheet.Rows[2].Delete; 
 b. ExcelID.ActiveSheet.Columns[1].Delete; 
 
 18) 打印预览工作表: 
 ExcelID.ActiveSheet.PrintPreview; 
 
 19) 打印输出工作表: 
 ExcelID.ActiveSheet.PrintOut; 
 
 20) 工作表保存: 
 if not ExcelID.ActiveWorkBook.Saved then 
 ExcelID.ActiveSheet.PrintPreview; 
 
 21) 工作表另存为: 
 ExcelID.SaveAs( 'C:/Excel/Demo1.xls' ); 
 
 22) 放弃存盘: 
 ExcelID.ActiveWorkBook.Saved := True; 
 
 23) 关闭工作簿: 
 ExcelID.WorkBooks.Close; 
 
 24) 退出 Excel: 
 ExcelID.Quit;
           

继续阅读