dataset中数据导到EXCEL模板中,但单元格[col,row]右边的单元格不为[col+1,row]时,如何处理?我的过程大致如下,现在的问题也就是操作excel的问题,当excel中出现了单元格合并的情况时,此时C6右边的单元格不为D6,可能为E6或F6。
如何求一个单元格右边的单元格和下边的个单元格的row跟col?    ExcelObj:=GetActiveOLEObject('Excel.application');
   wb  :=  ExcelObj.WorkBooks.Open(aBookFile)  ;
    wss := wb.WorkSheets ;
   ws := wb.WorkSheets[aSheetName]  ;
   ws.Activate; 
  .....//根据据起始位置 导出dataset中的数据到excel
  row := rowbegin ;
   col := colBegin ;
   aDataSet.First ;
   while not aDataSet.Eof do
    begin
      col := colbegin ;      for i:=0 to aDataSet.Fields.Count-1 do
      begin
        if aDataSet.Fields[i].Visible Then
        begin
           ws.Cells[row,col].value:=aDataSet.Fields[i].AsString;
           inc(col);
        end;
      end;
      row:=row + 1;
      aDataSet.Next;
    end;  

解决方案 »

  1.   

    特殊问题只能特殊处理。
    换个角度处理如何:先规范导出,然后插入一列 ExcelApp.ActiveSheet.Columns[1].Insert;或者判断到指定列时,跳跃。
      

  2.   

    嗯,报表模板是定好的,只有用第二种了。
    我用的一个数组专门来记录各列的标号,如('B','E'..'X')
    再写个函数得到跳跃值。 导数据的时候根据上面的数组 得到 每列的跳跃数,找到下一次该填值的地方。可以比较简单通用的解决问题了:)还是想知道"如何求一个单元格右边的单元格和下边的个单元格的row跟col?"!
      

  3.   

    //求各字符与第一字符间的间隔 ,如输入('B','E','aF') ,返回结果(3,30)
             //字符串中ArrChar的元素为一位或两位,够做26*26列的表格了^_^
             //ArrChar :各列在Excel上对应的标题字母,如
             //   excel模板中各列定位:线路(设备)缺陷(故障)月报表 --故障报表
                    //const OverColNumArray_8610_AccMonthStat : array[0..36] of string =
                    //( 'B','C','D','F','G','I','K','M','O','Q','R',
                   // 'S','T','U','V','W','X','Y','AB','AC','AD','AE',
                   // 'AF','AG','AH','AI','AJ','AK','AL','AM','AN',
                   // 'AO','AP','AQ','AR','AS', 'AT') ;
        // ArrInt :其他列与第一列的差值数组
        procedure GetCharArraySep(ArrChar :array of string  ; var ArrInt:array of integer  ) ;
    procedure GetCharArraySep(ArrChar: array of string;
      var ArrInt: array of integer);var
      CharLength : integer ;
      StringLength : integer ;
      i : integer ;
      IntLength : integer ;  function GetOrdValueFromString(p_S: string) : integer ;******
    调用如下:...............
      //=============================================//
       //    将第二个表格:异常故障月报 的数据导到Excel中             //
       //==============================================//   setlength(TabArrInt_Acc,length(OverColNumArray_8610_AccMonthStat)-1) ;
       GetCharArraySep(
                OverColNumArray_8610_AccMonthStat,
                TabArrInt_Acc
                ) ;
        row := Row_8610_2 ;
        col := Col_8610_2 ;
        DBGrid2.DataSource.DataSet.First ;
        while not DBGrid2.DataSource.DataSet.Eof do
         begin
           col := Col_8610_2 ;       for i:=0 to DBGrid2.DataSource.DataSet.Fields.Count-1 do
           begin
             if DBGrid2.DataSource.DataSet.Fields[i].Visible Then
             begin
                ws.Cells.Item[row,col].value:=
                    DBGrid2.DataSource.DataSet.Fields[i].AsString;
                col := Col_8610_2 + TabArrInt_Acc[i]   ;
             end;
           end;
           row:=row + 1;
           DBGrid2.DataSource.DataSet.Next;
         end;
        Screen.Cursor:= crDefault ;end;
      var
        tempstr : string ;
        UppStr : char ;//高位字符串
        LowStr : char ;// 低位字符串
        ResultInt : integer ;
      begin
        tempstr := UPPERCASE(trim(p_S)) ;    if length(tempstr) = 1 then
            ResultInt :=  ord(tempstr[1])
        else if length(trim(p_S)) = 2 then
        begin
          UppStr := tempstr[1] ;
          LowStr := tempstr[2] ;      ResultInt :=  (ord(UppStr)-ord('A')+1)*26 + ord(LowStr) ;
        end ;    result := ResultInt;
      end ;
    begin
        IntLength := length(ArrChar) ;
            //跳跃数组长度=标号数组长度-1
        //setlength(ArrChar, IntLength-1) ;    for i := 0 to (IntLength - 2) do
        begin
                //字符串长度
            ArrInt[i] := GetOrdValueFromString(ArrChar[i+1])
                         - GetOrdValueFromString(ArrChar[0]) ;
        end ;
    end;
      

  4.   

    上面粘错了,不好意思,再粘一遍。
    //求各字符与第一字符间的间隔 ,如输入('B','E','aF') ,返回结果(3,30)
             //字符串中ArrChar的元素为一位或两位,够做26*26列的表格了^_^
             //ArrChar :各列在Excel上对应的标题字母,如
             //excel模板中各列定位,为一数组:线路(设备)缺陷(故障)月报表 --故障报表,例如:const OverColNumArray_8610_AccMonthStat ...   
        // ArrInt :其他列与第一列的差值数组
        procedure GetCharArraySep(ArrChar :array of string  ; var ArrInt:array of integer  ) ;var
      CharLength : integer ;
      StringLength : integer ;
      i : integer ;
      IntLength : integer ;  function GetOrdValueFromString(p_S: string) : integer ;
      var
        tempstr : string ;
        UppStr : char ;//高位字符串
        LowStr : char ;// 低位字符串
        ResultInt : integer ;
      begin
        tempstr := UPPERCASE(trim(p_S)) ;    if length(tempstr) = 1 then
            ResultInt :=  ord(tempstr[1])
        else if length(trim(p_S)) = 2 then
        begin
          UppStr := tempstr[1] ;
          LowStr := tempstr[2] ;      ResultInt :=  (ord(UppStr)-ord('A')+1)*26 + ord(LowStr) ;
        end ;    result := ResultInt;
      end ;
    begin
        IntLength := length(ArrChar) ;
            //跳跃数组长度=标号数组长度-1
        //setlength(ArrChar, IntLength-1) ;    for i := 0 to (IntLength - 2) do
        begin
                //字符串长度
            ArrInt[i] := GetOrdValueFromString(ArrChar[i+1])
                         - GetOrdValueFromString(ArrChar[0]) ;
        end ;
    end;
    //函数定义结束
    ********************************************************************调用如下:
    var
       temp_filename : string ;    //文件名
       temp_SheetName : string ;   //表单名
       temp_FullFileName : string  ; //全文件名   ExcelObj ,  wb  ,wss, ws  :olevariant ;
       SaveDialog1: TSaveDialog;
       row ,col ,i :integer ;
       AppPath : string ;   Attributes, NewAttributes: Word;   TabArrInt_Bug : array of integer ;//跳跃长度数组 :缺陷
       TabArrInt_Acc : array of integer ;//跳跃长度数组 :故障
    begin
        AppPath := ExtractFileDir(Application.ExeName) ;    temp_filename := FileName_8610 ;
        temp_SheetName := SheetName_8610 ;
        temp_FullFileName := AppPath +'\ExcelModel\'+ temp_filename ;
         //判断文件是否存在
      if FileExists(temp_FullFileName) then
      begin
       ;
      end
      else
            //将文件设为只读
      begin
        attributes := filegetattr(temp_FullFileName) ;
        NewAttributes :=  ( NewAttributes or SysUtils.faReadOnly)  ;
        filesetattr(temp_FullFileName ,NewAttributes) ;
      end ;  //启动Excel
       try
         ExcelObj:=GetActiveOLEObject('Excel.application')
      except
        try
          ExcelObj:=CreateOLEObject('Excel.application')
        except
          ShowMessage('请您先安装Excel 2000,才能使用数据导出为Excel功能!');
          abort ;    end;
      end;  ExcelObj.Visible := True ;    //****************************************************
         //****************************************************
       if FileExists(temp_FullFileName) then
       begin
        wb  :=  ExcelObj.WorkBooks.Open(temp_FullFileName)  ;
        wss := wb.WorkSheets ;
        ws := wb.WorkSheets[temp_SheetName]  ;
        ws.Activate;
        end   ;   //=============================================//
       //    将第一个表格:缺陷月报 的数据导到Excel中             //
       //==============================================//   setlength(TabArrInt_Bug,length(OverColNumArray_8610_BugMonthStat)-1) ;
       GetCharArraySep(
                OverColNumArray_8610_BugMonthStat,
                TabArrInt_Bug
                ) ;
        row := Row_8610_1 ;
        col := Col_8610_1 ;
        DBGrid1.DataSource.DataSet.First ;
        while not DBGrid1.DataSource.DataSet.Eof do
         begin
           col := Col_8610_1 ;       for i:=0 to DBGrid1.DataSource.DataSet.Fields.Count-1 do
           begin
             if DBGrid1.DataSource.DataSet.Fields[i].Visible Then
             begin
                ws.Cells.Item[row,col].value:=
                    DBGrid1.DataSource.DataSet.Fields[i].AsString;
                col := Col_8610_1 + TabArrInt_Bug[i] ;
             end;
           end;
           row:=row + 1;
           DBGrid1.DataSource.DataSet.Next;
         end;
      

  5.   

    自己搞定的自己来领分,再粘个东^_^
    //********************************************//
    //********功能说明:分解字符串为子字符串,各子字符串之间用分隔符分开隔开*****//
    //********注意事项:字符串中不要含空格,分隔符不要用空格***********
    //********************************************//
    //基本思路:主要利用pos函数,动态数组 ,你查查帮助看它的用法
         //字符串例:edit1|edit2|edit3
         //首先设定动态数组的长度:即有多少个元素
         // 利出pos取出第一个|,即1后面的|,然后将它替换为空格' '  ,保留其在字符串位置,
         //取下一个字符串元素时要用到,即我现在得到1后面的'|',保留其字符串中的位置 (从左往右数,是第6个),
         //因为我们取下一个字符串元素需要此位置.   如下一个字符串是edit2,要取他的话,就是从6开始取到12,所以要保留十二。
         //依此类推吧
           //procedure GetArrayFromStr(aStr :string ; aSepStr:string;var aArray :TJCCArray ) ;
    var
      Len ,i ,index ,aLen:integer  ;
      tempResult : string ;
      ReplaceStr :string ;
    begin
      //首先得到动态数组的长度
      ReplaceStr := aStr   ;
      alen := 1 ;
      while pos(aSepStr, ReplaceStr)>0 do
      begin
        ReplaceStr[pos(aSepStr, ReplaceStr)] := ' ' ;
        inc(aLen) ;
      end  ;
      system.setLength(aArray, aLen) ;  Len := length(aStr ) ;
      tempResult := '' ;
      ReplaceStr := aStr ;
      index := 1 ;  i := 0 ;
      while pos(aSepStr, ReplaceStr)>0 do
      begin
        tempResult := copy( ReplaceStr ,index , pos(aSepStr, ReplaceStr)-index) ;
        index := pos(aSepStr, ReplaceStr) ;     ReplaceStr[pos(aSepStr, ReplaceStr)] := ' ' ;
         aArray[i] := tempResult ;
         inc( i) ;
      end ;
      tempResult := copy(ReplaceStr ,index , length(ReplaceStr)-1);
     //   showmessage(tempresult);
         aArray[i] := tempResult ;end ;