【dataset中数据导到EXCEL模板中,但单元格[col,row]右边的单元格不为[col+1,row]时,如何处理?】

JCC0128 2003-10-16 10:23:42
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;
...全文
112 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
JCC0128 2003-10-16
  • 打赏
  • 举报
回复
嗯,报表模板是定好的,只有用第二种了。
我用的一个数组专门来记录各列的标号,如('B','E'..'X')
再写个函数得到跳跃值。

导数据的时候根据上面的数组 得到 每列的跳跃数,找到下一次该填值的地方。

可以比较简单通用的解决问题了:)

还是想知道"如何求一个单元格右边的单元格和下边的个单元格的row跟col?"!
空中居士 2003-10-16
  • 打赏
  • 举报
回复
特殊问题只能特殊处理。
换个角度处理如何:

先规范导出,然后插入一列 ExcelApp.ActiveSheet.Columns[1].Insert;

或者判断到指定列时,跳跃。
JCC0128 2003-10-16
  • 打赏
  • 举报
回复
分少了点,给分时没注意,不够再补!!!!
RockYuan 2003-10-16
  • 打赏
  • 举报
回复
自己搞定的自己来领分,再粘个东^_^


//********************************************//
//********功能说明:分解字符串为子字符串,各子字符串之间用分隔符分开隔开*****//
//********注意事项:字符串中不要含空格,分隔符不要用空格***********
//********************************************//
//基本思路:主要利用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 ;
JCC0128 2003-10-16
  • 打赏
  • 举报
回复
上面粘错了,不好意思,再粘一遍。


//求各字符与第一字符间的间隔 ,如输入('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;
JCC0128 2003-10-16
  • 打赏
  • 举报
回复
//求各字符与第一字符间的间隔 ,如输入('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;

5,379

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧