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;
如何求一个单元格右边的单元格和下边的个单元格的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;
换个角度处理如何:先规范导出,然后插入一列 ExcelApp.ActiveSheet.Columns[1].Insert;或者判断到指定列时,跳跃。
我用的一个数组专门来记录各列的标号,如('B','E'..'X')
再写个函数得到跳跃值。 导数据的时候根据上面的数组 得到 每列的跳跃数,找到下一次该填值的地方。可以比较简单通用的解决问题了:)还是想知道"如何求一个单元格右边的单元格和下边的个单元格的row跟col?"!
//字符串中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;
//求各字符与第一字符间的间隔 ,如输入('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;
//********************************************//
//********功能说明:分解字符串为子字符串,各子字符串之间用分隔符分开隔开*****//
//********注意事项:字符串中不要含空格,分隔符不要用空格***********
//********************************************//
//基本思路:主要利用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 ;