51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 4610|回复: 4
打印 上一主题 下一主题

[原创] 参数化Excel单元格

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2010-5-18 17:52:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
首先声明,这不是一种适用于所有情况的普遍办法,只适用于定长的Excel和单元格,并且要参数化的单元格不多,参数化的值中也不能包含中文。
问题的缘起是一个Excel的导入功能:在导入Excel后,会刷出一个记录列表的页面,在这里选择刚才导入的那条记录,进行后续处理。为了在记录列表页面让所有Vuser选到自己的记录,需要使用这里的查询功能,而查询条件里能做为唯一标志的两个字段,一个是自动生成的,另一个在Excel里填写,它们都不能在这之前通过关联获得,它们都是在记录列表这个页面返回的。姑不论这样的程序设计是否合理,这里仅就Excel单元格的参数化问题进行探讨。
为了得到唯一的查询条件,只能通过参数化Excel表中的那个单元格来实现(姑且把它叫做 编号),除非你愿意手工生成N多Excel,并且这些Excel中的编号都不同。
我经常用的方法是使用时间参数来做唯一标志,这里也用这个参数来填充 编号 这个单元格,为了唯一标志每个Vuser使用的Excel文件,也用这个参数命名Excel文件。
以前常用的格式为 %Y-%m-%d %H:%M:%S.000,因为冒号不能作为文件名,所以这次改为 %Y-%m-%d %H.%M.%S.000,即如 2010-05-18 13.33.42.456。
用UltraEdit打开这个Excel文件,找到相应位置,如下图:

我们要参数化的就是这个时间,2010的2对应的位置是174aH,脚本实现如下,说明请看注释:

char wfilename[256];  //定义全局变量,以便在导入Excel文件后删除该文件
Action()
{

//生成Excel文件,使Excel中 编号 带时间信息
{
char * rfilename = "D:\\批量导入2010-05-18 13.33.42.456.xls";
long file_stream,file;
char * buffer,* p;
int count,i;
char * time=lr_eval_string("{时间}"); //将{时间}参数格式设为 %Y-%m-%d %H.%M.%S.000

buffer = (char *)malloc(512000*1);

//下三句生成新Excel文件名
strcpy(wfilename,"D:\\批量导入");
strcat(wfilename,time);
strcat(wfilename,".xls");

if ((file_stream = fopen(rfilename, "rb")) == NULL ) {  //只能以二进制方式打开Excel文件,.csv和.txt等文本文件都不支持多工作表的Excel文件
  lr_error_message ("Cannot open %s", rfilename);
  return -1;
}

count = fread(buffer, 1, 512000, file_stream);

p=buffer+0x174a; //到Excel单元格中时间字符串开始的位置,以做下面的替换
for (i=0;i<strlen(time);i++) {
     *(p+i)=*(time+i);
}
//不能使用字符串函数如strcpy()、strcat()等进行处理,因为Excel文件中一开始就有很多字符串的结束标志符\0

if ((file = fopen(wfilename, "wb")) == NULL) {
  lr_output_message ("Unable to create %s", wfilename);
  return -1;
}

fwrite(buffer, 1, count, file);

fclose(file);
}

/*导入Excel*/
……

web_submit_data("导入Excel",
  "Action=http://……",
  "Method=POST",
  "EncType=multipart/form-data",
  "RecContentType=text/html",
  "Referer=http://……",
  "Snapshot=t261.inf",
  "Mode=HTTP",
  ITEMDATA,
  ……
  "Name=file", "Value=D:\\\\批量导入{时间}.xls", "File=Yes", ENDITEM,
  LAST);

……

//导入完成后,删除上面新生成的Excel文件
remove(wfilename);

/*查询*/

//从查询结果中取关联数据,为后续处理用
web_reg_save_param(……);

web_submit_data("条件查询",
  "Action=http://……",
  "Method=POST",
  "Referer=http://……",
  "Snapshot=t284.inf",
  "Mode=HTTP",
  ITEMDATA,
  ……
  "Name=number", "Value={时间}", ENDITEM,
  ……
  LAST);

/*后续处理*/

return 0;
}

也许有人会问,为什么不在脚本中搜索时间串对应的位置,而要用UltraEdit来找呢,因为Excel二进制流无法使用字符串函数来搜索(有很多\0),只能逐字符搜索,效率很低。

如果单元格中有中文,情况有些不一样。例如我们将编号值填为 编号2010-05-18 13.33.42.456,用UltraEdit打开该文件,可能找不到时间串,但是反复修改后又可能找得到(这是不确定的!汗,我也不知道为什么。简单地,多加1个英文字符一般能够找到)。找到的情况不太一样,如下图:

时间串的每个字符间多了个不可见字符00H,在脚本中只需修改2处:
p=buffer+0x174a; 改为 p=buffer+0x180c;
*(p+i)=*(time+i); 改为 *(p+i*2)=*(time+i);

以上方法适用范围很窄,相当于将原文件作为一个模板,复制出一堆大同小异的Excel文件。无法用中文作为参数值,也无法处理变长的Excel和单元格。请同好高人指教。(Dll的方法应该具有更强的处理能力和普适性,但也没有现成的东东,要自己去写。或者还有其他的什么办法?)

附上脚本和Excel原文件:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?(注-册)加入51Testing

x
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

该用户从未签到

2#
发表于 2010-5-18 21:20:14 | 只看该作者
C语言操作Excel好像有个CSpreadSheet.h头文件可以用
回复 支持 反对

使用道具 举报

该用户从未签到

3#
发表于 2013-11-13 22:02:30 | 只看该作者
回复 1# 婴儿


    学习下
回复 支持 反对

使用道具 举报

该用户从未签到

4#
发表于 2013-11-13 22:02:33 | 只看该作者
回复 1# 婴儿


    学习下
回复 支持 反对

使用道具 举报

该用户从未签到

5#
发表于 2013-11-13 22:03:57 | 只看该作者
学习下
回复 支持 反对

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-5-6 06:19 , Processed in 0.079691 second(s), 28 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表