Snail's Home_首页_软件测试专业网站:51Testing软件测试网 - powered by X-Space

日历

« 2008-05-18  
    123
45678910
11121314151617
18192021222324
25262728293031

最新来客

统计信息

  • 访问量: 2046
  • 日志数: 23
  • 图片数: 1
  • 文件数: 1
  • 建立时间: 2007-05-07
  • 更新时间: 2008-04-16

RSS订阅

我的最新日志

  • 用INNER JOIN语法联接多个表建记录集

    2008-4-16

    多表联接建立记录集是十分有用的,因为某些情况下,我们需要把数字数据类型显示为相应的文本名称,这就遇到了多表联接建立记录集的问题。比如作一个会员注册系统,共有五个表,会员信息数据表member、会员身份表MemberIdentity、会员权限表MemberLevel、会员类别表MemberSort和会员婚姻状况表Wedlock。如果想把会员注册信息全部显示出来,肯定要将这四个表连起来,否则大家看到的某些会员信息可能只是数据编号。
        以会员类别表来说,在其数据表中,1代表普通会员,2代表高级会员,3代表终身会员,在显示时,如果不将会员类别表与会员详细数据表相关联,那么假如我们现在看到的是一名普通会员的注册信息,我们只能看到其类别为1,而谁又会知道1代表的是普通会员呢?所以要将会员类别表与会员详细数据表相关联,关联后,1就显示为普通会员,2就显示为高级会员,3就显示为终身会员,这样多好?同理,其它两个表也要与会员详细数据表相关联才能把数据编号显示为相应的名称。
       
        前天制作网站后台时遇到此问题,在面包论坛、狂迷俱乐部、蓝色理想、和5D多媒体论坛发了贴子求救,都没有获得答案,只好自己研究,花了两天时间终于成功,现将其写成教程供大家分享,希望大家少走弯路。
        本教程是把五个表联在一起,如果愿意,您可以将更多的表联在一起,方法大同小异啦~
       
        步骤一:用Access软件建立一个名为Member的数据库,在其中建五个表,分别为:会员信息数据表member、会员身份表MemberIdentity、会员权限表MemberLevel、会员类别表MemberSort和会员婚姻状况表Wedlock。
       
        ●会员信息数据表member:
        MemberID:自动编号,主键(ID号)
        MemberSort:数字(会员类别)
        MemberName:文本,会员姓名
        Password:文本(会员密码)
        MemberLevel:数字(会员权限)
        MemberIdentity:数字(会员身份)
        Wedlock:数字(婚姻状况)
        MemberQQ:文本(QQ号码)
        MemberEmail:文本(会员邮箱)
        MemberDate:日期/时间(会员注册日期)
       
        ●会员身份表MemberIdentity:
        MemberIdentity:自动编号,主键(ID号)
        IdentityName:文本(会员身份名称)
       
        ●会员权限表MemberLevel:
        MemberLevel:自动编号,主键(ID号)
        LevelName:文本(会员权限名称)
       
        ●会员类别表MemberSort:
        MemberSort:自动编号,主键(ID号)
        SortName:文本(会员类别名称)
       
        ●会员婚姻状况表Wedlock
        Wedlock:自动编号,主键(ID号)
        WedlockName:文本(会员婚姻状况类别)
        说明:五个表建好后,您可以自行设置您想要的类别,如会员权限,您可以设置两个类别--“未付费会员”和“已付费会员”,编号分别为“1”、“2”,如您设置了三个选项,那么第三个选项的编号当然就是“3”了。
        下面我们所要作的工作就是把“1”、“2”之类的编号显示为“未付费会员”和“已付费会员”,否则,大家谁会知道“1”代表的是“未付费会员”,“2”代表的是“已付费会员”?
       
        步骤二:建DSN数据源,建记录集
        ●运行Dreamweaver MX软件,在会员注册信息显示页面建一个名为ConnMember(您也可以起其它的名称)的DSN数据源。
       
        ●点击服务器行为面板中的“绑定”,建一个名为MemberShow的数据集,“连接”选择ConnMember,“表格”选择Member,“列”全选,“排序”选择MemberDate,降序。点击“高级”按钮,修改SQL框中自动生成的代码:
        原代码为:
        SELECT *
        FROM Member
        ORDER BY MemberDate DESC
       
        将代码修改为:
        SELECT *
        FROM (((Member INNER JOIN MemberSort ON Member.MemberSort=MemberSort.MemberSort) INNER JOIN MemberLevel ON Member.MemberLevel=MemberLevel.MemberLevel) INNER JOIN MemberIdentity ON Member.MemberIdentity=MemberIdentity.MemberIdentity) INNER JOIN Wedlock ON Member.Wedlock=Wedlock.Wedlock
        ORDER BY MemberDate DESC
        修改完代码后,点击“确定”,大功告成!
        现在,您可以打开记录集看一下,五个表中的字段全部集成在MemberShow记录集中,您只要将相应的字段绑定在该字段想显示的单元格中即可。这下好了,所有的数字编号全部变成了相应的名称,如会员权限,不再是“1”和“2”的数字形式了,而是变成了相应的名称“未付费会员”和“已付费会员”。其它的数字编号也变成了显示的文本名称,是不是很开心呢?
       
        注意事项:
        ●在输入字母过程中,一定要用英文半角标点符号,单词之间留一半角空格;
        ●在建立数据表时,如果一个表与多个表联接,那么这一个表中的字段必须是“数字”数据类型,而多个表中的相同字段必须是主键,而且是“自动编号”数据类型。否则,很难联接成功。
        ●代码嵌套快速方法:如,想连接五个表,则只要在连接四个表的代码上加一个前后括号(前括号加在FROM的后面,后括号加在代码的末尾即可),然后在后括号后面继续添加“INNER JOIN 表名X ON 表1.字段号=表X.字段号”代码即可,这样就可以无限联接数据表了:)
       
        语法格式:
        其实 INNER JOIN ……ON的语法格式可以概括为:
        FROM (((表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号) INNER JOIN 表4 ON Member.字段号=表4.字段号) INNER JOIN 表X ON Member.字段号=表X.字段号
        您只要套用该格式就可以了。
       
        现成格式范例:
        虽然我说得已经比较明白了,但为照顾初学者,我还是以本会员注册系统为例,提供一些现成的语法格式范例,大家只要修改其中的数据表名称和字段名称即可。
       
        连接两个数据表的用法:
        FROM Member INNER JOIN MemberSort ON Member.MemberSort=MemberSort.MemberSort
        语法格式可以概括为:
        FROM 表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号
       
        连接三个数据表的用法:
        FROM (Member INNER JOIN MemberSort ON Member.MemberSort=MemberSort.MemberSort) INNER JOIN MemberLevel ON Member.MemberLevel=MemberLevel.MemberLevel
        语法格式可以概括为:
        FROM (表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号
       
        连接四个数据表的用法:
        FROM ((Member INNER JOIN MemberSort ON Member.MemberSort=MemberSort.MemberSort) INNER JOIN MemberLevel ON Member.MemberLevel=MemberLevel.MemberLevel) INNER JOIN MemberIdentity ON Member.MemberIdentity=MemberIdentity.MemberIdentity
        语法格式可以概括为:
        FROM ((表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号) INNER JOIN 表4 ON Member.字段号=表4.字段号
       
        连接五个数据表的用法:
        FROM (((Member INNER JOIN MemberSort ON Member.MemberSort=MemberSort.MemberSort) INNER JOIN MemberLevel ON Member.MemberLevel=MemberLevel.MemberLevel) INNER JOIN MemberIdentity ON Member.MemberIdentity=MemberIdentity.MemberIdentity) INNER JOIN Wedlock ON Member.Wedlock=Wedlock.Wedlock
        语法格式可以概括为:
        FROM (((表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号) INNER JOIN 表4 ON Member.字段号=表4.字段号) INNER JOIN 表5 ON Member.字段号=表5.字段号
       
        连接六个数据表的用法:略,与上述联接方法类似,大家举一反三吧:)

  • SQL查询例子收集

    2008-4-16

      Select username,citytable.cityid
      FROM usertable,citytable
      Where usertable.cityid=citytable.cityid


      Select username,b.cityid
      FROM usertable a,citytable b
      Where a.cityid=b.cityid

      Select a.au_fname+a.au_lname
      FROM authors a,titleauthor ta
      (Select title_id,title
      FROM titles
      Where ytd_sales>10000
      ) AS t
      Where a.au_id=ta.au_id
      AND ta.title_id=t.title_id

  • 精妙SQL语句

    2008-4-05

    下列语句部分是Mssql语句,不可以在access中使用。

    SQL分类:
    DDL—数据定义语言(CREATE,ALTER,DROP,DECLARE)
    DML—数据操纵语言(SELECT,DELETE,UPDATE,INSERT)
    DCL—数据控制语言(GRANT,REVOKE,COMMIT,ROLLBACK)

    首先,简要介绍基础语句:
    1、说明:创建数据库
    CREATE DATABASE database-name
    2、说明:删除数据库
    drop database dbname
    3、说明:备份sql server
    --- 创建 备份数据的 device
    USE master
    EXEC sp_addumpdevice 'disk', 'testBack', 'c:\mssql7backup\MyNwind_1.dat'
    --- 开始 备份
    BACKUP DATABASE pubs TO testBack
    4、说明:创建新表
    create table tabname(col1 type1 [not null] [primary key],col2 type2 [not null],..)
    根据已有的表创建新表:
    A:create table tab_new like tab_old (使用旧表创建新表)
    B:create table tab_new as select col1,col2… from tab_old definition only
    5、说明:删除新表drop table tabname
    6、说明:增加一个列
    Alter table tabname add column col type
    注:列增加后将不能删除。DB2中列加上后数据类型也不能改变,唯一能改变的是增加varchar类型的长度。
    7、说明:添加主键: Alter table tabname add primary key(col)
    说明:删除主键: Alter table tabname drop primary key(col)
    8、说明:创建索引:create [unique] index idxname on tabname(col….)
    删除索引:drop index idxname
    注:索引是不可更改的,想更改必须删除重新建。
    9、说明:创建视图:create view viewname as select statement
    删除视图:drop view viewname
    10、说明:几个简单的基本的sql语句
    选择:select * from table1 where 范围
    插入:insert into table1(field1,field2) values(value1,value2)
    删除:delete from table1 where 范围
    更新:update table1 set field1=value1 where 范围
    查找:select * from table1 where field1 like ’%value1%’ ---like的语法很精妙,查资料!
    排序:select * from table1 order by field1,field2 [desc]
    总数:select count * as totalcount from table1
    求和:select sum(field1) as sumvalue from table1
    平均:select avg(field1) as avgvalue from table1
    最大:select max(field1) as maxvalue from table1
    最小:select min(field1) as minvalue from table1
    11、说明:几个高级查询运算词
    A: UNION 运算符
    UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重复行而派生出一个结果表。当 ALL 随 UNION 一起使用时(即 UNION ALL),不消除重复行。两种情况下,派生表的每一行不是来自 TABLE1 就是来自 TABLE2。
    B: EXCEPT 运算符
    EXCEPT 运算符通过包括所有在 TABLE1 中但不在 TABLE2 中的行并消除所有重复行而派生出一个结果表。当 ALL 随 EXCEPT 一起使用时 (EXCEPT ALL),不消除重复行。
    C: INTERSECT 运算符
    INTERSECT 运算符通过只包括 TABLE1 和 TABLE2 中都有的行并消除所有重复行而派生出一个结果表。当 ALL 随 INTERSECT 一起使用时 (INTERSECT ALL),不消除重复行。
    注:使用运算词的几个查询结果行必须是一致的。
    12、说明:使用外连接
    A、left outer join:
    左外连接(左连接):结果集几包括连接表的匹配行,也包括左连接表的所有行。
    SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c
    B:right outer join:
    右外连接(右连接):结果集既包括连接表的匹配连接行,也包括右连接表的所有行。
    C:full outer join:
    全外连接:不仅包括符号连接表的匹配行,还包括两个连接表中的所有记录。

    其次,大家来看一些不错的sql语句
    1、说明:复制表(只复制结构,源表名:a 新表名:b) (Access可用)
    法一:select * into b from a where 1<>1
    法二:select top 0 * into b from a

    2、说明:拷贝表(拷贝数据,源表名:a 目标表名:b) (Access可用)
    insert into b(a, b, c) select d,e,f from b;

    3、说明:跨数据库之间表的拷贝(具体数据使用绝对路径) (Access可用)
    insert into b(a, b, c) select d,e,f from b in ‘具体数据库’ where 条件
    例子:..from b in '"&Server.MapPath(".")&"\data.mdb" &"' where..

    4、说明:子查询(表名1:a 表名2:b)
    select a,b,c from a where a IN (select d from b ) 或者: select a,b,c from a where a IN (1,2,3)

    5、说明:显示文章、提交人和最后回复时间
    select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b

    6、说明:外连接查询(表名1:a 表名2:b)
    select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c

    7、说明:在线视图查询(表名1:a )
    select * from (SELECT a,b,c FROM a) T where t.a > 1;

    8、说明:between的用法,between限制查询数据范围时包括了边界值,not between不包括
    select * from table1 where time between time1 and time2
    select a,b,c, from table1 where a not between 数值1 and 数值2

    9、说明:in 的使用方法
    select * from table1 where a [not] in (‘值1’,’值2’,’值4’,’值6’)

    10、说明:两张关联表,删除主表中已经在副表中没有的信息
    delete from table1 where not exists ( select * from table2 where table1.field1=table2.field1 )

    11、说明:四表联查问题:
    select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where .....

    12、说明:日程安排提前五分钟提醒
    SQL: select * from 日程安排 where datediff('minute',f开始时间,getdate())>5

    13、说明:一条sql 语句搞定数据库分页
    select top 10 b.* from (select top 20 主键字段,排序字段 from 表名 order by 排序字段 desc) a,表名 b where b.主键字段 = a.主键字段 order by a.排序字段

    14、说明:前10条记录
    select top 10 * form table1 where 范围

    15、说明:选择在每一组b值相同的数据中对应的a最大的记录的所有信息(类似这样的用法可以用于论坛每月排行榜,每月热销产品分析,按科目成绩排名,等等.)
    select a,b,c from tablename ta where a=(select max(a) from tablename tb where tb.b=ta.b)

    16、说明:包括所有在 TableA 中但不在 TableB和TableC 中的行并消除所有重复行而派生出一个结果表
    (select a from tableA ) except (select a from tableB) except (select a from tableC)

    17、说明:随机取出10条数据
    select top 10 * from tablename order by newid()

    18、说明:随机选择记录
    select newid()

    19、说明:删除重复记录
    Delete from tablename where id not in (select max(id) from tablename group by col1,col2,...)

    20、说明:列出数据库里所有的表名
    select name from sysobjects where type='U'

    21、说明:列出表里的所有的
    select name from syscolumns where id=object_id('TableName')

    22、说明:列示type、vender、pcs字段,以type字段排列,case可以方便地实现多重选择,类似select 中的case。
    select type,sum(case vender when 'A' then pcs else 0 end),sum(case vender when 'C' then pcs else 0 end),sum(case vender when 'B' then pcs else 0 end) FROM tablename group by type
    显示结果:
    type vender pcs
    电脑 A 1
    电脑 A 1
    光盘 B 2
    光盘 A 2
    手机 B 3
    手机 C 3

    23、说明:初始化表table1
    TRUNCATE TABLE table1

    24、说明:选择从10到15的记录
    select top 5 * from (select top 15 * from table order by id asc) table_别名 order by id desc
      
    随机选择数据库记录的方法(使用Randomize函数,通过SQL语句实现)
      对存储在数据库中的数据来说,随机数特性能给出上面的效果,但它们可能太慢了些。你不能要求ASP“找个随机数”然后打印出来。实际上常见的解决方案是建立如下所示的循环:
    Randomize
    RNumber = Int(Rnd*499) +1
     
    While Not objRec.EOF
    If objRec("ID") = RNumber THEN
    ... 这里是执行脚本 ...
    end if
    objRec.MoveNext
    Wend
     
      这很容易理解。首先,你取出1到500范围之内的一个随机数(假设500就是数据库内记录的总数)。然后,你遍历每一记录来测试ID 的值、检查其是否匹配RNumber。满足条件的话就执行由THEN 关键字开始的那一块代码。假如你的RNumber 等于495,那么要循环一遍数据库花的时间可就长了。虽然500这个数字看起来大了些,但相比更为稳固的企业解决方案这还是个小型数据库了,后者通常在一个数据库内就包含了成千上万条记录。这时候不就死定了?
      采用SQL,你就可以很快地找出准确的记录并且打开一个只包含该记录的recordset,如下所示:
    Randomize
    RNumber = Int(Rnd*499) + 1
     
    SQL = "SELECT * FROM Customers WHERE ID = " & RNumber
     
    set ōbjRec = ObjConn.Execute(SQL)
    Response.WriteRNumber & " = " & objRec("ID") & " " & objRec("c_email")
     
      不必写出RNumber 和ID,你只需要检查匹配情况即可。只要你对以上代码的工作满意,你自可按需操作“随机”记录。Recordset没有包含其他内容,因此你很快就能找到你需要的记录这样就大大降低了处理时间。
    再谈随机数
      现在你下定决心要榨干Random 函数的最后一滴油,那么你可能会一次取出多条随机记录或者想采用一定随机范围内的记录。把上面的标准Random 示例扩展一下就可以用SQL应对上面两种情况了。
      为了取出几条随机选择的记录并存放在同一recordset内,你可以存储三个随机数,然后查询数据库获得匹配这些数字的记录:
    SQL = "SELECT * FROM Customers WHERE ID = " & RNumber & " OR ID = " & RNumber2 & " OR ID = " & RNumber3
     
      假如你想选出10条记录(也许是每次页面装载时的10条链接的列表),你可以用BETWEEN 或者数学等式选出第一条记录和适当数量的递增记录。这一操作可以通过好几种方式来完成,但是 SELECT 语句只显示一种可能(这里的ID 是自动生成的号码):
    SQL = "SELECT * FROM Customers WHERE ID BETWEEN " & RNumber & " AND " & RNumber & "+ 9"

      注意:以上代码的执行目的不是检查数据库内是否有9条并发记录。

     
    随机读取若干条记录,测试过
    Access语法:SELECT top 10 * From 表名 ORDER BY Rnd(id)
    Sql server:select top n * from 表名 order by newid()
    mysql:select * From 表名 Order By rand() Limit n
    Access左连接语法(最近开发要用左连接,Access帮助什么都没有,网上没有Access的SQL说明,只有自己测试, 现在记下以备后查)
    语法:select table1.fd1,table1,fd2,table2.fd2 From table1 left join table2 on table1.fd1,table2.fd1 where ...
    使用SQL语句 用...代替过长的字符串显示
    语法:
    SQL数据库:select case when len(field)>10 then left(field,10)+'...' else field end as news_name,news_id from tablename
    Access数据库:SELECT iif(len(field)>2,left(field,2)+'...',field) FROM tablename;
     
    Conn.Execute说明
    Execute方法
      该方法用于执行SQL语句。根据SQL语句执行后是否返回记录集,该方法的使用格式分为以下两种:
        1.执行SQL查询语句时,将返回查询得到的记录集。用法为:
        Set 对象变量名=连接对象.Execute("SQL 查询语言")
       Execute方法调用后,会自动创建记录集对象,并将查询结果存储在该记录对象中,通过Set方法,将记录集赋给指定的对象保存,以后对象变量就代表了该记录集对象。

        2.执行SQL的操作性语言时,没有记录集的返回。此时用法为:
        连接对象.Execute "SQL 操作性语句" [, RecordAffected][, Option]
          ·RecordAffected 为可选项,此出可放置一个变量,SQL语句执行后,所生效的记录数会自动保存到该变量中。通过访问该变量,就可知道SQL语句队多少条记录进行了操作。
          ·Option 可选项,该参数的取值通常为adCMDText,它用于告诉ADO,应该将Execute方法之后的第一个字符解释为命令文本。通过指定该参数,可使执行更高效。

    ·BeginTrans、RollbackTrans、CommitTrans方法
      这三个方法是连接对象提供的用于事务处理的方法。BeginTrans用于开始一个事物;RollbackTrans用于回滚事务;CommitTrans用于提交所有的事务处理结果,即确认事务的处理。
      事务处理可以将一组操作视为一个整体,只有全部语句都成功执行后,事务处理才算成功;若其中有一个语句执行失败,则整个处理就算失败,并恢复到处里前的状态。
      BeginTrans和CommitTrans用于标记事务的开始和结束,在这两个之间的语句,就是作为事务处理的语句。判断事务处理是否成功,可通过连接对象的Error集合来实现,若Error集合的成员个数不为0,则说明有错误发生,事务处理失败。Error集合中的每一个Error对象,代表一个错误信息。
  • 利用QTP自动化测试Flex 3应用程序

    2008-3-27

    利用QTP自动化测试Flex 3应用程序
     
    Adobe新出了Flex 3, 同时推出了用于Flex 3自动化测试的QTP plugin。本人也是刚刚入门Flex自动化测试,以下是一个简单的总结:

    软件需求:
    1. Flex Builder 3。 到这个地方
    https://www.adobe.com/cfusion/td ... us&product=flex (需要注册)下载 Adobe Flex Builder 3 Professional 或者Flex Builder 3 Professional Eclipse Plug-in (如果本机已有eclipse)。其中Flex Builder 3中已经包含QTP的plugin
    2. IE 6 或以上(目前只支持IE)
    3. Flash Player ActiveX control, version 9.0.28.0或以上,最新9.0.115.0 (检查C:\WINDOWS\system32\Macromed\Flash\FlashUtil9e.exe的属性可以查看当前安装flash的版本)
    4. QTP 9.1(不支持Smart Identification)或 QTP 9.2 和 patch 1701

    编译:
    必须用Flex Builder 3 编译Flex项目, 而不能仅仅用Flex 3 SDK编译,因为Flex Builder中带了一些的特殊的包
    1. 打开FB,右键选择你的Project -> Properties -> Flex Compiler
    2. 修改属性“Additional compiler arguments”,在该属性中添加如下代码:
    -include-libraries "flex_builder_dir\sdks\3.0.0\frameworks\libs\automation.swc" "flex_builder_dir\sdks\3.0.0\frameworks\libs\automation_agent.swc" "flex_builder_dir\sdks\3.0.0\frameworks\libs\qtp.swc" "flex_builder_dir\sdks\3.0.0\frameworks\libs\automation_dmv.swc"
    其中flex_builder_dir由Flex Builder的安装目录代替,windows平台的默认安装目录为 "C:\Program Files\Adobe\Flex Builder 3"
    3. 编译项目,然后发布应用到你的web server中
    4. 这时就为QA的自动化测试做好了准备

    QTP插件安装:
    1. 运行flex_builder_dir\Installers\QTP_Plugin_Installer.exe
    2. 验证plugin是否安装好:启动QTP,在Add-ins Manager窗口中出现Flex 3.0.0
    3. 这时QTP就可以识别Flex对象了

    更多更详细的信息都可以在adobe的官网上找到。
  • Install and Configure Flex Automated Testing

    2008-3-26

    Install and Configure Flex Automated Testing

    To use Flex Automated Testing, you must install Flex Builder 3 Professional. You cannot use Flex Automated Testing with only the Flex 3 SDK. If you do not have a Flex Builder Professional license, your test scrīpts are limited to 30 actions. If you exceed 30 actions in a test without the Professional license, you will receive a warning that your license is not present.

    Flex Automated Testing SWC files are installed by default with Flex Builder 3. They are located in the /frameworks/libs directory with the other SWC files. You can begin using Flex Automated Testing and build your own custom agents without any further installation.

    To use run-time automated testing (recommended):

    1. Open a command prompt.
    2. Navigate to the flex_builder_root/sdks/3.0.0/templates/automation-runtimeloading-files directory.
    3. Execute the build.bat file. This compiles the runtimeloading.mxml file into a SWF file.
    4. Copy the runtimeloading.swf and RunTimeLoading.html file to your web server. Copy the Flex application that you want to test to this server as well (the application need not be compiled with automation libraries).
    5. Request the RunTimeLoading.html file and pass your Flex application as the automationswfurl query string parameter; for example:
      http://localhost/RunTimeLoading.html?automationswfurl=MyApp.swf

    To compile your applications with static automation support:

    1. Start Flex Builder.
    2. Create a new Flex Project.
    3. Select your new Flex project in the Navigator.
    4. Select Project > Properties > Flex Compiler.
    5. In the "Additional compiler arguments" field, enter the following:
      -include-libraries "flex_builder_dir\sdks\3.0.0\frameworks\libs\automation.swc"
       "flex_builder_dir\sdks\3.0.0\frameworks\libs\automation_agent.swc"
       "flex_builder_dir\sdks\3.0.0\frameworks\libs\qtp.swc"
       "flex_builder_dir\sdks\3.0.0\frameworks\libs\automation_dmv.swc"

      The -include-libraries compiler option is relative to the Flex Builder installation directory; the default on Windows is "C:\Program Files\Adobe\Flex Builder 3\".

    6. Click the OK button to save your changes and OK to close the project Properties dialog box.
    7. Compile your Flex application.

      Examples and documentation for using custom agents can be found at Custom Agents.

    Flex 3 Plug-in for HP QuickTest Professional
    To use Flex Automated Testing with the Flex 3 Plug-in for HP QuickTest Professional (formerly Mercury QuickTest Pro), you must perform additional steps. The rest of this section describes how to install and use the Flex 3 Plug-in for HP QuickTest Professional.

    Requirements for Using the QTP Plug-in
    To test applications with Flex Automated Testing and the QTP agent, you must install the following:

    • Mercury QuickTest Professional 9.1 (no support for Smart Identification), available from Mercury
    • Mercury QuickTest Professional 9.2 and patch 1701 or later if you want Smart Identification support
    • Adobe Flex 3 Plug-in for Mercury QuickTest Pro
    • Microsoft Internet Explorer, version 6 or later
    • Flash Player ActiveX control, version 9.0.28.0 or higher

    Installing the Plug-in
    This section describes the steps necessary for a QC testing professional to configure QTP to work with Flex applications. You must install QTP and the plug-in.

    To install QTP:

    1. Install Flash Player 9 ActiveX control (9.0.28.0 or higher) for Microsoft Internet Explorer. This is currently the only supported browser/player.
    2. Install QTP 9.1 if you do not require support for Smart Identification. If you want to use Smart Identification, install QTP 9.2 and patch 1701. You must get QTP 9.1 from Mercury.
    3. If you are using Mercury QTP on Microsoft Windows Vista you need to turn off the User Account Control (UAC) feature. Instructions to turn off UAC are available here
    4. Restart your computer.

    To install the Flex 3 Plug-in for Mercury QuickTest Pro:

    1. Run the flex_builder_root/Installers/QTP_Plugin_Installer.exe.
    2. Start QTP.
    3. Close QTP.

    In addition to the plug-in's DLLs and XML files, the plug-in installer includes the following in the installation directory:

    • /demo — Contains a Flash movie that describes the basics of using the plug-in. Be sure to enable audio on your computer.
    • /Uninstall Adobe Flex 3 Plug-in for Mercury QuickTest Pro — Contains the uninstaller.

    Using the Plug-in

    1. Start QTP again after installing the plug-in. The Add-in Manager lists the Flex plug-in.
    2. Select the Flex plug-in in the Add-in Manager.
    3. Select New > Test and click the Record button.

    NOTE: Flex application testing with QTP currently supports only Microsoft Internet Explorer with the ActiveX Flash Player.

    For more information on these tasks and using QTP to test Flex applications, see Testing with QTP.

    For information on the operations and properties of Flex objects in QTP, see QTP Object Type Information.

    Samples for Automated Testing
    Sample custom agents are available at Custom Automation Agents.

    An application ready for testing with QTP can be found at Flexstore AT. This sample can be used to test if the QTP plugin installation was successful.

    An example for automating custom components can be found at Automating Custom Component.

    Using automation with the Adobe Flex Component Kit for Flash CS3
    You can create Flex controls, containers, skins, and other assets in Flash CS3 Professional, and then import those assets into your Flex application. When you want to automate an application that uses such assets, you must include the automation_flashflexkit.swc library.

    If you are using run-time loading, re-compile the runtimeloading.swf file by using the build.bat file in flex_builder_root\sdks\3.0.0\templates\automation-runtimeloading-files\. The batch file includes the necessary libraries.

    If you are compiling automation support into your application, add the automation_flashflexkit.swc to your include-libraries compiler option. This is in addition to the other automation SWC files. The SWC files are located in the flex_builder_root\sdks\3.0.0\frameworks\libs directory.

  • QTP 经常要用到的程序和函数:

    2008-3-23

    1. 创建一个vbs文件:TestVbs.vbs
    内容如下:
    '##################################################################################
    '##################################################################################
    Sub CloseWeb()

    '         此处可以用到描述性编程,把先期打开的IE窗口全关闭
    Dim WinIe,Ie,i,m
    Set WinIe=descrīption.Create()
    WinIe("regexpwndtitle").value=" Microsoft Internet Explorer"  '所有页面的regexpwndtitle属性值都是" Microsoft Internet Explorer",也可以用
    其他属性
    Set Ie=desktop.ChildObjects(WinIe)
    m=Ie.count
    For i=1 to m
            Ie(i-1).close                 ' 0为最后打开的一个,可关闭打开的几个,,循环改成for i=1 to m
    Next
    End Sub
    '##################################################################################



    function TestVbs(format)
            msgbox "参数是" & format
    end function


    '#################################################################
    '#################################################################
    '往文件里面写内容
    '第一个参数 文件的路径
    '第二个参数:写入的内容
    '第三个参数:写入的格式("Appending/Writing")
    ' See also "FileSystemObject"
    Sub Write2File(FilePath,content,style)
       Dim fso,f
       Dim stl
            If Ucase(style)="APPENDING" Then
                    stl=8
            else
                    if Ucase(style)="WRITING" then
                                    stl=2
                    else
                                            reporter.ReportEvent 1,"参数错误","Writing <" & FilePath &">:<"& content &">With<" & style & ">"
                                    Exit Sub
                    end if
            End If  
       Set fso=CreateObject("scrīpting.FileSystemObject")
       Set f=fso.OpenTextFile(FilePath,stl,true)
       'content="写入的第一行内容"
       f.WriteLine(content)
       f.Close
       Set f=nothing
       Set fso=nothing

    End Sub
    '#################################################################




    '#################################################################
    '#################################################################
    ' 连接
    数据库子程序
    ' 第一个参数:根据数据库的类型,设计连接字符串(参见udl文件)
    ' 第二个参数:连接数据库之后,进行查询的相应语句
    ' 第三个参数:查询记录返回到res
    Sub OpenDB(conn,sql,res)
       Set cnn=CreateObject("adodb.connection")
       cnn.open conn
       Set res=CreateObject("adodb.recordset")
       res.open
    sql,cnn,1,1
       
    End Sub
    '#################################################################




    '#################################################################
    '#################################################################
    ' 关闭数据库的连接
    sub CloseDB
       Set res=nothing
            Set cnn=nothing
    end sub
    '#################################################################

    2. QTP导入这个TestVbs.vbs 文件:
    菜单:Test-->Setting-->Resource
    在“Associated Library Files” 添加入该文件
    这里建议可以使用 相对路径,如..\TestVbs.vbs

    3.
    测试封装的子程序:
    用“Run from steps”运行模式(专家视图 右键,第四个菜单项,脚本从光标处运行)
    在QTP 中添加测试代码:

    CloseWeb()    '实现关闭当前所有的IE窗口
    stop


    ' 调用外部函数 Write2File
    Write2File "c:\File.txt","Writhing a Line","Writing"
    Write2File "c:\File.txt","Appending a Line","Appending"
    Write2File "c:\File.txt","Appending a Line","Appending!"   ' 参数不正确
    Write2File ".\vbs\File.txt","Appending a Line","Appending"
    stop


    '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ' 设置连接数据库所需要的初始值,包括:
    ' conn :数据库连接字符串
    ' sql:查询的SQL语句
    ' res:查询的返回记录

    Dim conn,sql,res
    conn="Provider=MSDASQL.1;Persist Security Info=False;Data Source=QT_Flight32"
    sql="select * from Orders"
    Set res=nothing

    ' 调用外部子程序 OpenDB 进行连接数据库
            OpenDB conn,sql,res
                    'msgbox res.RecordCount&"行," & res.fields.count & "列"
                    res.MoveFirst
               ' res.MoveNext    没有它的话,记录就成了死循环
              
                    'reporter.ReportEvent 2,"测试连接数据库","数据库获取数据:" & res.fields(0)

            RowCount=res.RecordCount
            ColumnCount=res.fields.count
            While not res.eof
                    Record=""
                    For i=0 to ColumnCount-1
                            Record=Record & ":" &res.fields(i)
                    Next
                            Record=mid(Record,2)
                            reporter.ReportEvent 2,"数据库记录:",Record
                    res.MoveNext
            Wend
      
    ' 调用外部子程序 CloseDB关闭数据库
            CloseDB
  • 手工编写QTP测试脚本

    2008-3-21

    在上一篇《管理QTP测试脚本的对象仓库》中,我们讨论了如何建立一个结构化的,易于维护的对象仓库系统。我们这样做不仅仅是为了维护方便,更重要的一点,当我们有了一套结构清楚的对象仓库以后,我们就可以轻松的手工编写QTP脚本了。
    这里可能有人会问,QTP的录制功能不是很强大么,为什么还要自己手写脚本,这样是不是更麻烦。我先说一下我对手写测试脚本的感受,供大家参考。首先,如果我们整理好对象仓库,再录制脚本,QTP就会又自动生成一批新的对象,命名很乱,再修改替换太费事;其次,录制脚本的过程如果出现问题,再重来,很麻烦;最后,也是最重要的,手写脚本时思路非常清楚,而且写完再运行,感觉非常好,呵呵。
    与编写脚本相比,脚本的维护工作同样很重要,而且维护脚本一般都是直接修改脚本,并不会去重新录制,所以开始的时候就用手写的方式,维护起来就会更轻松。
    编写QTP脚本其实是比较简单、快速的。我们首先创建一个Test,然后把所有相关对象仓库的tsr文件和vbs文件添加到这个Test里面,下面就可以开始写了。写脚本大致会遇到这么几种情况:
    1、调用vbs函数
    2、调用其他Test
    3、打开指定的URL
    4、操作页面Page上的控件
    5、添加CheckPoint
    6、其他逻辑运算
    我们分别讲一下。调用vbs函数比较简单,直接Call [函数名]。如果要调用其他的Test,那么首先点击Call to Existing Test,然后在QC中选择一个可以复用的Test,例如登录。如果登录的Test有参数,那么可以这样写:
    RunAction “Action1 [login]”, oneIteration , “张三”
    下面的脚本要操作对象仓库了。我们先写出“Browser(”,这时就会发现,对象仓库里面的Browser对象都列了出来,然后我们选择需要的那个B对象就好。我们先从打开指定URL的脚本开始讲,打开指定的URL使用的机会比较多,特别是在Test的开始。一般我们这样写
    Browser(”登录”).Navigate “指定的URL”
    这里的“登录”是一个Browser对象,一般我们要选业务上符合的B对象。写完这句以后要再写:
    Browser(”登录”).Page(”登录首页”).Sync
    这句的意思是等待“登录首页”这个Page加载完毕,注意不要用Wait几秒这种方式来等待页面加载结束。
    操作Page的对象是比较简单的,由于控件的类型太多,比如下拉菜单WebList、文本输入框WebEdit、按钮WebButton,这里就不一一说明了,大家看下面的一些例子吧:
    Browser(”购买直充”).Page(”购买直充”).WebList(”游戏区”).Select 1
    Browser(”购买直充”).Page(”购买直充”).WebEdit(”PlayerName”).Set “abc”
    Browser(”购买直充”).Page(”购买直充”).WebEdit(”PlayerNameAgain”).Set “abc”
    Browser(”购买直充”).Page(”购买直充”).WebEdit(”CheckCode”).Set “8888″
    Browser(”购买直充”).Page(”购买直充”).Image(”Submit”).Click
    如果遇到问题,不知道怎么写,可以先用录制的方式,生成一些脚本,然后仿照脚本写就可以了。另外在Page下面有可能会有Frame对象,这个没关系,就像这样写即可:
    Browser(”我的直充”).Page(”我的直充”).Frame(”直充入口”).Image(”立即直充”).Click
    添加CheckPoint要稍微复杂一些,比如说我们要检查Page上的一个WebElement的显示字符是否正确,那么首选要把这个WebElement完整的写在Test里面,这一句后面需要删除:
    Browser(”购买直充”).Page(”购买直充”).WebElement(”购买结果”).Click
    然后右击这一行脚本,选择Insert Standard CheckPoint,在弹出的CP属性窗口,设置CP的细节。确认后脚本就会自动生成一行:
    Browser(”购买直充”).Page(”购买直充”).WebElement(”购买结果”).Check CheckPoint(”购买结果”)
    最后再把上面那一行删除就可以了。
    其他的逻辑运算,例如循环、判断,请参考vbs脚本语法,这里不说了。
    总之,手动编写QTP脚本有很多好处,我在尝试了录制和手写两种方式之后,最终选择了手写的方式,大家不妨也试试,特别是对编码有兴趣的同学。
  • QTP测试flex制作的flash网站的方法

    2008-3-21

    现在Flex做的网站由于画面效果很好,现在很受欢迎,但是了解flash自动化测试的人寥寥无几,最近有项目是这方面的,研究了一番,略有成果,现总结如下:

    一.QTP自动化测试flex制作的flash系统需要插件, 插件安装方法如下:

    1. 到这个地方
    https://www.adobe.com/cfusion/td ... us&product=flex 其在flex automation for QTP,需要注册,很快的。

    2. 下载下的文件名为flexATWin.exe ,将后缀该为“.rar”文件

    3. 解压缩flexATWin.rar文件

    4. 检索“*.exe”文件

    5. 你会看见一个“Flex2_Plugins_QuickTestPro.exe”文件,这是一个独立的文件有37.5MB大,将它可以单独拷贝出来,其他的文件可以删除,这个就是flex 的QTP插件了

    6. 安装Flex2_Plugins_QuickTestPro.exe 文件,打开QTP9.2 发现


    7. OK,下面就靠大家研究如何适用flex了。

    二.仅仅安装好插件是不够的,还需要满足下面条件:

    环境:
    1.flex automation只能安装在QTP 9.1 及以上版本
    2.必须安装flex 2.0.1, 而且你的应用程序必须在flex 2.0.1下编译
    3.flex plugin for qtp 只支持 IE6及以上版本。
    4.必须安装flash player 9.0.28或以上版本
    5.JRE 1.4.2或以上版本

    三.确认是不是安装成功:

    1.检查注册表,如没发现有TEAPluginIE.dll和TEAPluginQTP.dll,则说明没有安装成功

    2.或者打开QTP==》tools==》object indentification==》Environment下拉框中是否有Flex2.0.1选项

    如果有表示安装成功。

    四.录制flex制作的flash系统,有些系统是不录制的。

    1.在系统编译的时候需要倒进来automation.swc, automation_agent.swc, and qtp.swc 这几个包文件文件,

    其中automation.swc默认就有,不需要重新导入

    automation_agent.swc, and qtp.swc 这两个是从你安装flex for qtp testing 插件的目录下面取出来的,有时候还需要automation_agent_rb.swc

    默认文件存放在C:\Program Files\Adobe\Flex Automation\frameworks下面的两个文件夹里面,将他们放到你系统对应的lib下面。

    如果你的系统用到了Flex的chart,那么还需要导入automation_charts.swc

    2.然后就是重新编译,发布,如果没有以外的话现在你的系统就可以使用QTP录制了。

    补足:如果自动化测试Flex系统,其实对flex系统还有其他方面的要求,详细请参考 官方说明
  • 一些自动化框架源码的下载地址

    2008-3-21

    用 CuteFtp 工具下载

    Host:
    ftp://ftp.prenhall.com/
    Username: anonymous
    Password: [your email address]

    注意:login methord 选择 anonymous 方式, Password: [your email address] 写自己的邮箱就可以了
    链接成功之后,进入路径 Directory: /pub/ptr/yourdon_press.w-080/mosley/
    可以看到一些自动化框架的源码,接下来就可以下载了。
     

    Instructions

    Because we are practitioners, the aim of this book is to offer useful advice on test automation from the test automation developer’s/user’s perspective. The purpose of this site is to fulfill that goal.

    Our examples and templates were developed on Rational Suite TestStudio platform, but we feel they can easily be adapted for use with other automated testing platforms. We have included examples, scrīpt template files and Utility scrīpt Files from Archer Group’s Control Synchronized Data Driven Testing (CSDDT) approach. We have also included Carl Nagle’s Data Driven Engine (DDE) approach also for the TestStudio environment) and Keith Zambelich’s data-driven approach using Mercury Interactive’s WinRunner automated test tool, which is based on Zambelich’s Test Plan Driven framework that uses his Toolkit For WinRunner.

    These resources can be used to easily jump-start your data-driven automated testing effort if you are a Rational or Mercury inactive customer, and even if you are not they can be easily adapted to the automated testing tool environment you are using.

    Installing and using the CSDDT templates and libraries

    1. Copy the sbh and sbl files to your default sqabas32 folder. Under Rational 2001 this should be the default path.

      Example:

      C:\your repository folder.....\TestDatastore\DefaultTestscrīptDatastore\TMS_scrīpts\SQABas32

    2. Copy the *.rec files to your default scrīpt folder. Under Rational 2001 this should be the default path unless the administrator has changed it.

      Example:

      C:\your repository folder.....\TestDatastore\DefaultTestscrīptDatastore\TMS_scrīpts

    3. After the scrīpt files have been copied, Robot will not be aware of these files. You must open robot, then select new scrīpt. Type in the name of the scrīpt file exactly as the name as the file(s) that was copied over. When you click OK the file should be displayed, already populated with the scrīpt commands.

    The sbh, sbl and rec files can be opened and edited with a standard test editor like notepad.

    After all the files have been created and then closed, go to Robot's file menu and select "Compile All".

    Provided all files have been copied to the proper location, the scrīpts should be able to be run at this point.

    Installing the ClassicsCD Example

    The same procedure as described for installing the CSDDT files should be used to install this example.

    Installing the DDE Framework

    Before installing the DDE scaffolding, go to the Documentation folder and read the DDEngine reference.htm and Data-Driven Engine System Setup.htm. These are the two most important documents to read, however, it is recommended that you also review the other documents in this folder before you attempt to install the DDE. Be sure to install the DDE and all of it associated patches/upgrades. For the version upgrades and new patches, you should check the main DDE download site at http://groups.yahoo.com/group/RobotDDEUsers/.

    Lastly you should joint this group so that you receive the DDE related email messages.

    The WinRunner Data-Driven Framework

    Begin by reading White Paper TestPlan Driven Automation.htm. At this point you will be ready for more detail and should read Keyword Method.doc. These two documents provide a complete overview of Zambelich’s framework. Also look at Toolkit For WinRunner.htm. Finally review the MS Excel workbook files, TK_OVERVIEW.xls and DRIVER.xls.

    At this point, if you are interested in implementing this approach, you must contact Keith Zambelich at Automated Testing Specialists, http://www.sqa-test.com in order to acquire a copy of the Toolkit For WinRunner software package.

    There is also a WinRunner users group at http://groups.yahoo.com/group/winrunner/ which is sponsored by Mercury Interactive.

  • QuickTest Plus帮助文档中EXCEL相关函数

    2008-3-17

    QuickTest Plus帮助文档中EXCEL相关函数

    打开QTP,test--settings--resources,将附件文件添加进去就可以使用相关函数了

    ?
    Dim ExcelApp    'As Excel.Application
    Dim excelSheet  'As Excel.worksheet
    Dim excelBook   'As Excel.workbook
    Dim fso         'As scrīpting.FileSystemObject

    ' *********************************************************************************************
    ' 函数说明:创建一个Excel应用程序ExcelApp,并创建一个新的工作薄Workbook;
    ' 参数说明:无
    ' 调用方法:
    '           CreateExcel()
    ' *********************************************************************************************

    Function CreateExcel()
        Dim excelSheet
        Set ExcelApp = CreateObject("Excel.Application")
        ExcelApp.Workbooks.Add  
        ExcelApp.Visible = True
        Set CreateExcel = ExcelApp
    End Function

    ' *********************************************************************************************
    ' 函数说明:关闭Excel应用程序;
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    ' 调用方法:
    '           CloseExcel(ExcelApp)
    ' *********************************************************************************************
    Sub CloseExcel(ExcelApp)
        Set excelSheet = ExcelApp.ActiveSheet
        Set excelBook = ExcelApp.ActiveWorkbook
        Set fso = CreateObject("scrīpting.FileSystemObject")
        On Error Resume Next
        fso.CreateFolder "C:\Temp"
        fso.DeleteFile "C:\Temp\ExcelExamples.xls"
        excelBook.SaveAs "C:\Temp\ExcelExamples.xls"
        ExcelApp.Quit
        Set ExcelApp = Nothing
        Set fso = Nothing
        Err = 0
        On Error GoTo 0
    End Sub

    ' *********************************************************************************************
    ' 函数说明:保存工作薄;
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    '          (2)workbookIdentifier:属于ExcelApp的工作薄名称;
    '          (3)path:保存的路径;
    ' 返回结果:
    '          (1)保存成功,返回字符串:OK
    '          (2)保存失败,返回字符串:Bad Worksheet Identifier
    ' 调用方法:
    '           ret = SaveWorkbook(ExcelApp, "Book1", "D:\Example1.xls")
    ' *********************************************************************************************
    ' 函数说明:保存工作薄;
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    '          (2)workbookIdentifier:属于ExcelApp的工作薄名称;
    '          (3)path:保存的路径;
    ' 返回结果:
    '          (1)保存成功,返回字符串:OK
    '          (2)保存失败,返回字符串:Bad Worksheet Identifier
    ' 调用方法:
    '           ret = SaveWorkbook(ExcelApp, "Book1", "D:\Example1.xls")
    ' *********************************************************************************************
    Function SaveWorkbook(ExcelApp, workbookIdentifier, path) 'As String
        Dim workbook
        On Error Resume Next  '启用错误处理程序
        Set workbook = ExcelApp.Workbooks(workbookIdentifier)
        On Error GoTo 0   '禁用错误处理程序
        If Not workbook Is Nothing Then
            If path = "" Or path = workbook.FullName Or path = workbook.Name Then
                workbook.Save
            Else
                Set fso = CreateObject("scrīpting.FileSystemObject")
                '判断路径中是否已添加扩展名.xls
                If InStr(path, ".") = 0 Then
                    path = path & ".xls"
                End If
                '删除路径下现有同名的文件
                On Error Resume Next
                fso.DeleteFile path
                Set fso = Nothing
                Err = 0
                On Error GoTo 0
               
                workbook.SaveAs path
            End If
            SaveWorkbook = "OK"
        Else
            SaveWorkbook = "Bad Workbook Identifier"
        End If
    End Function
    ' *********************************************************************************************
    ' 函数说明:设置工作表excelSheet单元格的值
    ' 参数说明:
    '          (1)excelSheet:工作表名称;
    '          (2)row:列的序号,第一列为1;
    '          (3)column:行的序号,第一行为1;
    '          (4)value:单元格要设置的值;
    ' 返回结果:
    '          无返回值
    ' 调用方法:
    '           SetCellValue excelSheet1, 1, 2, "test"
    ' *********************************************************************************************
    Sub SetCellValue(excelSheet, row, column, value)
        On Error Resume Next
        excelSheet.Cells(row, column) = value
        On Error GoTo 0
    End Sub
    'The GetCellValue returns the cell's value according to its row column and sheet
    'excelSheet - the Excel Sheet in which the cell exists
    'row - the cell's row
    'column - the cell's column
    'return 0 if the cell could not be found
    ' *********************************************************************************************
    ' 函数说明:获取工作表excelSheet单元格的值
    ' 参数说明:
    '          (1)excelSheet:工作表名称;
    '          (2)row:列的序号;
    '          (3)column:行的序号;
    ' 返回结果:
    '          (1)单元格存在,返回单元格值;
    '          (2)单元格不存在,返回0;
    ' 调用方法:
    '           set CellValue = GetCellValue(excelSheet, 1, 2)
    ' *********************************************************************************************
    Function GetCellValue(excelSheet, row, column)
        value = 0
        Err = 0
        On Error Resume Next
        tempValue = excelSheet.Cells(row, column)
        If Err = 0 Then
            value = tempValue
            Err = 0
        End If
        On Error GoTo 0
        GetCellValue = value
    End Function
    ' *********************************************************************************************
    ' 函数说明:获取并返回工作表对象
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    '          (2)sheetIdentifier:属于ExcelApp的工作表名称;
    ' 返回结果:
    '          (1)成功:工作表对象Excel.worksheet
    '          (1)失败:Nothing
    ' 调用方法:
    '           Set excelSheet1 = GetSheet(ExcelApp, "Sheet Name")
    ' *********************************************************************************************
    Function GetSheet(ExcelApp, sheetIdentifier)
        On Error Resume Next
        Set GetSheet = ExcelApp.Worksheets.Item(sheetIdentifier)
        On Error GoTo 0
    End Function
    ' *********************************************************************************************
    ' 函数说明:添加一张新的工作表
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    '          (2)workbookIdentifier:属于ExcelApp的工作薄名称;
    '          (2)sheetName:要插入的工作表名称;
    ' 返回结果:
    '          (1)成功:工作表对象worksheet
    '          (1)失败:Nothing
    ' 调用方法:
    '           InsertNewWorksheet(ExcelApp, workbookIdentifier, "new sheet")
    ' *********************************************************************************************

    Function InsertNewWorksheet(ExcelApp, workbookIdentifier, sheetName)
        Dim workbook 'As Excel.workbook
        Dim worksheet 'As Excel.worksheet

        '如果指定的工作薄不存在,将在当前激活状态的工作表中添加工作表
        If workbookIdentifier = "" Then
            Set workbook = ExcelApp.ActiveWorkbook
        Else
            On Error Resume Next
            Err = 0
            Set workbook = ExcelApp.Workbooks(workbookIdentifier)
            If Err <> 0 Then
                Set InsertNewWorksheet = Nothing
                Err = 0
                Exit Function
            End If
            On Error GoTo 0
        End If

        sheetCount = workbook.Sheets.Count  '获取工作薄中工作表的数量
        workbook.Sheets.Add , sheetCount '添加工作表
        Set worksheet = workbook.Sheets(sheetCount + 1)  '初始化worksheet为新添加的工作表对象

        '设置新添加的工作表名称
        If sheetName <> "" Then
            worksheet.Name = sheetName
        End If

        Set InsertNewWorksheet = worksheet
    End Function

    ' *********************************************************************************************
    ' 函数说明:修改工作表的名称;
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    '          (2)workbookIdentifier:属于ExcelApp的工作薄名称;
    '          (3)worksheetIdentifier:属于workbookIdentifier工作薄的工作表名称;
    '          (4)sheetName:修改后的工作表名称;
    ' 返回结果:
    '          (1)修改成功,返回字符串:OK
    '          (2)修改失败,返回字符串:Bad Worksheet Identifier
    ' 调用方法:
    '           set ret = RenameWorksheet(ExcelApp, "Book1", "Sheet1", "Sheet Name")
    ' *********************************************************************************************

    Function RenameWorksheet(ExcelApp, workbookIdentifier, worksheetIdentifier, sheetName)
        Dim workbook
        Dim worksheet
        On Error Resume Next
        Err = 0
        Set workbook = ExcelApp.Workbooks(workbookIdentifier)
        If Err <> 0 Then
            RenameWorksheet = "Bad Workbook Identifier"
            Err = 0
            Exit Function
        End If
        Set worksheet = workbook.Sheets(worksheetIdentifier)
        If Err <> 0 Then
            RenameWorksheet = "Bad Worksheet Identifier"
            Err = 0
            Exit Function
        End If
        worksheet.Name = sheetName
        RenameWorksheet = "OK"
    End Function

    ' *********************************************************************************************
    ' 函数说明:删除工作表;
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    '          (2)workbookIdentifier:属于ExcelApp的工作薄名称;
    '          (3)worksheetIdentifier:属于workbookIdentifier工作薄的工作表名称;
    ' 返回结果:
    '          (1)删除成功,返回字符串:OK
    '          (2)删除失败,返回字符串:Bad Worksheet Identifier
    ' 调用方法:
    '           set ret = RemoveWorksheet(ExcelApp, "Book1", "Sheet1")
    ' *********************************************************************************************

    Function RemoveWorksheet(ExcelApp, workbookIdentifier, worksheetIdentifier)
        Dim workbook 'As Excel.workbook
        Dim worksheet 'As Excel.worksheet
        On Error Resume Next
        Err = 0
        Set workbook = ExcelApp.Workbooks(workbookIdentifier)
        If Err <> 0 Then
            RemoveWorksheet = "Bad Workbook Identifier"
            Exit Function
        End If
        Set worksheet = workbook.Sheets(worksheetIdentifier)
        If Err <> 0 Then
            RemoveWorksheet = "Bad Worksheet Identifier"
            Exit Function
        End If
        worksheet.Delete
        RemoveWorksheet = "OK"
    End Function

    ' *********************************************************************************************
    ' 函数说明:添加新的工作薄
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    ' 返回结果:
    '          (1)成功:工作表对象NewWorkbook
    '          (1)失败:Nothing
    ' 调用方法:
    '          set NewWorkbook = CreateNewWorkbook(ExcelApp)
    ' *********************************************************************************************

    Function CreateNewWorkbook(ExcelApp)
        Set NewWorkbook = ExcelApp.Workbooks.Add()
        Set CreateNewWorkbook = NewWorkbook
    End Function

    ' *********************************************************************************************
    ' 函数说明:打开工作薄
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    '          (2)path:要打开的工作薄路径;
    ' 返回结果:
    '          (1)成功:工作表对象NewWorkbook
    '          (1)失败:Nothing
    ' 调用方法:
    '          set NewWorkbook = CreateNewWorkbook(ExcelApp)
    ' *********************************************************************************************

    Function OpenWorkbook(ExcelApp, path)
        On Error Resume Next
        Set NewWorkbook = ExcelApp.Workbooks.Open(path)
        Set ōpenWorkbook = NewWorkbook
        On Error GoTo 0
    End Function

    ' *********************************************************************************************
    ' 函数说明:将工作薄设置为当前工作状态
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    '          (2)workbookIdentifier:要设置为当前工作状态的工作薄名称;
    ' 返回结果:无返回值;
    ' 调用方法:
    '          ActivateWorkbook(ExcelApp, workbook1)
    ' *********************************************************************************************

    Sub ActivateWorkbook(ExcelApp, workbookIdentifier)
        On Error Resume Next
        ExcelApp.Workbooks(workbookIdentifier).Activate
        On Error GoTo 0
    End Sub

    ' *********************************************************************************************
    ' 函数说明:关闭Excel工作薄;
    ' 参数说明:
    '          (1)ExcelApp:Excel应用程序名称;
    '          (2)workbookIdentifier:
    ' 调用方法:
    '           CloseWorkbook(ExcelApp, workbookIdentifier)
    ' *********************************************************************************************

    Sub CloseWorkbook(ExcelApp, workbookIdentifier)
        On Error Resume Next
        ExcelApp.Workbooks(workbookIdentifier).Close
        On Error GoTo 0
    End Sub

    ' *********************************************************************************************
    ' 函数说明:判断两个工作表对应单元格内容是否相等
    ' 参数说明:
    '          (1)sheet1:工作表1的名称;
    '          (2)sheet2:工作表2的名称;
    '          (3)startColumn:开始比较的行序号;
    '          (4)numberOfColumns:要比较的行数;
    '          (5)startRow:开始比较的列序号;
    '          (6)numberOfRows:要比较的列数;
    '          (7)trimed:是否先除去字符串开始的空格和尾部空格后再进行比较,true或flase;
    ' 返回结果:
    '          (1)两工作表对应单元格内容相等:true
    '          (2)两工作表对应单元格内容不相等:flase         
    ' 调用方法:
    '           ret = CompareSheets(excelSheet1, excelSheet2, 1, 10, 1, 10, False)
    ' *********************************************************************************************

    Function CompareSheets(sheet1, sheet2, startColumn, numberOfColumns, startRow, numberOfRows, trimed)
        Dim returnVal 'As Boolean
        returnVal = True

        '判断两个工作表是否都存在,任何一个不存在停止判断,返回flase
        If sheet1 Is Nothing Or sheet2 Is Nothing Then
            CompareSheets = False
            Exit Function
        End If

        '循环判断两个工作表单元格的值是否相等
        For r = startRow to (startRow + (numberOfRows - 1))
            For c = startColumn to (startColumn + (numberOfColumns - 1))
                Value1 = sheet1.Cells(r, c)
                Value2 = sheet2.Cells(r, c)

                '如果trimed为true,去除单元格内容前面和尾部空格
                If trimed Then
                    Value1 = Trim(Value1)
                    Value2 = Trim(Value2)
                End If

                '如果单元格内容不一致,函数返回flase
                If Value1 <> Value2 Then
                    Dim cell 'As Excel.Range
                    '修改sheet2工作表中对应单元格值
                    sheet2.Cells(r, c) = "Compare conflict - Value was '" & Value2 & "', Expected value is '" & Value1 & "'."  
                    '初始化cell为sheet2中r:c单元格对象
                    Set cell = sheet2.Cells(r, c) '
                    '将sheet2工作表中对应单元格的颜色设置为红色
                    cell.Font.Color = vbRed  
                    returnVal = False
                End If
            Next
        Next
        CompareSheets = returnVal
    End Function
Open Toolbar