发布新日志

  • 在改变BUG的状态为Fixed的时候,如何要求强制添加注释信息(转自论坛)

    2009-08-10 13:53:43

    注意:
    1. 代码是在自定义->set up workflow中定义的,
    2. 请找到相关的function进行修改。需要具备一定vb代码基础。
    3. 不光是Fixed状态,大家可以灵活运用,根据自己的需要
    4. 我本人已经试过没有问题.
    最后,代码是一行一行整理的,大家要珍惜啊


    ' variable global to defect module
    dim CommentFieldFlag

    Function Defects_Bug_CanPost  
    On Error Resume Next
    ' checks for Status of "Fixed" and comments flag = true else allows the user post defect
        If Not Bug_Fields("BG_BUG_ID").IsNull AND Bug_Fields("BG_STATUS").Value = "Fixed" Then
            If CommentFieldFlag = True then
              Defects_Bug_CanPost = True
            Else           
              Defects_Bug_CanPost = False
              MsgBox "please add a comment (using the Add Comments button) with information about the fix.",VbInformation  ,"No Comment Warning"      
            End If
         Else      
             Defects_Bug_CanPost = True  
         End If
    'comment out or delete this next line if there by default
    'Defects_Bug_CanPost = Project_DefaultRes
    On Error GoTo 0
    End Function


    Sub Defects_Bug_AfterPost  
       On Error Resume Next
      ' resets the flag after each defect is posted
       CommentFieldFlag = False
       On Error GoTo 0
    End Sub



    Sub Defects_EnterModule  
        On Error Resume Next
      ' initialises flag   
       CommentFieldFlag = False
      On Error GoTo 0
    End Sub



    Sub Defects_Bug_FieldChange(FieldName)  
    On Error Resume Next
    ' sets flag for comments when comments updated
       If FieldName = "BG_DEV_COMMENTS" then
              CommentFieldFlag = True
       End If
      On Error GoTo 0
    End Sub
  • DTParameter 对象

    2009-08-06 20:25:06

    DTParameter对象指的是运行时DataTable Sheet中的列对象。

    注意:所有应用于DTParameter对象的方法仅适用于run-time DataTable对象。所有对run-time DataTable对象的改变只影响测试结果,不影响design-time Data Table

     

    1.     Property

    Ø        Name

    描述

    返回run-time Data Table的列名。

    语法

    DTParameter.Name

    示例

    下面的例子使用“Name”方法返回run-time Data Table中新创建的列的名称,并将列名写入Report

    Dim paramname

    paramname = DataTable.LocalSheet.AddParameter("Food", "pizza").Name

    Reporter.ReportEvent 1, "The New Parameter name is", paramname

    Ø        RawValue

    描述

    获取当前行指定列所对应的单元格的原始数据。原始数据是尚未计算处理过的数据,如单元格中的公式内容等。

    语法

    DTParameter.RawValue

    本语法与DataTable.RawValueParameterID[,SheetID]用途是一样的,但是使用方法不同。

    示例

    下面的例子使用RawValue属性来获取run-time Data Table的“ActionA”表“Date”列的当前行所对应的单元格中的公式。本例中的返回值应该是“=Now()“。

    FormulaVal=DataTable.GetSheet("ActionA").GetParameter("Date").RawValue

    Ø        Value

    描述

    这个属性是列对象的默认属性。获取或设置列的当前行所对应的单元格的数据。

    注意:这个方法返回的数据是计算后的数据。假如单元格中包括公式,则这个方法返回TrueFalse

    语法

    获取单元格数据:

    DTParameter.Value or DTParameter

    设置单元格数据:

    DTParameter.Value=newvalueor DTParameter=newvalue

    示例

    下面的例子使用Value来设置SheetActionA”的“Destination”列的当前行所对应的单元格的数据。

    DataTable.GetSheet("ActionA").GetParameter("Destination").Value="New York"

    注意:可以省略本语句中的“Value”,因为ValueDTParameter的默认属性。

    Ø        ValueByRow

    描述

    获取指定列指定行所对应的单元格的数据。

    语法

    DTParameter.ValueByRow(RowNum)

    Argument

    Type

    Descrīption

    RowNum

    Number

    指定行号。行号从1开始。

    示例

    下面的例子使用“ValueByRow”来获得表“ActionA”的“Destination”列的第4行数据。

    DataTable.GetSheet("ActionA").GetParameter("Destination").ValueByRow(4)

  • LoadRunner processor、memory、network interface性能对象 常用性能计数器说明(转)

    2009-08-06 10:58:20

    TPS  1   Transactions Per Second 的 缩 写, 也 就 是 事 务 数/ 秒

             2   Throughtput Per Second 的缩写,单位:Byte/second 字节/秒,也就是吞吐量啦。。。。。
     
    【分享】Network Interface 计数器

     

    许多人对 Kbps、KB、Mbps 等速度单位有所误解,
    以下简单解释一下所谓的 1.5M、3M、6M 如何计算。
    所谓 1.5M 宽带,其实是指 1.5Mbps (bits per second),亦即 1.5 x 1024 / 8 = 192KB/sec,

    但这只是理论上的速度,实际上则要再扣约 12% 的 Ethernet Header, IP Header, TCP Header, ATM Header 等控制讯号,故其传输速度上限应为 169KB/sec 左右。

    在传输单位的写法上,B 和 b 分别代表 Bytes 和 bits,两者的定义是不同的,钱万不要混淆。

    1 Byte = 8 bits
    1 Kb = 1024 bits
    1 KB = 1024 bytes
    1 Mb = 1024 Kb
    1 MB = 1024 KB

    宽带最高下载理论值

    1.5 M =169 KB/s
    3 M =338 KB/s
    6 M =676 KB/s
    10 M =1126 KB/s

    以上谈到的是理论值,对于实际的连接速度可以通过下载文件的方法来测试,


    Bytes Total/sec    是在每个网络适配器上发送和接收字节的速率,包括帧字符在内。Network Interface\\Bytes Received/sec=Network Interface\\Bytes Received/sec+Network Interface\\Bytes Sent/sec.

    Current Bandwidth  指以位/每秒估计的网络接口的当前带宽。

    Output Queue Length      为输出数据列队(数据包)的长度。如果这个长于 2,即会出现延缓并且如果可能的话找出并解决瓶颈问题。由于请求是在这个操作由网络驱动程序接口规格(NDIS)列队,这永远会是 0。

    Packets/sec      为在网络界面发送和接收数据包的速率。

    Packets Outbound Discarded      为选为丢弃的输出数据包的数目,即便没有发现会阻止传输这些数据包的错误。丢弃数据包的可能原因是释放缓冲空间。

    Packets Outbound Error      为由于错误不能传输的输出数据包的数目。

    Packets Received Discarded      指选定要丢弃的输入数据包的数字,即使没有发现阻碍这些数据包成为可传送到更高层协议的错误。造成丢弃数据包的可能原因是释放缓冲器空间。

    Packets Received Error       指输入数据包的数目,这些数据包含阻碍它们成为可传送到更高层协议的错误。

    Packets Received/sec        为在网络界面接收数据包的速率。

    Packets Sent/sec      为在网络界面发送数据包的速率。

     

     


    【分享】Processor计数器
    Processor计数器

    % Processor Time        指处理器用来执行非闲置线程时间的百分比。计算方法是,测量范例间隔内非闲置线程活动的时间,用范例间隔减去该值。(每台处理器有一个闲置线程,该线程在没有其他线程可以运行时消耗周期)。这个计数器是处理器活动的主要说明器,显示在范例间隔时所观察的繁忙时间平均百分比。这个值是用 100% 减去该服务不活动的时间计算出来的。    通常CPU的平均活动符合应该在80%以下,超过80%表示CPU的处理能力已经达到极限。

    % DPC Time        指在范例间隔期间处理器用在缓延程序调用(DPC)接收和提供服务的百分比。DPC 正在运行的为比标准间隔优先权低的间隔。由于 DPC 是以特权模式执行的,DPC 时间的百分比为特权时间百分比的一部分。这些时间单独计算并且不属于间隔计算总数的一部分。这个总数显示了作为实例时间百分比的平均忙时。越低越好。在多处理器系统中,如果这个值大于50%并且Processor:% Processor Time非常高,加入一个网卡可能会提高性能,提供的网络已经不饱和。

    % Privileged Time        在特权模式下处理线程执行代码所花时间的百分比。当调用 Windows 系统服务时,此服务经常在特权模式运行,以便获取对系统专有数据的访问。在用户模式执行的线程无法访问这些数据。 对系统的调用可以是直接的(explicit)或间接的(implicit),例如页面错误或中断。不像某些早期的操作系统,Windows 除了使用用户和特权模式的传统保护模式之外,还使用处理边界作为分系统保护。某些由 Windows 为您的应用程序所做的操作除了出现在处理的特权时间内,还可能在其他子系统处理出现。这个时间包括CPU维护中断和延迟过程调用的时间。如果该值过高,应该有I/O处理导致大量系统中断。

    % User Time        指处理器处于用户模式的时间百分比。用户模式是为应用程序、环境分系统和整数分系统设计的有限处理模式。另一个模式为特权模式,它是为操作系统组件设计的并且允许直接访问硬件和所有内存。操作系统将应用程序线程转换成特权模式以访问操作系统服务。这个计数值将平均忙时作为示例时间的一部分显示。

    Interrupts/sec        是处理器接收和处理硬件中断的平均速度,单位为每秒事例数。这不包括分开计数的延迟的进程调用(DPCs)。这个值说明生成中断的设备(如系统时钟、鼠标、磁盘驱动器、数据通讯线、网络接口卡和其他外缘设备)的活动。这些设备通常在完成任务或需要注意时中断处理器。正常线程执行因此被中断。系统时钟通常每 10 毫秒中断处理器一次,创建中断活动的背景。这个计数值显示用上两个实例中观察到的值之间的差除于实例间隔的持续时间所得的值。

    % Interrupt Time        是处理器在实例间隔期间接受和服务硬件中断的时间。此值间接表示了生成间隔的设备活动, 如系统时钟、鼠标、磁盘驱动程序、数据通讯线路、网络界面卡和其他外围设备。当这些设备完成一项任务或需要管理时,它们通常会中断处理器。中断期间,正常的线程执行会停止。多数系统时钟会每隔 10 毫秒中断处理器,产生间隔活动的背景,在间隔期间,终止正常的线程执行。此计数器显示此平均占用时间为实例时间的一部分。

    Private Bytes        指这个处理不能与其他处理共享的、已分配的当前字节数。

    Page Faults/sec        指在这个进程中执行线程造成的页面错误出现的速度。当线程引用了不在主内存工作集中的虚拟内存页即会出现 Page Fault。如果它在备用表中(即已经在主内存中)或另一个共享页的处理正在使用它,就会引起无法从磁盘中获取页。

    % User Time        指处理线程用于执行使用用户模式的代码的时间的百分比。应用程序、环境分系统和集合分系统是以用户模式执行的。Windows 的可执行程序、内核和设备驱动程序不会被以用户模式执行的代码损坏。不像某些早期的操作系统,Windows 除了使用用户和特权模式的传统式保护模式之外,还使用处理边界作为分系统保护。某些由 Windows 为您的应用程序所做的操作除了出现在处理的特权时间内,还可能在其他子系统处理出现。

    % Privileged Time        是在特权模式下处理线程执行代码所花时间的百分比。当调用 Windows 系统服务时,此服务经常在特权模式运行,以便获取对系统专有数据的访问。在用户模式执行的线程无法访问这些数据。对系统的调用可以是直接的(explicit)或间接的(implicit),例如页面错误或间隔。不像某些早期的操作系统,Windows 除了使用用户和特权模式的传统保护模式之外,还使用进程边界作为分系统保护。某些由 Windows 为您的应用程序所做的操作除了出现在进程的特权时间内,还可能在其他子系统进程出现。

    % Processor Time        是所有进程线程使用处理器执行指令所花的时间百分比。指令是计算机执行的基础单位。线程是执行指令的对象,进程是程序运行时创建的对象。此计数包括处理某些硬件间隔和陷阱条件所执行的代码。

    Virtual Bytes        指处理使用的虚拟地址空间的以字节数显示的当前大小。使用虚拟地址空间不一定是指对磁盘或主内存页的相应的使用。虚拟空间是有限的,可能会限制处理加载数据库的能力。

    Working Set        指这个处理的 Working Set 中的当前字节数。Working Set 是在处理中被线程最近触到的那个内存页集。如果计算机上的可用内存处于阈值以上,即使页不在使用中,也会留在一个处理的 Working Set中。当可用内存降到阈值以下,将从 Working Set 中删除页。如果需要页时,它会在离开主内存前软故障返回到 Working Set 中。

    Page File Bytes        指这个处理在 Paging file 中使用的最大字节数。Paging File 用于存储不包含在其他文件中的由处理使用的内存页。Paging File 由所有处理共享,并且 Paging File 空间不足会防止其他处理分配内存。

    I/O Data Bytes/sec        处理从 I/O 操作读取/写入字节的速度。这个计数器为所有由本处理产生的包括文件、网络和设备 I/O 的活动计数。

     

     


    【分享】Memory计数器

    Page Faults/sec        每秒钟出错页面的平均数量。由于每个错误操作中只有一个页面出错,计算单位为每秒出错页面数量,因此这也等于页面错误操作的数量。这个计数器包括硬错误(那些需要磁盘访问的)和软错误(在物理内存的其他地方找到的错误页)。许多处理器可以在有大量软错误的情况下继续操作。但是,硬错误可以导致明显的拖延。当进程请求一块内存但系统无法分配时发生页面错误,该值过高(与未加压时比较)可能有两方面的原因:
                           1、 应用程序已经占用了过多内存,这可以通过增加内存量来解决。
                            2、 应用程序的内存请求过于频繁(如:频繁地创建和销毁对象)。此时要考虑更改设计。

    Committed Bytes        指以字节表示的确认虚拟内存。确认内存磁盘页面文件上保留了空间的物理内存。每个物理磁盘上可以有一个或一个以上的页面文件。这个计数器只显示上一回观察到的值;它不是一个平均值。

    Available MBytes        计算机上运行的进程的可用物理内存大小,单位是千字节,而不是在 Memory\\Available Bytes 中报告的字节。它是将零的、空闲的和备用内存列表的空间添加在一起来计算的。空闲内存可随时使用; 零内存是为了防止以后的进程看到以前进程使用的数据而在很多页内存中填满了零的内存。备用内存是指从进程的工作集(它的物理 内存)移到磁盘的,但是仍旧可以重新调用的内存。 这个计数器只显示观察到的最后一个值;它不是一个平均值。当这个数值变小时,Windows开始频繁地调用磁盘页面文件。如果这个数值很小,例如小于5 MB,系统会将大部分时间消耗在操作页面文件上。

    Pages/sec        指为解决硬页错误从磁盘读取或写入磁盘的速度。这个计数器是可以显示导致系统范围延缓类型错误的主要指示器。它是 Memory\\Pages Input/sec 和 Memory\\Pages Output/sec 的总和。是用页数计算的,以便在不用做转换的情况下就可以同其他页计数如: Memory\\Page Faults/sec 做比较,这个值包括为满足错误而在文件系统缓存(通常由应用程序请求)的非缓存映射内存文件中检索的页。    一般如果pages/sec持续高于几百,那么您应该进一步研究页交换活动。

    Commit Limit        指在不用扩展分页文件的情况下可以使用的虚拟内存的数量。这是用字节来计算的。确认的内存是指保留在磁盘分页文件上的物理内存。在每个逻辑磁盘上可以有一个分页内存。如果扩展分页文件,这个限量将相应增加。这个计数器只显示上一回观察到的值;而不是一个平均值。

     

  • LoadRunner监视的性能计数器(转)

    2009-08-06 10:40:49

    今天,我先把我整理的一些计数器及其阈值要求等贴出来,这些计数器是针对我对windows操作系统,C/S结构的sql server数据库及WEB平台。net产品测试时的一些计数器;大家可以继续补充,作过unix平台上oracle数据库测试及J2EE架构及WEBLOGIC方面测试的朋友,也希望把自己使用的计数器贴出来,让大家分享。

        好了,先说这些了,希望通过这个专题,最终能让大家对自己的测试结果进行分析。

        Memory: 内存使用情况可能是系统性能中最重要的因素。如果系统“页交换”频繁,说明内存不足。“页交换”是使用称为“页面”的单位,将固定大小的代码和数据块从 RAM 移动到磁盘的过程,其目的是为了释放内存空间。尽管某些页交换使 Windows 2000 能够使用比实际更多的内存,也是可以接受的,但频繁的页交换将降低系统性能。减少页交换将显著提高系统响应速度。要监视内存不足的状况,请从以下的对象计数器开始:Available Mbytes:可用物理内存数。 如果Available Mbytes的值很小(4 MB 或更小),则说明计算机上总的内存可能不足,或某程序没有释放内存。

        page/sec: 表明由于硬件页面错误而从磁盘取出的页面数,或由于页面错误而写入磁盘以释放工作集空间的页面数。一般如果pages/sec持续高于几百,那么您应该进一步研究页交换活动。有可能需要增加内存,以减少换页的需求(你可以把这个数字乘以4k就得到由此引起的硬盘数据流量)。Pages/sec 的值很大不一定表明内存有问题,而可能是运行使用内存映射文件的程序所致。

        page read/sec:页的硬故障,page/sec的子集,为了解析对内存的引用,必须读取页文件的次数。阈值为>5. 越低越好。大数值表示磁盘读而不是缓存读。

        由于过多的页交换要使用大量的硬盘空间,因此有可能将导致将页交换内存不足与导致页交换的磁盘瓶径混淆。因此,在研究内存不足不太明显的页交换的原因时,您必须跟踪如下的磁盘使用情况计数器和内存计数器:Physical Disk\ % Disk Time Physical Disk\ Avg.Disk Queue Length例如,包括 Page Reads/sec 和 % Disk Time 及 Avg.Disk Queue Length.如果页面读取操作速率很低,同时 % Disk Time 和 Avg.Disk Queue Length的值很高,则可能有磁盘瓶径。但是,如果队列长度增加的同时页面读取速率并未降低,则内存不足。

        要确定过多的页交换对磁盘活动的影响,请将 Physical Disk\ Avg.Disk sec/Transfer 和 Memory\ Pages/sec 计数器的值增大数倍。如果这些计数器的计数结果超过了 0.1,那么页交换将花费百分之十以上的磁盘访问时间。如果长时间发生这种情况,那么您可能需要更多的内存。

        Page Faults/sec:每秒软性页面失效的数目(包括有些可以直接在内存中满足而有些需要从硬盘读取)较page/sec只表明数据不能在内存的指定工作集中立即使用。

        Cache Bytes:文件系统缓存(File System Cache),默认情况下为50%的可用物理内存。如IIS5.0 运行内存不够时,它会自动整理缓存。需要关注该计数器的趋势变化如果您怀疑有内存泄露,请监视 Memory\ Available Bytes 和 Memory\ Committed Bytes,以观察内存行为,并监视您认为可能在泄露内存的进程的 Process\Private Bytes、Process\Working Set 和Process\Handle Count.如果您怀疑是内核模式进程导致了泄露,则还应该监视 Memory\Pool Nonpaged Bytes、Memory\ Pool Nonpaged Allocs 和 Process(process_name)\ Pool Nonpaged Bytes.

        Pages per second :每秒钟检索的页数。该数字应少于每秒一页。

        Process:%Processor Time: 被处理器消耗的处理器时间数量。如果服务器专用于sql server,可接受的最大上限是80-85% Page Faults/sec:将进程产生的页故障与系统产生的相比较,以判断这个进程对系统页故障产生的影响。

        Work set: 处理线程最近使用的内存页,反映了每一个进程使用的内存页的数量。如果服务器有足够的空闲内存,页就会被留在工作集中,当自由内存少于一个特定的阈值时,页就会被清除出工作集。

        Inetinfo:Private Bytes:此进程所分配的无法与其它进程共享的当前字节数量。如果系统性能随着时间而降低,则此计数器可以是内存泄漏的最佳指示器。

        Processor:监视“处理器”和“系统”对象计数器可以提供关于处理器使用的有价值的信息,帮助您决定是否存在瓶颈。

        %Processor Time:如果该值持续超过95%,表明瓶颈是CPU.可以考虑增加一个处理器或换一个更快的处理器。

        %User Time:表示耗费CPU的数据库操作,如排序,执行aggregate functions等。如果该值很高,可考虑增加索引,尽量使用简单的表联接,水平分割大表格等方法来降低该值。

        %Privileged Time:(CPU内核时间)是在特权模式下处理线程执行代码所花时间的百分比。如果该参数值和"Physical Disk"参数值一直很高,表明I/O有问题。可考虑更换更快的硬盘系统。另外设置Tempdb in RAM,减低"max async IO","max lazy writer IO"等措施都会降低该值。

        此外,跟踪计算机的服务器工作队列当前长度的 Server Work Queues\ Queue Length 计数器会显示出处理器瓶颈。队列长度持续大于 4 则表示可能出现处理器拥塞。此计数器是特定时间的值,而不是一段时间的平均值。

        % DPC Time:越低越好。在多处理器系统中,如果这个值大于50%并且Processor:% Processor Time非常高,加入一个网卡可能会提高性能,提供的网络已经不饱和。

        Thread ContextSwitches/sec: (实例化inetinfo 和dllhost 进程) 如果你决定要增加线程字节池的大小,你应该监视这三个计数器(包括上面的一个)。增加线程数可能会增加上下文切换次数,这样性能不会上升反而会下降。如果十个实例的上下文切换值非常高,就应该减小线程字节池的大小。

        Physical Disk:%Disk Time %:指所选磁盘驱动器忙于为读或写入请求提供服务所用的时间的百分比。如果三个计数器都比较大,那么硬盘不是瓶颈。如果只有%Disk Time比较大,另外两个都比较适中,硬盘可能会是瓶颈。在记录该计数器之前,请在Windows 2000 的命令行窗口中运行diskperf -yD.若数值持续超过80%,则可能是内存泄漏。

        Avg.Disk Queue Length:指读取和写入请求(为所选磁盘在实例间隔中列队的)的平均数。该值应不超过磁盘数的1.5~2 倍。要提高性能,可增加磁盘。注意:一个Raid Disk实际有多个磁盘。

        Average Disk Read/Write Queue Length:指读取(写入)请求(列队)的平均数。

        Disk Reads(Writes)/s: 物理磁盘上每秒钟磁盘读、写的次数。两者相加,应小于磁盘设备最大容量。

        Average Disksec/Read: 指以秒计算的在此盘上读取数据的所需平均时间。

        Average Disk sec/Transfer:指以秒计算的在此盘上写入数据的所需平均时间。

        Network Interface:Bytes Total/sec :为发送和接收字节的速率,包括帧字符在内。判断网络连接速度是否是瓶颈,可以用该计数器的值和目前网络的带宽比较

        SQLServer性能计数器:Access Methods(访问方法) 用于监视访问数据库中的逻辑页的方法。。 Full Scans/sec(全表扫描/秒) 每秒不受限的完全扫描数。可以是基本表扫描或全索引扫描。如果这个计数器显示的值比1或2高,应该分析你的查询以确定是否确实需要全表扫描,以及S Q L查询是否可以被优化。。 Page splits/sec(页分割/秒)由于数据更新操作引起的每秒页分割的数量。

        Buffer Manager(缓冲器管理器):监视 Microsoft® SQL Server? 如何使用: 内存存储数据页、内部数据结构和过程高速缓存;计数器在 SQL Server 从磁盘读取数据库页和将数据库页写入磁盘时监视物理 I/O. 监视 SQL Server 所使用的内存和计数器有助于确定: 是否由于缺少可用物理内存存储高速缓存中经常访问的数据而导致瓶颈存在。如果是这样,SQL Server 必须从磁盘检索数据。 是否可通过添加更多内存或使更多内存可用于数据高速缓存或 SQL Server 内部结构来提高查询性能。

        SQL Server 需要从磁盘读取数据的频率。与其它操作相比,例如内存访问,物理 I/O 会耗费大量时间。尽可能减少物理 I/O 可以提高查询性能。。Page Reads/sec:每秒发出的物理数据库页读取数。这一统计信息显示的是在所有数据库间的物理页读取总数。由于物理 I/O 的开销大,可以通过使用更大的数据高速缓存、智能索引、更高效的查询或者改变数据库设计等方法,使开销减到最小。。Page Writes/sec (。写的页/秒) 每秒执行的物理数据库写的页数。。Buffer Cache Hit Ratio. 在“缓冲池”(Buffer Cache/Buffer Pool)中没有被读过的页占整个缓冲池中所有页的比率。可在高速缓存中找到而不需要从磁盘中读取的页的百分比。这一比率是高速缓存命中总数除以自 SQL Server 实例启动后对高速缓存的查找总数。经过很长时间后,这一比率的变化很小。由于从高速缓存中读数据比从磁盘中读数据的开销要小得多,一般希望这一数值高一些。通常,可以通过增加 SQL Server 可用的内存数量来提高高速缓存命中率。计数器值依应用程序而定,但比率最好为90% 或更高。增加内存直到这一数值持续高于90%,表示90% 以上的数据请求可以从数据缓冲区中获得所需数据。。 Lazy Writes/sec(惰性写/秒)惰性写进程每秒写的缓冲区的数量。值最好为0. Cache Manager(高速缓存管理器) 对象提供计数器,用于监视 Microsoft® SQL Server? 如何使用内存存储对象,如存储过程、特殊和准备好的 Transact-SQL 语句以及触发器。。 Cache Hit Ratio(高速缓存命中率,所有Cache“的命中率。在SQL Server中,Cache可以包括Log Cache,Buffer Cache以及Procedure Cache,是一个总体的比率。) 高速缓存命中次数和查找次数的比率。对于查看SQL Server高速缓存对于你的系统如何有效,这是一个非常好的计数器。如果这个值很低,持续低于80%,就需要增加更多的内存。

        Latches(闩) 用于监视称为闩锁的内部 SQL Server 资源锁。监视闩锁以明确用户活动和资源使用情况,有助于查明性能瓶颈。。 Average Latch Wait Ti m e ( m s ) (平均闩等待时间(毫秒)) 一个SQL Server线程必须等待一个闩的平均时间,以毫秒为单位。如果这个值很高,你可能正经历严重的竞争问题。。 Latch Waits/sec (闩等待/秒) 在闩上每秒的等待数量。如果这个值很高,表明你正经历对资源的大量竞争。

        Locks(锁) 提供有关个别资源类型上的 SQL Server 锁的信息。锁加在 SQL Server 资源上(如在一个事务中进行的行读取或修改),以防止多个事务并发使用资源。例如,如果一个排它 (X) 锁被一个事务加在某一表的某一行上,在这个锁被释放前,其它事务都不可以修改这一行。尽可能少使用锁可提高并发性,从而改善性能。可以同时监视 Locks 对象的多个实例,每个实例代表一个资源类型上的一个锁。。 Number of Deadlocks/sec(死锁的数量/秒) 导致死锁的锁请求的数量。 Average Wait Time(ms) (平均等待时间(毫秒)) 线程等待某种类型的锁的平均等待时间。 Lock Requests/sec(锁请求/秒) 每秒钟某种类型的锁请求的数量。

        Memory manager:用于监视总体的服务器内存使用情况,以估计用户活动和资源使用,有助于查明性能瓶颈。监视 SQL Server 实例所使用的内存有助于确定:是否由于缺少可用物理内存存储高速缓存中经常访问的数据而导致瓶颈存在。如果是这样,SQL Server 必须从磁盘检索数据。

        是否可以通过添加更多内存或使更多内存可用于数据高速缓存或 SQL Server 内部结构来提高查询性能。

        Lock blocks:服务器上锁定块的数量,锁是在页、行或者表这样的资源上。不希望看到一个增长的值。

        Total server memory:sql server服务器当前正在使用的动态内存总量。

        监视IIS需要的一些计数器Internet Information Services Global:File Cache Hits %、File CacheFlushes、File Cache Hits File Cache Hits %是全部缓存请求中缓存命中次数所占的比例,反映了IIS 的文件缓存设置的工作情况。对于一个大部分是静态网页组成的网站,该值应该保持在80%左右。而File Cache Hits是文件缓存命中的具体值,File CacheFlushes 是自服务器启动之后文件缓存刷新次数,如果刷新太慢,会浪费内存;如果刷新太快,缓存中的对象会太频繁的丢弃生成,起不到缓存的作用。通过比较File Cache Hits 和File Cache Flushes 可得出缓存命中率对缓存清空率的比率。通过观察它两个的值,可以得到一个适当的刷新值(参考IIS 的设置ObjectTTL 、MemCacheSize 、MaxCacheFileSize)

        Web Service:Bytes Total/sec:显示Web服务器发送和接受的总字节数。低数值表明该IIS正在以较低的速度进行数据传输。

        Connection Refused:数值越低越好。高数值表明网络适配器或处理器存在瓶颈。

        Not Found Errors:显示由于被请求文件无法找到而无法由服务器满足的请求数(HTTP状态代码404)

  • ORACLE三种关闭方式(转)

    2009-08-03 10:45:13

    1、shutdown normal 
       正常方式关闭数据库


    2、shutdown immediate 
       立即方式关闭数据库。 
       在SVRMGRL中执行shutdown immediate,数据库并不立即关闭, 
       而是在Oracle执行某些清除工作后才关闭(终止会话、释放会话资源), 
       当使用shutdown不能关闭数据库时,shutdown immediate可以完成数据库关闭的操作。 


    3、shutdown abort 
       直接关闭数据库,正在访问数据库的会话会被突然终止, 
       如果数据库中有大量操作正在执行,这时执行shutdown abort后,重新启动数据库需要很长時間

    --------------------------------------------------------

    shutdown abort 的时候,跟kill 进程是一样的效果
    数据库立即关闭,这个时候文件状态可能不一致
    因为正常关闭数据库会同步校验各文件,使得重新启动的时候文件时间点一致并且不用进行崩溃恢复

    若检查点信息一致,则做崩溃恢复
    若检查点信息不一致(正好在更新文件头)则需要做介质恢复

    这些问题都好处理,最怕的问题是这个时候系统有大量IO,结果这样造成写的突然中断,碰巧造成文件块的逻辑坏块,那麻烦比较大一些,尤其是系统表空间的block损坏


    虽然shutdown abort 出错的几率很小,1000个人可能只有一个人碰到,但是我们还是要小心。
    正确的处理流程是,shutdown immediate ,若数据库迟迟不能down下来,在os上观察IO状况,几乎没有io的时候,另开一窗口shutdown  abort ,几乎不会出问题了
  • Wscript.Shell 对象详细介绍(转)

    2009-08-02 11:52:27

    WshShell 对象
    ProgID Wscript.Shell
    文件名 WSHom.Ocx
    CLSID F935DC22-1CF0-11d0-ADB9-00C04FD58A0B
    IID F935DC21-1CF0-11d0-ADB9-00C04FD58A0B

    下表说明和 WshShell 对象有关的属性。
    属性 说明
    Environment 返回 WshEnvironment 集合对象。
    SpecialFolders 使用 WshSpecialFolders 对象提供对 Windows shell 文件夹的访问,如桌面文件夹,开始菜单文件夹和个人文档文件夹。

    下表说明和 WshShell 对象有关的方法。
    方法 说明
    CreateShortcut 创建并返回 WshShortcut 对象。
    ExpandEnvironmentStrings 扩展 PROCESS 环境变量并返回结果字符串。
    Popup 显示包含指定消息的消息窗口。
    RegDelete 从注册表中删除指定的键或值。
    RegRead 从注册表中返回指定的键或值。
    RegWrite 在注册表中设置指定的键或值。
    Run 创建新的进程,该进程用指定的窗口样式执行指定的命令。

    WshShell.Environment
    Environment 属性返回 WshEnvironment 对象。
    语法
    WshShell.Environment ( [strType]) = objWshEnvironment
    注释
    若 strType 指定了环境变量所处的位置,可能值为 "System"、"User"、"Volatile" 和 "Process"。若未提供 strType,则该方法在 Windows NT 中检索系统环境变量或在 Windows 95 中检索进程环境变量。
    对于 Windows 95,strType 参数仅支持 "Process"。
    下列变量是由 Windows 操作系统提供的。脚本也可获取由其他应用程序设置的环境变量。
    名称 说明
    NUMBER_OF_PROCESSORS 计算机上运行的处理器数目。
    PROCESSOR_ARCHITECTURE 用户工作站使用的处理器类型。
    PROCESSOR_IDENTIFIER 用户工作站的处理器 ID。
    PROCESSOR_LEVEL 用户工作站的处理器级。
    PROCESSOR_REVISION 用户工作站的处理器版本。
    OS 用户工作站所用的操作系统。
    COMSPEC 用于运行“命令提示”窗口的命令(通常为 cmd.exe)。
    HOMEDRIVE 本地主驱动器(通常为 C 驱动器)。
    HOMEPATH 用户的默认路径(在 Windows NT 上通常为 usersdefault)。
    PATH 路径环境变量。
    PATHEXT 可执行文件的扩展名(通常为 .com、 .exe、.bat 或 .cmd)。
    PROMPT 命令提示符(通常为 $P$G)。
    SYSTEMDRIVE 系统所在的本地驱动器(例如,c:)。
    SYSTEMROOT 系统目录(例如,c:winnt)。和 WINDIR 相同。
    WINDIR 系统目录(例如 c:winnt)。和 SYSTEMROOT 相同。
    TEMP 存储临时文件的目录(例如,c:temp)。用户可更改。
    TMP 存储临时文件的目录(例如,c:temp)。用户可更改。

    示例
    '' Retrieve the NUMBER_OF_PROCESSORS system environment variable
    Set WshShell = Wscript.CreateObject("Wscript.Shell")
    Set WshSysEnv = WshShell.Environment("SYSTEM")
    Wscript.Echo WshSysEnv("NUMBER_OF_PROCESSORS")
    请参阅
    WshEnvironment 对象

    WshEnvironment 对象
    WshEnvironment 对象未直接给出,可用 WshShell.Environment 属性来访问。
    ProgID N/A
    文件名 WSHom.Ocx
    CLSID
    IID

    下表描述与 WshEnvironment 对象关联的属性。
    属性 说明
    Item 获取或设置指定的环境变量值。
    Count 枚举项的数目。
    length 枚举项的数目 (JScript)。

    下表描述与 WshEnvironment 对象关联的方法。
    方法 说明
    Remove 删除指定的环境变量。

    WshShell.SpecialFolders
    SpecialFolders 属性提供 WshSpecialFolders 对象以便访问 Windows 的 shell 文件夹,例如桌面文件夹、开始菜单文件夹和个人文档文件夹。
    语法
    WshShell.SpecialFolders = objWshSpecialFolders
    示例
    '' This code fragment shows how to access the desktop folder
    Set WshShell = Wscript.CreateObject("Wscript.Shell")
    MsgBox "Your desktop is " & WshShell.SpecialFolders("Desktop")
    请参阅
    WshSpecialFolders 对象
    WshSpecialFolders 对象
    该对象未直接给出。要得到 WshSpecialFolders 对象,请使用 WshShell.SpecialFolders 属性。
    ProgID N/A
    文件名 WSHom.Ocx
    CLSID
    IID

    下表描述与 WshSpecialFolders 对象关联的属性。
    属性 描述
    Item 指定文件夹的完整路径(默认)。
    Count 枚举项的数目。
    length 枚举项的数目 (JScript) 。
    WshSpecialFolders.Item
    Item 属性返回由 strFolderName 指定的文件夹的完整路径。它是默认属性。
    语法
    WshShell.SpecialFolders.Item("strFolderName") = strFolderPath
    WshShell.SpecialFolders("strFolderName") = strFolderPath
    注释
    若请求的文件夹 (strFolderName) 不可用,则 WshShell.SpecialFolders("strFolderName") 返回 NULL。例如,Windows 95 没有 AllUsersDesktop 文件夹,如果 strFolderName = AllUsersDesktop,则返回 NULL。
    Windows 95 和 Windows NT 4.0 操作系统提供下列指定文件夹:
    AllUsersDesktop
    AllUsersStartMenu
    AllUsersPrograms
    AllUsersStartup
    Desktop
    Favorites
    Fonts
    MyDocuments
    NetHood
    PrintHood
    Programs
    Recent
    SendTo
    StartMenu
    Startup
    Templates
    示例
    '' This fragment returns the full path for the Windows Desktop folder
    Set WshShell = Wscript.CreateObject("Wscript.Shell")
    StrMyDesktop = WshShell.SpecialFolders("Desktop")
    '' List all special folders
    For Each strFolder In WshShell.SpecialFolders
    MsgBox strFolder
    Next
    请参阅
    WshShell.SpecialFolders 属性

    WshShell.CreateShortcut
    CreateShortcut 方法创建 WshShortcut 对象并将其返回。如果快捷方式标题以 .url 结尾,就会创建 WshURLShortcut 对象。
    语法
    WshShell.CreateShortcut(strPathname) = objShortcut
    示例
    '' This code fragment creates a shortcut
    '' to the currently executing script
    Set WshShell = Wscript.CreateObject("Wscript.Shell")
    Set ShellLink = WshShell.CreateShortcut("Current Script.lnk")
    oShellLink.TargetPath = Wscript.ScriptFullName
    oShellLink.Save
    Set UrlLink = WshShell.CreateShortcut("Microsoft Web Site.URL")
    oUrlLink.TargetPath = "
    http://www.microsoft.com"
    oUrlLink.Save
    请参阅
    WshShortcut 对象、WshUrlShortcut 对象
    WshShortcut 对象
    该对象未直接给出。要获得 WshShortcut 对象,请使用 WshShell.CreateShortcut 方法。
    ProgID N/A
    文件名 WSHom.Ocx
    CLSID F935DC28-1CF0-11d0-ADB9-00C04FD58A0B
    IID F935DC27-1CF0-11d0-ADB9-00C04FD58A0B

    下表说明和 WshShortcut 对象有关的属性。
    属性 说明
    Arguments 快捷方式对象的参数。
    Description 快捷方式对象的说明。
    Hotkey 快捷方式对象的热键。
    IconLocation 快捷方式对象的图标位置。
    TargetPath 快捷方式对象的目标路径。
    WindowStyle. 快捷方式对象的窗口样式。
    WorkingDirectory 快捷方式对象的工作目录。

    下表说明与 WshShortcut 对象有关的方法。
    方法 说明
    Save 将快捷方式存储到指定的文件系统中。
    WshShortcut.Arguments
    Arguments 属性提供快捷方式对象的参数。
    语法
    WshShortcut.Arguments = strArguments
    WshShortcut.Description
    Description 属性提供快捷方式对象的说明。
    语法
    WshShortcut.Description = strDescription
    WshShortcut.Hotkey
    HotKey 属性提供快捷方式对象的热键。热键是启动或切换程序的键盘快捷方式。
    语法
    WshShortcut.HotKey = strHotKey
    注释
    strHotKey 的BNF语法如下:
    Hotkey ::= modifier* keyname
    modifier ::= "ALT+" | "CTRL+" | "SHIFT+" | "EXT+"
    keyname ::= "A" .. "Z" |
    "0".. "9" |
    "Back" | "Tab" | "Clear" | "Return" |
    "Escape" | "Space" | "Prior" | ...
    所有键的名称都可以在 WINUSER.H 中找到。热键不区分大小写。
    热键只能激活位于 Windows 桌面或 Windows“开始”菜单的快捷方式。
    Windows 资源管理器不接受 ESC、ENTER、TAB、SPACE、PRINT SCREEN 或 BACKSPACE,即使 WshShortcut.Hotkey 遵循 Win32 API 支持它们。因此,建议在快捷方式中不要用这些键。
    示例
    Set WshShell = Wscript.CreateObject("Wscript.WshShell")
    strDesktop = WshShell.SpecialFolders("Desktop")
    Set MyShortcut = WshShell.CreateShortcut(strDesktop & "a_key.lnk")
    OMyShortcut.TargetPath = "%windir%notepad.exe"
    oMyShortCut.Hotkey = "ALT+CTRL+F"
    oMyShortCut.Save
    Wscript.Echo oMyShortCut.HotKey = "Alt+Ctrl+F"
    请参阅
    WshSpecialFolders 对象
    WshShortcut.IconLocation
    IconLocation 属性提供快捷方式对象的图标位置。图标位置的格式应为 "Path,index"。
    语法
    WshShortcut.IconLocation = strIconLocation
    WshShortcut.TargetPath
    TargetPath 属性提供快捷方式对象的目标路径。
    语法
    WshShortcut.TargetPath = strTargetPath
    WshShortcut.WindowStyle
    WindowStyle. 属性提供快捷方式对象的窗口样式。
    语法
    WshShortcut.WindowStyle. = natWindowStyle
    WshShortcut.WorkingDirectory
    WorkingDirectory 为一个快捷方式对象提供工作目录。
    语法
    WshShortcut.WorkingDirectory = strWorkingDirectory
    WshShortcut.Save
    Save 方法把快捷方式对象保存到由 FullName 属性指定的位置。
    语法
    WshShortcut.Save
    WshUrlShortcut 对象
    该对象未直接给出。要获取 WshUrlShortcut 对象,可使用 WshShell.CreateShortcut 方法。
    ProgID N/A
    文件名 WSHom.Ocx
    CLSID
    IID

    下表说明了和 WshUrlShortcut 对象有关的属性。
    属性 说明
    FullName URL 快捷方式对象的完整路径。
    TargetPath URL 快捷方式对象的目标路径。

    下表说明了和 WshUrlShortcut 对象有关的方法。
    方法 说明
    Save 将快捷方式保存到指定的文件系统中。
    WshUrlShortcut.FullName
    FullName 属性提供快捷方式对象的完整路径。
    语法
    WshUrlShortcut.FullName = strFullName
    WshUrlShortcut.TargetPath
    TargetPath 属性提供快捷方式对象的目标路径。
    语法
    WshUrlShortcut.TargetPath = strTargetPath
    WshUrlShortcut.Save
    Save 方法保存一个快捷方式,该快捷方式指向 FullName 属性指定的位置。
    语法
    WshUrlShortcut.Save
    WshShell.ExpandEnvironmentStrings
    ExpandEnvironmentStrings 方法在 strString 中扩展 PROCESS 环境变量并返回结果字符串。变量被 ''%'' 字符括起。
    环境变量不区分大小写。
    语法
    WshShell.ExpandEnvironmentStrings(strString) = strExpandedString
    示例
    MsgBox "Prompt is " & WshShell.ExpandEnviromentStrings("%PROMPT%")

    WshShell.Popup
    Popup 方法显示一个弹出式消息框窗口,消息框中包含的消息由 strText 指定。该消息框的窗口标题由 strTitle 指定。若 strTitle 省略,则窗口标题为 Windows Scripting Host。
    语法
    WshShell.Popup(strText, [natSecondsToWait], [strTitle], [natType]) = intButton
    注释
    若提供 natSecondsToWait 且其值大于零,则消息框在 natSecondsToWait 秒后关闭。
    natType 的含义与其在 Win32? MessageBox 函数中相同。下表显示 natType 中的值及含义。下表中的值可以组合。
    按钮类型
    值 说明
    0 显示“确定”按钮
    1 显示“确定”和“取消”按钮
    2 显示“终止”、“重试”和“忽略”按钮
    3 显示“是”、“否”和“取消”按钮
    4 显示“是”和“否”按钮
    5 显示“重试”和“取消”按钮

    图标类型
    值 说明
    16 显示停止标记图标
    32 显示问号图标
    48 显示感叹号图标
    64 显示信息标记图标

    以上两个表并不涵盖 natType 的所有值。完整的列表请参阅 Win32 文档。
    返回值 intButton 指示用户所单击的按扭编号。若用户在 natSecondsToWait 秒之前不单击按扭,则 intButton 设置为 -1 。
    值 说明
    1 “确定”按扭
    2 “取消”按扭
    3 “终止”按扭
    4 “重试”按扭
    5 “忽略”按扭
    6 “是”按扭
    7 “否”按扭

    示例
    Set WshShell = Wscript.CreateObject("Wscript.Shell")
    WshShell.Popup "Where do you want to go today?"
    请参阅
    Wscript.Echo 方法
    Wscript.Echo
    Echo 方法在窗口(Wscript.exe 中)或“命令提示符”窗口(Cscript.exe 中)显示参数。
    参数用空格分隔。在 Cscript.exe 中,该方法在显示最后一个参数之后输出一对回车/换行(CR LF)。
    语法
    Wscript.Echo [anyArg...]
    示例
    Wscript.Echo
    Wscript.Echo 1, 2, 3
    Wscript.Echo "Windows Scripting Host is cool."
    WshShell.RegDelete
    RegDelete 从注册表中删除名为 strName 的键或值。
    语法
    WshShell.RegDelete strName
    参数
    strName
    如果 strName 以反斜杠 () 结束,则该方法删除键而不是值。
    strName 参数必须以下列之一的根键名开始:
    短根键名 长根键名
    HKCU HKEY_CURRENT_USER
    HKLM HKEY_LOCAL_MACHINE
    HKCR HKEY_CLASSES_ROOT
    HKEY_USERS
    HKEY_CURRENT_CONFIG

    示例
    Set WshShell = Wscript.CreateObject("Wscript.Shell")
    WshShell.RegDelete "HKCUScriptEngineValue" '' Delete value "Value"
    WshShell.RegDelete "HKCUScriptEngineKey" '' Delete key "Key"
    请参阅
    WshShell.RegRead 方法、WshShell.RegWrite 方法

    WshShell.RegRead
    RegRead 方法返回名为 strName 的注册表键或值。
    语法
    WshShell.RegRead(strName) = strValue
    参数
    strName
    如果 strName 以反斜杠 () 结束,则该方法返回键,而不是值。
    strName 参数必须以下列根键名开始。
    Short Long
    HKCU HKEY_CURRENT_USER
    HKLM HKEY_LOCAL_MACHINE
    HKCR HKEY_CLASSES_ROOT
    HKEY_USERS
    HKEY_CURRENT_CONFIG

    注释
    RegRead 方法仅支持 REG_SZ、REG_EXPAND_SZ、REG_DWORD、REG_BINARY 和 REG_MULTI_SZ 数据类型。若注册表有其他数据类型,RegRead 返回 DISP_E_TYPEMISMATCH。
    示例
    Set WshShell = Wscript.CreateObject("Wscript.Shell")
    WshShell.RegRead("HKCUScriptEngineVal") '' Read from value "Val"
    WshShell.RegRead("HKCUScriptEngineKey") '' Read from key "Key"
    请参阅
    WshShell.RegDelete 方法、WshShell.RegWrite 方法

    WshShell.RegWrite
    RegWrite 方法设置名为 strName 的注册表键或值。
    语法
    WshShell.RegWrite strName, anyValue, [strType]
    参数
    strName
    若 strName 以一个反斜杠 () 结束,则该方法设置键,而不是值。
    strName 参数必须以下列根键名开头。
    Short Long
    HKCU HKEY_CURRENT_USER
    HKLM HKEY_LOCAL_MACHINE
    HKCR HKEY_CLASSES_ROOT
    HKEY_USERS
    HKEY_CURRENT_CONFIG

    anyValue
    当 strType 为 REG_SZ 或 REG_EXPAND_SZ 时,RegWrite 方法自动将 anyValue 转换为字符串。若 strType 为 REG_DWORD,则 anyValue 被转换为整数。若 strType 为 REG_BINARY,则 anyValue 必须是一个整数。
    strType
    RegWrite 方法支持 strType 为 REG_SZ、REG_EXPAND_SZ、REG_DWORD 和 REG_BINARY。若其他的数据类型被作为 strType 传递,RegWrite 返回 E_INVALIDARG。
    示例
    Set WshShell = Wscript.CreateObject("Wscript.Shell")
    WshShell.RegWrite "HKCUScriptEngineValue", "Some string value"
    WshShell.RegWrite "HKCUScriptEngineKey", 1 "REG_DWORD"
    请参阅
    WshShell.RegDelete 方法、WshShell.RegWrite方法

    WshShell.Run
    Run 方法创建一个新的进程,该进程以 intWindowStyle. 窗口样式执行 strCommand。
    语法
    WshShell.Run (strCommand, [intWindowStyle], [blnWaitOnReturn])
    参数
    strCommand
    在 strCommand 参数内部的环境变量被自动扩展。
    intWindowStyle.
    这是为新进程在 STARTUPINFO 结构内设置的 wShowWindow 元素的值。其意义与 ShowWindow 中的 nCmdShow 参数相同,可取以下值之一。名称 值 含义
    SW_HIDE
    0 隐藏窗口并激活另一窗口。
    SW_MINIMIZE
    6 最小化指定窗口并激活按 Z 序排序的下一个顶层窗口。
    SW_RESTORE
    9 激活并显示窗口。若窗口是最小化或最大化,则恢复到原来的大小和位置。在还原应用程序的最小化窗口时,应指定该标志。
    SW_SHOW
    5 以当前大小和位置激活并显示窗口。
    SW_SHOWMAXIMIZED
    3 激活窗口并以最大化显示该窗口。
    SW_SHOWMINIMIZED
    2 激活窗口并以最小化显示该窗口。
    SW_SHOWMINNOACTIVE
    7 最小化显示窗口。活动窗口保持活动。
    SW_SHOWNA
    8 以当前状态显示窗口。活动窗口保持活动。
    SW_SHOWNOACTIVATE
    4 按窗口最近的大小和位置显示。活动窗口保持活动。
    SW_SHOWNORMAL
    1 激活并显示一个窗口。若窗口是最小化或最大化,则恢复到其原来的大小和位置。

    blnWaitOnReturn
    如果未指定 blnWaitOnReturn 或其值为 FALSE,则该方法立即返回到脚本继续执行而不等待进程结束。
    若 blnWaitOnReturn 设为 TRUE,则 Run 方法返回由应用程序返回的任何错误代码。如果未指定 blnWaitOnReturn 或其值为 FALSE,则 Run 返回错误代码 0(zero)。
    示例
    '' This fragment launches Notepad with the current executed script
    Set WshShell = Wscript.CreateObject("Wscript.Shell")
    WshShell.Run ("notepad " & Wscript.ScriptFullName)
    WshShell.Run ("%windir%notepad" & Wscript.ScriptFullName)
    '' This fragment returns the error code from the executed application
    Return = WshShell.Run("notepad " & Wscript.ScriptFullName, 1, TRUE)

  • 正交表(转自论坛)

    2009-07-31 11:35:07

    1。行数为mn型的正交表中,试验次数(行数)=∑(每列水平数-1)+1
       比如一个Lx(s1^k1s2^k2..)的正交表
       它的行数计算 x=k1*(s1-1)+k2*(s2-1)+...+1

    可以结合pdf上面的例子验证:

    L18(3^66^1)=> 6*(3-1)+1*(6-1)+1=18

    L49(7^8) => 8*(7-1)+1=49


    2。pdf P33:

    “水平数(变量的取值)相同但在正交表中找不到相同的因素数(变量),取因素数最接近但略大的实际值

    的表。”

    这个例子就是P38

    实际情况是5因素2水平;作者选取了L8(2^7)的正交表;因为这就是因素数最接近但略大的实际值的正交表

    图中蓝色全处的部分;是作者舍去的;我们只要5个因素即满足;剩下的两个不需要


    3。pdf P43


    我也实在不知道L49(7^8)是怎么设计出来的!我觉得5因素6水平最接近的表也不是这个

    另外 pdf p46  

    蓝色是圈走可以删掉的 因为L18(3^66^1)中 实际只要4因素3水平的那部分 用了6因素3水平的表

    红色是指可以取任意状态;因为是多出来的;你可以自己按需设计


    4。我想给大伙一个网址;里面有个正交表库;超过200多条数据;我觉得很好的


    A Library of Orthogonal Arrays

    http://www.research.att.com/~njas/oadir/index.html#4_2


    简要说明一下格式


    标准正交表: OA.N.K.S.name

    N:行数(runs)
    K:因素(factors)
    S:水平(levels)
    t: ??(strength) 不好意思;我没搞懂strength是什么东西?  你们有知道的麻烦告诉我:)

    简记:OA(N,S^k,2) 这里strength=2


    混合正交表: MA.N.s1.k1.s2.k2...

    简记:OA(N,s1^k1,s2^k2...)
  • 揭秘QTP的DeviceReplay对象(转)

    2009-07-28 23:31:11

    不知道为什么HP的帮助文档中没有提供关于DeviceReplay的强大功能的信息描述。你可以在Java插件中却可以找到DeviceReplay的属性,但是对于那些不使用Java插件的人可能会觉得这个对象仅在Java程序的测试中可用。

    为什么要用DeviceReplay?
    有些时候我们需要针对界面做一些指定的动作,例如右键单击一个对象,使用功能键(Fx)来激活某些热键的功能,这时候就可以使用DeviceReplay对象,或者在Object.Set和Object.Type方法不生效时使用DeviceReplay。

     

    并且DeviceReplay在输入特殊符号以及不同语言的文字时会很有用,因为不需要安装指定的字体或改变键盘布局,这对于测试多语言环境的应用程序会非常有用。

     

    在鼠标操作方面,我发现DragDrop方法非常有用,可以使用它来执行拖拽的操作,把一个Item从一个Frame拖动到另外一个Frame,或者在应用程序之间拖动。

    Mercury.DeviceReplay对象
    Mercury.DeviceReplay对象用于模拟鼠标单击和移动,还有键盘输入等操作。要使用DeviceReplay,你必须确保被测试的应用程序(AUT)是处于激活状态的窗口。如果你想对某个对象执行一项操作,则该对象必须拥有焦点(focus)。对于
    Windows应用程序,可以使用Activate方法:

    Window( "W" ).Activate micLeftBtn

     

    如果想把焦点设置到某个指定的对象上,通常使用Click方法可以完成。

     

    对于Web环境的应用程序,Activate方法不被支持,因此可以使用下面的技巧来完成:

    hwnd = Browser( "B" ).GetROProperty( "hwnd" )

    Window( "hwnd:=" & hwnd ).Activate micLeftBtn

     

    通常可以使用FireEvent “onfocusin”或object.focus,例如WebEdit(“WE”).Object.focus或WebEdit(“WE”)。FireEvent “onfocusin”。

     

    在调用DeviceReplay对象的方法之前,你需要首先创建DeviceReplay对象:

    Set deviceReplay = CreateObject( "Mercury.DeviceReplay" )

    Microsoft.VisualBasic.Devices.Keyboard类
    为什么我要在介绍DeviceReplay对象之前介绍这个.NET的类呢?DeviceReplay是一个强大的未被文档化的对象,但是有一定的局限性。其中一个局限就是不能判断一个Control键是否已经被按下。在输入一个大写字母之前,我们需要知道CAPS-LOCK键是否已经按下。在使用数字键盘之前我们需要检查NUM-LOCK键是否已经被按下。否则我们在切换键盘输入状态时可能得到的并不是我们想要的状态。

     

    Devices.Keyboard类提供了属性,可用于获取当前的键盘状态,例如当前什么键被按下了,并且提供一个方法用于向激活的窗口发送键盘敲击事件。

     

    几个有用的属性包括:

    AltKeyDown - 判断ALT键是否处于按下状态。

    CapsLock -  判断CAPS LOCK键是否处于打开状态。

    CtrlKeyDown - 判断CTRL 键是否处于按下状态。

    NumLock - 判断NUM LOCK键是否处于打开状态。

    ScrollLock - 判断SCROLL LOCK键是否处于打开状态。

    ShiftKeyDown - 判断SHIFT键是否处于按下状态。

     

    Set Keyboard = DotNetFactory.CreateInstance(

    "Microsoft.VisualBasic.Devices.Keyboard", "Microsoft.VisualBasic" )

    Print CBool( Keyboard.AltKeyDown )

    Print CBool( Keyboard.CapsLock )

    Print CBool( Keyboard.CtrlKeyDown )

    Print CBool( Keyboard.NumLock )

    Print CBool( Keyboard.ScrollLock )

    Print CBool( Keyboard.ShiftKeyDown )

     

    注意:在使用DotNetFactory时数据类型必须被转换

    System.Windows.Forms.Control 类
    DeviceReplay的另外一个局限是不能获取当前鼠标(光标)在屏幕的位置。而System.Windows.Forms.Control这个类定义了那些拥有视觉表现的控件的基类。

     

    通过MousePosition属性可以获取当前鼠标光标在屏幕坐标的位置。访问MousePosition属性时,可以返回代表鼠标光标位置的Point数据。

    我的鼠标在哪?
    Set ctlr = DotNetFactory.CreateInstance("System.Windows.Forms.Control")

    For i = 1 To 10

    Wait 2

    Print "1. X=" & ctlr.MousePosition.X & "; Y=" & ctlr.MousePosition.Y

    Next

    Mercury.DeviceReplay的方法
    SendString方法
    描述

    向激活的窗口发送一个或多个键盘按键,就像敲击键盘一样。

    语法

    object.SendString( str )

    参数

    object : Mercury.DeviceReplay对象。

    str : 敲击的字符串。

    返回值

    无。

    例子

    下面的例子会激活记事本(notepad)并输入一段字符:

    Set deviceReplay = CreateObject( "Mercury.DeviceReplay" )

    SystemUtil.Run "notepad.exe", "", "", "open"

    ' ** this line always identifies the notepad window.

    Window( "nativeclass:=Notepad", "index:=0" ).Activate micLeftBtn

    deviceReplay.SendString( "DeviceReplay" )

    Set deviceReplay = Nothing

    KeyDown方法
    描述

    模拟一个按键的按下并保持(相当于Win32的KEY_DOWN事件)。

    语法

    object.KeyDown( key )

    参数

    object : Mercury.DeviceReplay对象。

    key : 按键的数值码。可查阅后面的“Key Codes 参考”。

    返回值

    无。

    例子

    下面的例子会激活记事本(notepad)程序并使用大写和小写的方式输入字符串。注意在发送第一个字符串时,SHIFT键保持被按下的状态:

    Const VK_SHIFT = 42

    Const VK_RETURN = 28

    Set deviceReplay = CreateObject( "Mercury.DeviceReplay" )

    SystemUtil.Run "notepad.exe", "", "", "open"

    Window( "nativeclass:=Notepad", "index:=0" ).Activate micLeftBtn

    ' ** Typing uppercase

    deviceReplay.KeyDown VK_SHIFT

    deviceReplay.SendString( "devicereplay" )

    deviceReplay.PressKey VK_RETURN

    deviceReplay.KeyUp VK_SHIFT

    ' ** Typing in lower case

    deviceReplay.SendString( "devicereplay" )

    Set deviceReplay = Nothing

    提示

    在KeyDown后应该有相应的KeyUp方法的调用。

    KeyDown方法就像人工按下一个按键并保持按下的状态。

    KeyUp方法
    描述

    模拟通过键盘释放某个按下的按键。

    语法

    object.KeyUp( key )

    参数

    object : Mercury.DeviceReplay对象。

    key : 按键的数值码。可查阅后面的“Key Codes 参考”。

    返回值

    无。

    例子

    下面的例子会激活并并使用热键CTRL+O来打开记事本(notepad)的菜单,然后用ESC键关闭对话框。

    Const VK_O = 24

    Const VK_CONTROL = 29

    Const VK_ESCAPE = 1

    Set deviceReplay = CreateObject( "Mercury.DeviceReplay" )

    SystemUtil.Run "notepad.exe", "", "", "open"

    Window( "nativeclass:=Notepad", "index:=0" ).Activate micLeftBtn

    ' ** Typing uppercase

    Wait 1

    ' ** Opening the menu Ctrl + O

    deviceReplay.KeyDown VK_CONTROL

    deviceReplay.PressKey VK_O

    deviceReplay.KeyUp VK_CONTROL

    Wait 2

    ' ** Closing the menu

    deviceReplay.PressKey VK_ESCAPE

    deviceReplay.SendString "Menu Open, was closed."

    Set deviceReplay = Nothing

    提示

    KeyUp方法应该与KeyDown方法配对使用。

    多个KeyUp不会对应用程序造成影响。

    如果需要组合热键,仅需要像人工执行的方式一样即可。

    PressKey方法
    描述

    模拟通过键盘按下一个按键并立即释放。

    语法

    object.PressKey( key )

    参数

    object : Mercury.DeviceReplay对象。

    key : 按键的数值码。可查阅后面的“Key Codes 参考”。

    返回值

    无。

    例子

    下面的例子会激活记事本并使用热键CTRL+O来模拟选择文件打开菜单,然后用ESCAPE按键关闭对话框。

    Const VK_O = 24 : Const VK_F = 33

    Const VK_CONTROL = 29 : Const VK_ESCAPE = 1 : Const VK_MENU = 56

    Set deviceReplay = CreateObject( "Mercury.DeviceReplay" )

    SystemUtil.Run "notepad.exe", "", "", "open"

    Window( "nativeclass:=Notepad", "index:=0" ).Activate micLeftBtn

    Wait 1

    ' ** Opening the menu Alt + F + O

    deviceReplay.PressKey VK_MENU

    deviceReplay.PressKey VK_F

    deviceReplay.PressKey VK_O

    Wait 2

    ' ** Closing the menu

    deviceReplay.PressKey VK_ESCAPE

    deviceReplay.SendString "Open menu was closed."

    Set deviceReplay = Nothing

    PressNKeys方法
    描述

    模拟通过键盘多次按下一个按键并立即释放。

    语法

    object.PressNKey( key, N )

    参数

    object : Mercury.DeviceReplay对象。

    key : 按键的数值码。可查阅后面的“Key Codes 参考”。

    N:重复的次数。

    返回值

    无。

    例子

    例1 – 美国的州

    Option Explicit

    Const VK_RETURN = 28 : Const VK_F = 33 : Const VK_O = 24

    Const VK_TAB = 15 : Const VK_F5 = 63

    Const VK_CAPITAL = 58 : Const VK_NUMLOCK = 69

    Const VK_SUBTRACT = 74 : Const VK_MULTIPLY = 55

    Const VK_MENU = 56

    Dim deviceReplay

    Private Sub SetupKeyboard()

    Const CLASS_NAME = "Microsoft.VisualBasic.Devices.Keyboard"

    Const ASSEMBLY = "Microsoft.VisualBasic"

    Dim Keyboard

    Set Keyboard = DotNetFactory.CreateInstance( CLASS_NAME, ASSEMBLY )

    If CBool( Keyboard.CapsLock ) Then

    deviceReplay.PressKey VK_CAPITAL

    End If

    If CBool( Keyboard.NumLock ) = False Then

    deviceReplay.PressKey VK_NUMLOCK

    End If

    Set Keyboard = Nothing

    End Sub

    Private Sub SetupNotepad()

    deviceReplay.PressKey VK_MENU

    deviceReplay.PressKey VK_O

    deviceReplay.PressKey VK_F

    deviceReplay.SendString "Courier New"

    deviceReplay.PressKey VK_TAB

    deviceReplay.PressKey VK_TAB

    deviceReplay.SendString "14"

    deviceReplay.PressKey VK_RETURN

    Wait 1

    End Sub

    Private Sub PrintRow( ByVal state, ByVal usps, byVal capital )

    deviceReplay.SendString state

  • QTP小知识(转)

    2009-07-28 23:29:43

    1 检查页面是否存在
    对象exist可以检查某一个页面是否存在。
    代码:
    if Browser("…").Page(“…").Exist then
    ‘在运行结果中显示的报告, “micPass”的状态是通过, micFail是不通过
       reporter.ReportEvent micPass ,“页面存在“,”通过“  
       else
       reporter.ReportEvent micFail ,"页面不存在“,"不通过"
    end if

    7.2 防止程序中断的方法
    在回放脚本的时候,有时因为错误导致运行的脚本中断,不能自动运行。为了能达到真正无人职守的状态可以在脚本的最前面加上如下的代码: 
    On error resume next  ‘遇到错误返回到脚本的下一行继续执行。
    On error goto 0 ‘错误处理的控制权,平时是由QTP控制的(这个叫默认的),当有on error resume next 时,是交给on error处理,当on error goto 0时,就换给QTP

    7.3 同步点的设定
    等待某一对象出现后继续执行,为了防止qtp找不到对象而设定同步点。有2种方法:1种是用wait加等待的时间,如wait 5(qtp等待5秒钟后继续执行)。另一种方法是等待要执行对象的出现,如果出现就继续执行,否则一直等待,代码如下:
    y=......waitproperty("visible",true,10000)
    If y=true then
       ‘执行下一条语句
       else
        ’对象不出现就一直等待,直到过了10000秒后程序找不到对象报错
    End if

    7.4 截屏
    在优化脚本时,如果想查看某一页面在执行后的页面效果,可以采取截屏的办法截取当前的操作页面并保存到本地。代码:
        desktop. capturebitmap “c:\***.bmp“,ture     ’在脚本中想要查看的一行插入,运行后图片保存到设置的路径下
    7.5 导入execl文件并参数化数据方法
    Qtp自带了datatable表,可以把要参数化的数据写在里面,但这样写脚本和数据不能分离,后期不好维护脚本。现在采用从外部导入execl文件的方法导入数据。代码如下:
       datatable.ImportSheet “D:\...\data.xls”,“sheet1”,“global“ 
       ‘第一个参数是要导入文件的路径,第二个是execl的第一个表格,第三个参数是在execl的全局范围内查找

       另外datatable对象还有很多操作,比如:获取表中字段的行数,插入表数据,删除数据等,下面是获取表中数据的代码:datatable("A","dtglobalsheet)
    7.6 为描述性编程自动创建注释
       当希望在每一个新建action时都增加一些头部说明,比如作者、创建日期、说明等信息,那么用action template 来实现最简单快捷。 方法:用记事本等文本编辑器,输入如下类似的内容:           'Company:东方般若            'Date: Date          然后将文件保存为ActionTemplate.mst,并存放到QTP安装目录下的dat目录。

    7.7 导入vbs文件
    想要实现脚本的函数化,并更好的维护它,可以把一些公用的函数写到vbs里面,用qtp来调用它。
    实现调用vbs的方法有2种:
    1.函数executefile加vbs文件的路径
      executefile “c:\...\funcation.vbs”

    2.设置QTP test/settings/resources/+函数目录

    7.8 时间差函数

    统计两个日期时间段之间的间隔,还有多少小时
    Dim timediff
    timediff=datediff(“H”,now,“2008-8-8” )
    Print timediff
    7.9 获取web下拉框中数据的行数和数据值
    1.获取行数:首先将webtable添加到对象库中,查看对象库里有该webtable的属性后
    count=Browser("…").Page("Page").Frame("…").WebTable("...").RowCount
       Msgbox count ‘查看行数
    2.获取数据值,
       for i=1 to  count    
    value=Browser("…").Page("Page").Frame("…").WebTable("...").getcelldata(i,1)
       msgbox value
       next
    获取到列表中的数值后,qtp的对象库中没有这个WebElement的对象,一般采用描述性编程的方法获取对象,比如:用getcelldata获取的表中数据的innertext属性是“普通岗”,那么就可以用如下代码:
    for i=1 to  count    
       value=Browser("…").Page("Page").Frame("…").WebTable("...").getcelldata(i,1)
     
       Browser(“…”).Page(“Page”).Frame(“…”). WebElement(“innertext:=“&value,”index:=1”).click
    next

    7.10 对象获得焦点
    判断某个webedit输入框是否获取了焦点,如果没有获取就给它焦点,然后输入数值。代码如下:

    if not browser("**").page(“**").webedit(“
    **").object.isdisabled  then
             .object.focus
             .object.set "输入数值“

    7.11 获取对象当前属性值
    用GetROProperty可以获取对象的当前属性值,比如一些对象的属性经常发生变化,用getroproterty就能定位对象当前的属性状态来执行相应的操作。
    Dim pro
    pro= browser("**").page(“**").webedit(“
      **“). GetROProperty(“property”,value)
    Msgbox pro ‘弹出窗口,查看获取的属性。

    7.12 Systemutil对象的应用
    利用systemutil可以实现的功能:回放qtp脚本时禁止鼠标和键盘的输入;打开应用程序或web;通过句柄关闭进程;通过进程名关闭进程等。下面的代码是打开百度网页:
      systemutil.run “iexplore.exe”,“http://www.baidu.com”,“”,“”,“”,3        ‘打开百度的首页,最后面的参数“3” 代表打开ie后最大化

       SystemUtil.CloseProcessByName(“iexplore.exe”)      ‘关闭ie

       
    7.13 Action的使用
    action分为内部调用和外部调用2种方法:内部调用使用split划分;外部调用时被调用的action设置成share,并共享对象库。
       split action:RunAction "action", oneIteration
    7.14.  随即数

    在测试中有时会用到随即数,有多种方法:
       
    第一种 :n=randomnumber.value(1,255)  ’n的值从1到255之间随即产生

    第二种 :randomize      ‘更新反回的数据          dim n
                 n=int (10*rnd())
                 msgbox n        ‘n为10以内的整数


    7.15 “is+*”类型功能
       isarray'是否是数组 isconnected'判断QTP是否连接到TD isdate'是否是合法的日期类型 isempty'判断是否初始化 isNull'判断是否为空值 isNumeric'判断是否是数字型 isobject'判断是否一个功能对象 isready'判断设备是否准备就绪 isRootFolder'是否是根目录
    7.16 对象库

    打开对象库resources->object repository,或者用快捷方式:ctrl+r来打开。

    1.Qtp中的对象库和脚本是一一对应的,如果脚本中某个对象在对象库中不存在,则无法回放成功,会提示找不到对象。

    2.对无法识别的对象用spy工具获得后添加到对象库中。

    3.有时候脚本回放失败就是找不到对象的原因,可以通过用spy工具查看找不到对象的属性,然后打开对象库,比较二者的属性信息,如果属性有不相同的说明就是属性的原因,可以通过更改属性的方式统一对象属性。

    7.17 调试脚本

    1.脚本编写完毕,可以用按ctrl+f7来查看脚本是否有语法错误。

    2. Msgbox和print:在回放脚本时可以方便的查看自己想看到的信息。


    3.设置断点:为了测试某一小段脚本的功能,而当整个action很长的时
    候,可以设置断点单步debug。
    7.18 强制退出
    遇到问题退出可以用exittest或 exit for,例如下面代码:

    Public function text_exit()
         for i=0 to 10
                if i=3 then
                    exittest
                    ‘exit for
                end if
         next
    End function

    Text_exit()
          
    7.19 连接数据库_增删改
    Dim conn,strSql    '定义变量
    set conn = CreateObject("ADODB.Connection")   '创建连接
    conn.ConnectionString="Provider=SQLOLEDB.1;Password=isaac121379;Persist Security Info=True;User ID=sa;Initial Catalog=WisdomCRM;Data source=192.168.12.29"   '设置连接字符串
    conn.open  '开启连接
    'strSql="insert into UM_User  values(1,'UserID')"  '设置插入语句
    strSql="drop  table TM_Task_14_Target"
    'strSql="select *  from UM_User"

    If conn.state=0 Then   '如果连接状态为0,表示连接失败,写入reporter对象中,否则表示连接成功
        Reporter.ReportEvent micFail,"testing","数据库连接失败"
        conn.close
        Set conn = nothing
    else
       Reporter.ReportEvent micPass,"testing","数据库连接成功"
       conn.execute strSql    '执行更新语句
       conn.close
       Set conn = nothing
    End If
    7.20 连接数据库_查
    Dim conn,res,strSql    '定义变量
    set conn = CreateObject("ADODB.Connection")   '创建连接
    conn.ConnectionString="Provider=SQLOLEDB.1;Password=isaac121379;Persist Security Info=True;User ID=sa;Initial Catalog=WisdomCRM;Data source=192.168.12.29"  '设置连接字符串
    conn.open  '开启连接
    Set res = CreateObject("ADODB.RecordSet")   '创建一个记录集对象
    strSql="select * from UM_User"  '设置查询雨具
    If conn.state=0 Then   '如果连接状态为0,表示连接失败,写入reporter对象中,否则表示连接成功
        Reporter.ReportEvent micFail,"testing","数据库连接失败"
        res.close                               '关闭结果集和连接,并且置为空
        Set res = nothing
        conn.close
        Set conn = nothing
    else
       Reporter.ReportEvent micPass,"testing","数据库连接成功"
       res.open strSql,conn    '执行查询语句
       res.MoveFirst        '将记录集游标指到记录集的最开始
       Do
          Reporter.ReportEvent micPass,"file",cstr(res(0))+" : "+cstr(res(1))  '循环遍历查询结果,并且保持到reproter对象中,直到记录集到达末尾,循环结束
          res.MoveNext
       Loop until res.eof = true
       res.close
       Set res = nothing
       conn.close
       Set conn = nothing
    End If
    低级录制
    在无法识别对象时使用
    利用Vbs运行外部程序
    WSH也就是用来解析Vbs的宿主,本身包含了几个个常用对象:
    1、scrīpting.FileSystemObject  —>  提供一整套文件系统操作函数
    2、scrīpting.Dictionary  —>  用来返回存放键值对的字典对象
    3、Wscrīpt.Shell  —>  提供一套读取系统信息的函数,如读写注册表、查找指定文件的路径、读取DOS环境变量,读取链接中的设置
    4、Wscrīpt.NetWork  —>
    提供网络连接和远程打印机管理的函数。(其中,所有scrīpting对象都存放在SCRRUN.DLL文件中,所有的Wscrīpt对象都存放在WSHOM.ocx文件中。)
    现在我们需要的是第三个对象,好了,让我们先连接一下对象看看,在记事本的编辑窗口中输入:
    Set ōbjShell = CreateObject(“Wscrīpt.Shell”)
    objShell.Run “notepad”
    Objshell.run “calc”
    自建日志
    Public Sub logfile(message)
    Const ForReading = 1, ForWriting = 2, ForAppending = 8
    Dim fileSystemObj, fileSpec
    Dim currentTime
    currentDate = Date
    currentTime = Time
    testName = "log"
    Set fileSystemObj = CreateObject("scrīpting.FileSystemObject")
    fileSpec ="f:\log.txt"
    If Not (fileSystemObj.FileExists(filespec)) Then
    Set logFile = fileSystemObj.CreateTextFile(fileSpec, ForWriting, True)
    logFile.WriteLine("###############################################")
    logFile.WriteLine (currentDate & currentTime & " Test: " & environment.Value("TestName") )
    logFile.WriteLin("######################################")
    logFile.Close
    Set logFile = Nothing
    End If
    Set logFile = fileSystemObj.OpenTextFile(fileSpec, ForAppending, False, True)
    logFile.WriteLine (currentDate & " "& currentTime & " " & message)
    logFile.Close
    Set logFile = Nothing
    Set fileSystemObj = Nothing
    End Sub
    logfile(“ok")
    Vb6生成dll
    Environment对象
    检查页面文字显示颜色
    Set Elements = Browser(“WisdomCRM客户关系管理系统”).Object.Document.all.tags(“div”)’tags(“td”)为在td中检查
    For each Element in Elements
      If Element.InnerText="执行团队" Then
        strhtml=Element.Innerhtml
        n=instr(strhtml,"color=red")
        If n=0 Then
          msgbox "Text color is red!"
       exit for
        End If
      End If
    Next
    关闭重复的页面
    Dim loginwin
    Set loginwin = descrīption.Create()                                                  '创建对象名为loginwin的对象
    loginwin( "name").value="WisdomCRM客户关系管理系统"   ',对象属性及值


    Set child=desktop.ChildObjects (loginwin)
    cout=child.count
    msgbox cout
    For i=1 to cout
       child(i-1).close  '循环寻找这个对象
    Next
    获取当前测试的路径
    Path = environment("TestDir")'获取当前测试的路径
    msgbox path
    获取本机ip
    set IPConfigSet = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery _
    ("select IPAddress from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")

    for each IPConfig in IPConfigSet
    if Not IsNull(IPConfig.IPAddress) then
    for i=LBound(IPConfig.IPAddress) to UBound(IPConfig.IPAddress)
    Msgbox IPConfig.IPAddress(i)
    next
    end if
    next
    点亮对象
    highlight
    fireEvent用法
    针对Link对象,onmouseover时间, 还有onchange, onclick, ondblclick, onblur, onfocus, onmousedown, onmouseup, onmouseout, onsubmit, onreset, onpropertychange事件可以使用
    sendkeys实例
    Set wshshell=createobject(“wscrīpt.shell”)
    其使用格式为:object.SendKeys string “object”:表示WshShell对象 “string”:表示要发送的按键指令字符串,需要放在英文双引号中。 1.基本键   一般来说,要发送的按键指令都可以直接用该按键字符本身来表示,例如要发送字母“x”,使用“WshShell.SendKeys "x"”即可。当然,也可直接发送多个按键指令,只需要将按键字符按顺序排列在一起即可,例如,要发送按键“happy”,可以使用“WshShell.SendKeys "happy"”。
    sendkeys实例
    2.特殊功能键 对于需要与Shift、Ctrl、Alt三个控制键组合的按键,SendKeys使用特殊字符来表示: Shift---------WshShell.SendKeys "+" Ctrl---------WshShell.SendKeys "^" Alt---------WshShell.SendKeys "%" 由于“+”、“^”这些字符用来表示特殊的控制按键了,如何表示这些按键呢? 只要用大括号括住这些字符即可。例如: 要发送加号“+”,可使用“WshShell.SendKeys "{+}"” 另外对于一些不会生成字符的控制功能按键,也同样需要使用大括号括起来按键的名称,例如要发送回车键,需要用“WshShell.SendKeys "{ENTER}"”表示,发送向下的方向键用“WshShell.SendKeys "{DOWN}"”表示。 Space---------WshShell.SendKeys " " Enter---------WshShell.SendKeys "{ENTER}" ←---------WshShell.SendKeys "{RIGHT}" ↑---------WshShell.SendKeys "{UP}" F1---------WshShell.SendKeys "{F1}" Tips:如果需要发送多个重复的单字母按键,不必重复输入该字母,SendKeys允许使用简化格式进行描述,使用格式为“{按键 数字}”。例如要发送10个字母“x”,则输入“WshShell.SendKeys "{x 10}"”即可。

    先录制取得初始脚本,再做简单的修改和参数化,再进行封装形成可重用的函数,最后回放调试,形成了最终的脚本。
  • 正交实验法设计测试用例(转)

    2009-07-28 23:28:10

    正交实验法设计测试用例是考虑用最少的用例来覆盖两两组合的情况,是套用正交表来随机的产生用例,没有主次之分,是一种提高测试覆盖率的简单易用的方法。

       正交实验法的重点是首先确定因子、状态,生成因子状态表;然后用加权筛选的方法去除不重要的因子、状态得到简化的因子状态表(因素分析表);再利用正交表构造测试数据集。

       如何选择正交表呢?有几条原则:

       1 每个因子状态数目相同的情况,因子数为M,状态数为N,则最佳选择一个M因子N状态的正交表,如果不存在这样的正交表,则选择K因子N状态的正交表(K>M)。

       2 如果不同因子状态数目不相同,选择出现次数最多的状态数(相同的话选择大的)。

       3 如果所选的正交表的状态数小于因子最大的状态数,比如

        a1  a2 

        b1  b2  b3

        c1  c2 

    则把b1 b2放在一起,写用例的时候再分开写。

     a1

     b1b2  c1
     a2  b1b2  c2
     a1  b3  c2
     a2  b3  c1

    用例:

    a1 b1 c1

    a1 b2 c1

    a2 b1 c2 

    a2 b2 c2

    a1 b3 c2

    a2 b3 c1 

    正交表的下载网址http://www.york.ac.uk/depts/maths/tables/orthogonal.htm 

     正交实验法设计测试用例的例子:

    假设一个WEB站点,该站点有大量的服务器和操作系统,并且有许多具有各种插件的浏览器浏览:

    WEB浏览器:Netscape6.2IE6.0Opera4.0

    插件:       无、RealPlayerMediaPlayer

    应用服务器:IISApcheNetscape Enterprise

    操作系统:Windows2000Windows NTLinux

     

    WEB浏览器

    插件

    应用服务器

    操作系统

    1

    Netscape6.2

    IIS

    Windows2000

    2

    Netscape6.2

    RealPlayer

    Apche

    Windows NT

    3

    Netscape6.2

    MediaPlayer

    Netscape

    Linux

    4

    IE6.0

    Apche

    Linux

    5

    IE6.0

    RealPlayer

    Netscape

    Windows2000

    6

    IE6.0

    MediaPlayer

    IIS

    Windows NT

    7

    Opera4.0

    Netscape

    Windows NT

    8

    Opera4.0

    RealPlayer

    IIS

    Linux

    9

    Opera4.0

    MediaPlayer

    Apche

    Windows2000

     

     

    正交表:

     

     

    1

    2

    3

    4

    1

    1

    1

    1

    1

    2

    1

    2

    2

    2

    3

    1

    3

    3

    3

    4

    2

    1

    2

    3

    5

    2

    2

    3

    1

    6

    2

    3

    1

    2

    7

    3

    1

    3

    2

    8

    3

    2

    1

    3

    9

    3

    3

    2

    1

    一、            提取系统功能说明中的因子:

    1、WEB浏览器

    2、插件

    3、应用服务器

    4、操作系统 

    二、            分析各因子的状态

       1、WEB浏览器:1Netscape6.22=IE6.03=Opera4.0

    2、插件: 1=None2=RealPlayer3=MediaPlayer

    3、应用服务器: 1=IIS2=Apche3=Netscape Enterprise

    4、操作系统: 1=Windows20002=Windows NT3=Linux

     

    三、            将因子、状态映射到上面正交表中:

     

    测试用例

    浏览器

    插件

    服务器

    操作系统

    1

    Netscape6.2

    None

    IIS

    Windows2000

    2

    Netscape6.2

    RealPlayer

    Apche

    Windows NT

    3

    Netscape6.2

    MediaPlayer

    Netscape Enterprise

    Linux

    4

    IE6.0

    None

    Apche

    Linux

    5

    IE6.0

    RealPlayer

    Netscape Enterprise

    Windows2000

    6

    IE6.0

    MediaPlayer

    IIS

    Windows NT

    7

    Opera4.0

    None

    Netscape Enterprise

    Windows NT

    8

    Opera4.0

    RealPlayer

    IIS

    Linux

    9

    Opera4.0

    MediaPlayer

  • ORA-01950: 对表空间 'USERS' 无权限

    2009-07-27 18:05:00

    创建新的用户时,要指定default   tablespace,否则它会把system表空间当成自己的缺省表空间。这样做是不提倡的。估计原来创建某个用户的时候没有指定缺省表空间,而现在它使用系统表空间的权限被DBA给收回了。  
      先用的简单的办法试试,一般缺省的ORACLE安装都是有USERS表空间的。  
      比如你要在用户(或SCHEMA)usera中建表,那么你用SYSTEM登录ORACLE后,执行如下SQL  
       
      ALTER   USER   usera   QUOTA   UNLIMITED   ON   USERS;  
      如果没有USERS表空间,则会报错,你可以找一个其他的表空间,从v$tablespace可以看到所有的表空间。

     

    下面情况sany用户开始创建的时候没有制定default tablespace   ********


    SQL> connect sany/as646333
    已连接。
    SQL> select * from user_sys_privs
      2  ;

    USERNAME                       PRIVILEGE                                ADM
    ------------------------------ ---------------------------------------- ---
    SANY                           CREATE SESSION                           NO
    SANY                           EXECUTE ANY PROCEDURE                    NO
    SANY                           CREATE USER                              NO
    SANY                           CREATE TABLE                             NO

    SQL> create table bjwh(user_id number(5),user_name varchar2(20),phone varchar2(12),email varchar2(20
    ));
    create table bjwh(user_id number(5),user_name varchar2(20),phone varchar2(12),email varchar2(20))
    *
    第 1 行出现错误:
    ORA-01950: 对表空间 'USERS' 无权限


    SQL> connect system/oracle
    已连接。
    SQL> alter user sany quota unlimited on users;

    用户已更改。

    SQL> connect sany/as646333
    已连接。
    SQL>  create table bjwh(user_id number(5),user_name varchar2(20),phone varchar2(12),email varchar2(2
    0));

    表已创建。

    SQL> disconnect
    从 Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
    With the Partitioning, OLAP and Data Mining options 断开
    SQL> desc bjwh
    SP2-0640: 未连接
    SP2-0641: "DESCRIBE" 需要连接至服务器
    SQL> connect sany/as646333
    已连接。
    SQL> desc bjwh
     名称                                      是否为空? 类型
     ----------------------------------------- -------- ----------------------------
     USER_ID                                            NUMBER(5)
     USER_NAME                                          VARCHAR2(20)
     PHONE                                              VARCHAR2(12)
     EMAIL                                              VARCHAR2(20)

     

    问题解决。

  • oracle中性能视图V$SYSSTAT小结(转)

    2009-07-24 17:41:41

    按照OracleDocument中的描述,v$sysstat存储自数据库实例运行那刻起就开始累计全实例(instance-wide)的资源使用情况。

    类似于v$sesstat,该视图存储下列的统计信息:
    1>.事件发生次数的统计(如:user commits)
    2>.数据产生,存取或者操作的total列(如:redo size)
    3>.如果TIMED_STATISTICS值为true,则统计花费在执行操作上的总时间(如:CPU used by this session)

    v$sysstat视图常用列介绍:
    STATISTIC#: 标识
    NAME: 统计项名称
    VALUE: 资源使用量
    该视图还有一列class-统计类别但极少会被使用,各类信息如下:
    1 代表事例活动
    2 代表Redo buffer活动
    4 代表锁
    8 代表数据缓冲活动
    16 代表OS活动
    32 代表并行活动
    64 代表表访问
    128 代表
    信息
    注意:Statistic#的值在不同版本中各不相同,使用时要用Name做为查询条件而不要以statistic#的值做为条件。

    使用v$sysstat中的数据

      该视图中数据常被用于监控系统性能。如buffer cache命中率、软解析率等都可从该视图数据计算得出。
    该视图中的数据也被用于监控系统资源使用情况,以及系统资源利用率的变化。正因如此多的性能数据,检查某区间内系统资源使用情况可以这样做,在一个时间段开始时创建一个视图数据快照,结束时再创建一个,二者之间各统计项值的不同(end value - begin value)即是这一时间段内的资源消耗情况。这是oracle工具的常用方法,诸如Statspack以及BSTAT/ESTAT都是如此。
    为了对比某个区间段的数据,源数据可以被格式化(每次事务,每次执行,每秒钟或每次登陆),格式化后数据更容易从两者中鉴别出差异。这类的对比在升级前,升级后或仅仅想看看一段时间内用户数量增长或数据增加如何影响资源使用方面更加实用。
    你也可以使用v$sysstat数据通过查询v$system_event视图来检查资源消耗和资源回收。

    V$SYSSTAT中包含多个统计项,这部分介绍了一些关键的v$sysstat统计项,在调优方面相当有用。下列按字母先后排序:

     

    数据库使用状态的一些关键指标:

    l         CPU used by this session:所有sessioncpu占用量,不包括后台进程。这项统计的单位是百分之x.完全调用一次不超过10ms

    l         db block changes:那部分造成SGA中数据块变化的insert,updatedelete操作数 这项统计可以大概看出整体数据库状态。在各项事务级别,这项统计指出脏缓存比率。

    l         execute count:执行的sql语句数量(包括递归sql)

    l         logons current:当前连接到实例的Sessions。如果当前有两个快照则取平均值。

    l         logons cumulative:自实例启动后的总登陆次数。

    l         parse count (hard):在shared pool中解析调用的未命中次数。当sql语句执行并且该语句不在shared pool或虽然在shared pool但因为两者存在部分差异而不能被使用时产生硬解析。如果一条sql语句原文与当前存在的相同,但查询表不同则认为它们是两条不同语句,则硬解析即会发生。硬解析会带来cpu和资源使用的高昂开销,因为它需要oracleshared pool中重新分配内存,然后再确定执行计划,最终语句才会被执行。

    l         parse count (total):解析调用总数,包括软解析和硬解析。当session执行了一条sql语句,该语句已经存在于shared pool并且可以被使用则产生软解析。当语句被使用(即共享) 所有数据相关的现有sql语句(如最优化的执行计划)必须同样适用于当前的声明。这两项统计可被用于计算软解析命中率。

    l         parse time cpu:总cpu解析时间(单位:10ms)。包括硬解析和软解析。

    l         parse time elapsed:完成解析调用的总时间花费。

    l         physical readsOS blocks read数。包括插入到SGA缓存区的物理读以及PGA中的直读这项统计并非i/o请求数。

    l         physical writes:从SGA缓存区被DBWR写到磁盘的数据块以及PGA进程直写的数据块数量。

    l         redo log space requests:在redo logs中服务进程的等待空间,表示需要更长时间的log switch

    l         redo sizeredo发生的总次数(以及因此写入log buffer),以byte为单位。这项统计显示出update活跃性。

    l         session logical reads:逻辑读请求数。

    l         sorts (memory) and sorts (disk)sorts(memory)是适于在SORT_AREA_SIZE(因此不需要在磁盘进行排序)的排序操作的数量。sorts(disk)则是由于排序所需空间太大,SORT_AREA_SIZE不能满足而不得不在磁盘进行排序操作的数量。这两项统计通常用于计算in-memory sort ratio

    l         sorts (rows): 列排序总数。这项统计可被'sorts (total)'统计项除尽以确定每次排序的列。该项可指出数据卷和应用特征。

    l         table fetch by rowid:使用ROWID返回的总列数(由于索引访问或sql语句中使用了'where rowid=&rowid'而产生)

    l         table scans (rows gotten):全表扫描中读取的总列数

    l         table scans (blocks gotten):全表扫描中读取的总块数,不包括那些split的列。

    l         user commits + user rollbacks:系统事务起用次数。当需要计算其它统计中每项事务比率时该项可以被做为除数。例如,计算事务中逻辑读,可以使用下列公式:session logical reads / (user commits + user rollbacks)

     

    注:SQL语句的解析有软解析soft parse与硬解析hard parse之说,以下是5个步骤:

    1:语法是否合法(sql写法)

    2:语义是否合法(权限,对象是否存在)

    3:检查该sql是否在公享池中存在

    -- 如果存在,直接跳过45,运行sql. 此时算soft parse

    4:选择执行计划

    5:产生执行计划

    -- 如果5个步骤全做,这就叫hard parse.

     

    注意物理I/O

     

      oracle报告物理读也许并未导致实际物理磁盘I/O操作。这完全有可能因为多数操作系统都有缓存文件,可能是那些块在被读取。块也可能存于磁盘或控制级缓存以再次避免实际I/OOracle报告有物理读也许仅仅表示被请求的块并不在缓存中。

     

    V$SYSSTAT得出实例效率比(Instance Efficiency Ratios)

     

    下列是些典型的instance efficiency ratios v$sysstat数据计算得来,每项比率值应该尽可能接近1

     

    l         Buffer cache hit ratio:该项显示buffer cache大小是否合适。

    公式:1-((physical reads-physical reads direct-physical reads direct (lob)) / session logical reads)

    执行:

    select 1-((a.value-b.value-c.value)/d.value)

     from v$sysstat a,v$sysstat b,v$sysstat c,v$sysstat d

     where a.name='physical reads' and

             b.name='physical reads direct' and

             c.name='physical reads direct (lob)' and

             d.name='session logical reads';

     

    l         Soft parse ratio:这项将显示系统是否有太多硬解析。该值将会与原始统计数据对比以确保精确。例如,软解析率仅为0.2则表示硬解析率太高。不过,如果总解析量(parse count total)偏低,这项值可以被忽略。

    公式:1 - ( parse count (hard) / parse count (total) )

    执行:

    select 1-(a.value/b.value)

     from v$sysstat a,v$sysstat b

     Where a.name='parse count (hard)' and b.name='parse count (total)';

     

    l         In-memory sort ratio:该项显示内存中完成的排序所占比例。最理想状态下,在OLTP系统中,大部分排序不仅小并且能够完全在内存里完成排序。

    公式:sorts (memory) / ( sorts (memory) + sorts (disk) )

    执行:

    select a.value/(b.value+c.value)

     from v$sysstat a,v$sysstat b,v$sysstat c

     where a.name='sorts (memory)' and

             b.name='sorts (memory)' and c.name='sorts (disk)';

     

    l         Parse to execute ratio:在生产环境,最理想状态是一条sql语句一次解析多数运行。

    公式:1 - (parse count/execute count)

    执行:

    select 1-(a.value/b.value)

     from v$sysstat a,v$sysstat b

     where a.name='parse count (total)' and b.name='execute count';

     

    l         Parse CPU to total CPU ratio:该项显示总的CPU花费在执行及解析上的比率。如果这项比率较低,说明系统执行了太多的解析。

    公式:1 - (parse time cpu / CPU used by this session)

    执行:

    select 1-(a.value/b.value)

     from v$sysstat a,v$sysstat b

     where a.name='parse time cpu' and

             b.name='CPU used by this session';

     

    l         Parse time CPU to parse time elapsed:通常,该项显示锁竞争比率。这项比率计算

    是否时间花费在解析分配给CPU进行周期运算(即生产工作)。解析时间花费不在CPU周期运算通常表示由于锁竞争导致了时间花费

    公式:parse time cpu / parse time elapsed

    执行:

    select a.value/b.value

     from v$sysstat a,v$sysstat b

     where a.name='parse time cpu' and b.name='parse time elapsed';

     

    V$SYSSTAT获取负载间档(Load Profile)数据

     

      负载间档是监控系统吞吐量和负载变化的重要部分,该部分提供如下每秒和每个事务的统计信息:logons cumulative, parse count (total), parse count (hard), executes, physical reads, physical writes, block changes, and redo size.

     

      被格式化的数据可检查'rates'是否过高,或用于对比其它基线数据设置为识别system profile在期间如何变化。例如,计算每个事务中block changes可用如下公式:

    db block changes / ( user commits + user rollbacks )

    执行:

    select a.value/(b.value+c.value)

     from v$sysstat a,v$sysstat b,v$sysstat c

     where a.name='db block changes' and

             b.name='user commits' and c.name='user rollbacks';

     

     

    其它计算统计以衡量负载方式,如下:

    l         Blocks changed for each read:这项显示出block changesblock reads中的比例。它将指出是否系统主要用于只读访问或是主要进行诸多数据操作(如:inserts/updates/deletes)

    公式:db block changes / session logical reads

    执行:

    select a.value/b.value

     from v$sysstat a,v$sysstat b

     where a.name='db block changes' and

             b.name='session logical reads' ;

     

    l         Rows for each sort

    公式:sorts (rows) / ( sorts (memory) + sorts (disk) )

    执行:

    select a.value/(b.value+c.value)

     from v$sysstat a,v$sysstat b,v$sysstat c

     where a.name='sorts (rows)' and

             b.name='sorts (memory)' and c.name='sorts (disk)';

  • QTP使用EXCEL对象(转)

    2009-07-24 16:19:19

    一、Excel对象模型

      为了在VB应用程序中调用Excel,必须要了解Excel对象模型。Excel对象模型描述了Excel的理论结构,所提供的对象很多,其中最重要的对象,即涉及VB调用Excel最可能用到的对象有:



      二、调用Excel

      在VB应用程序中调用Excel,实质是将Excel作为一个外部对象来引用,由Excel对象模型提供能从VB应用程序内部来程序化操纵的对象以及相关的属性、方法和事件。

      1、在VB工程中添加对Excel类型库的引用

      为了能从VB应用程序中访问Excel丰富的内部资源,使Excel应用程序运行得更快,需要在VB工程中添加对Excel类型库的引用。具体步骤如下:

      a)从VB5“工程”菜单中选择“引用”;

      b) 在“引用”对话框中选择Excel类型库:"Microsoft Excel9.0 Object Library";

      c)单击左边小方框,使之出现“√”符号;

      d)按“确定”退出。

      注:要想在VB应用程序中调用Excel,你的计算机系统中必须安装Excel。

      2、引用Application对象

      Application对象是Excel对象模型的顶层,表示整个Excel应用程序。在VB应用程序中调用Excel,就是使用Application对象的属性、方法和事件。为此,首先要声明对象变量:

    Dim VBExcel As Object

      或直接声明为Excel对象:

    Dim VBExcel As Excel.Application

      在声明对象变量之后,可用CreateObject函数或GetObject函数给变量赋值新的或已存在的Application对象引用。

      a)用CreateObject函数生成新的对象引用:

    Set VBExcel=CreateObject ("Excel.Application")

      字符串“Excel.Application”是提供Excel应用程序的编程ID,这个变量引用Excel应用程序本身。

      b)用Getobject函数打开已存在的对象引用:

    Set AppExcel=GetObject("SAMP.XLS")

      上面语句打开文件SAMP.XLS。

      3、Application对象常用的属性、方法

    属性、方法 方法
    Visible属性 取True或False,表明Excel应用程序是否可见。
    Left,Top属性 Excel窗口的位置;
    Height, Width属性 Excel窗口的大小;
    WindowState属性 指定窗口的状态,取:XIMaximized(最大化)X1 Minimized(最小化)x1 Normal(缺省)。
    Quit方法 退出Microsoft Excel;
    Calculate方法 重新计算所有打开的工作簿、工作表或单元格。
    Evaluate方法 求值数学表达式并返回结果。

      示例1:求值数学表达式:

    Dim VBExcel As Object
    Set VBExcel=CreateObject ("Excel.Application")
    X=VBExcel. Evaluate ("3+5*(cos (1/log (99. 9)))")

    三、使用Excel应用程序

      如前所述,在VB应用程序中调用Excel应用程序,就是使用Application对象的属性、方法和事件。下面分类给出其中常用的属性和方法。

      1、使用工作薄

      Workbook对象代表Excel应用程序中当前打开的一个工作簿,包含在Workbooks集合中。可以通过Workbooks集合或表示当前活动工作簿的Active Workbook对象访问Workbook对象。

      常用的方法有:

    属性、方法 意义
    Add方法 创建新的空白工作簿,并将其添加到集合中。
    Open方法 打开工作簿。
    Activate方法 激活工作簿,使指定工作簿变为活动工作簿,以便作为Active Workbook对象使用。
    Save方法 按当前路径和名称保存现有工作簿(如是首次保存,则将其保存到缺省名称中,如BOOK1.XLS)。
    SaveAs方法 首次保存工作簿或用另一名称保存工作簿。
    Close方法 关闭工作簿。
    PrintOut方法 打印工作簿,语法为:

    PrintOut (from, To, Copies, Preview, Printer, ToFile, Collate)

      可选参数:

     From:打印的起始页号。如省略将从起始位置开始打印。
     To:打印的终止页号。如省略将打印至最后一页。
     Copies:要打印的份数。如省略将只打印一份。
     Preview:如果为True则Excel打印指定对象之前进行打印预览。如果为False,或省略则立即打印该对象。
     Printer:设置活动打印机的名称。
     ToFile:如果为True则打印输出到文件。
     Collate:如果为True则逐份打印每份副本。

      下面语句将活动工作簿的2到5页打印3份:

    ActiveWorkbook.PrintOut From:=2 To 5 Copies:=3

      示例2:生成、保存、关闭工作簿

    Dim VBExcel As Excel.Application
    Set VBExcel== CreateObject("Excel.Application")
    With VBExcel
    .Workbooks.Add
    With ActiveWorkbook
    .Save As"C: \Temp \OUTPUT.XLS"
    .Close
    End With
    .Quit
    End With

      2、使用工作表

      Sheets集合表示工作簿中所有的工作表。可以通过Sheets集合来访问、激活、增加、更名和删除工作表。一个Worksheet对象代表一个工作表。

      常用的属性、方法有:

    属性、方法 意义
    Worksheets属性 返回Sheets集合。
    Name属性 工作表更名。
    Add方法 创建新工作表并将其添加到工作簿中。
    Select方法 选择工作表。
    Copy方法 复制工作表。
    Move方法 将指定工作表移到工作簿的另一位置。
    Delete方法 删除指定工作表。
    PrintOut方法 打印工作表。

      示例3:将C盘工作簿中的工作表复制到A盘工作簿中:

    Dim VBExcel As Excel.Application
    Set VBExcel=CreateObject("Excel.Application")
    With VBExcel
     .Workbooks.Open "C:\Temp\OUTPUT.XLS"
     .Workbooks.Open"A:\OUTPUT1.XLS"
     .Workbooks("OUTPUT.XLS").Sheets ("Sales").Copy
     .Workbooks("OUTPUT1.XLS)
     .Workbooks("OUTPUT1.XLS").Save
     .Workbooks("OUTPUT.XLS").Close
     .Workbooks("OUTPUTI.XLS").Close
     .Quit
    End With

      3、使用单元范围

      Range对象代表工作表的某一单元格、某一行、某一列、某一选定区域或者某一三维区域。

      常用的属性、方法有:

    属性、方法 意义
    Range属性 Range (arg)其中arg为A1--样式符号,表示单个单元格或单元格区域。
    Cells属性 Cells (row, col )(其中row为行号,col为列号)表示单个单元格。
    ColumnWidth属性 指定区域中所有列的列宽。
    Rowl3eight属性 指定区域中所有行的行宽。
    Value属性 指定区域中所有单元格的值(缺省属性)。
    Formula属性 指定单元格的公式,由A1--样式引用。
    Select方法 选择范围。
    Copy方法 将范围的内容复制到剪贴板。
    C1earContents方法 清除范围的内容。
    Delete方法 删除指定单元范围。

      4、使用图表

      Chart对象代表工作簿中的图表。该图表既可为嵌人式图表(包含于ChartObject对象中)也可为分立的图表工作表。

      常用方法有:

    方法

    意义

    Add方法 新建图表工作表。返回Chart对象。
    PrineOut方法 打印图表。
    ChartWizard方法 修改给定图表的属性,其语法为:
     
    ChartWizard(Source, Gallery, Format, P1otBy, CategoryLabels,
    SeriesLabels, HasLegend, Title, CategoryTitle, ValueTitle, ExtraTitle)

      其中:

      Source:包含新图表的源数据的区域。如省略,将修改活动图表工作表或活动工作表中处于选定状态的嵌人式图表。

      Gallery:图表类型。其值可为下列常量之一:xlArea, x1Bar, xlColumn, xlLine, x1Pie, xlRadar,x1XYScatter, xlCombination, x13DArea, x13DBar、x13DColumn, x13DLine, x13DPie、x13 DSurface、xlDoughnut或xlDefaultAutoFormat。

      Format:内置自动套用格式的编号。如省略,将选择默认值。

      P1otBy:指定系列中的数据是来自行(xlRows)还是列(xlColumns)。

      CategoryLabels:表示包含分类标志的源区域内行数或列数的整数。

      SeriesLabels:表示包含系列标志的源区域内行数或列数的整数。

      HasLegend:若指定True,则图表将具有图例。

      Title:图表标题文字。

      CategoryTitle:分类轴标题文字。

      ValueTitle:数值轴标题文字。

      ExtraTitle:三维图表的系列轴标题,或二维图表的第二数值轴标题。

      可组合使用Add方法和ChartWizard方法,以创建包含工作表中数据的图表工作表。下例基于工作表“Sheetl”中单元格区域“A1:A20”中的数据生成新的折线图并打印。

    With Charts.Add
     .ChartWizard source:=Worksheets ("sheet1").Range ("a1:a20"),gallery:=xlLine, title:=“折线图表”
     .Printout
    End With


      5、使用Excel工作表函数

      在VB语句中可使用大部分的Excel工作表函数,可通过WorksheetFunction对象调用Excel工作表函数。下面的Sub过程用Min工作表函数求出指定区域中单元格的最小值,并通过消息框显示结果值。

    Sub UseFunction()
    Dim myRange As Range
    Set myRange=Worksheets ("Sheet1").Range("B2:F10")
    answer=Application.WorksheetFunction.Min(myRange)
    MsgBox answer
    End Sub

      如果使用以区域引用为参数的工作表函数,必须指定一个Range对象。如可用Match工作表函数对A1:A10区域的所有单元格进行搜索。

    Sub FindFirst()
    my Var=Application.WorksheetFunction.Match (9, Worksheets( 1).Range("A1:A10"),0)
    MsgBox myVar
    End Sub

      要在单元格中插人工作表函数,可将该函数指定为对应于Range对象的Formula属性值。在以下示例中,将当前工作簿Sheetl内A1:B3区域的Formula属性指定为RAND工作表函数(此函数产生二个随机数)。

    Sub InsertFormula()
    Worksheets ("Sheet1" ).Range("A1:B3").Formula="RAND()"
    End Sub

  • 设计功能和界面测试用例

    2009-07-03 15:30:59

    1.1 文本框、按钮等控件测试
    1.1.1 文本框的测试
    如何对文本框进行测试

     a,输入正常的字母或数字。
     b,输入已存在的文件的名称;
     c,输入超长字符。例如在“名称”框中输入超过允许边界个数的字符,假设最多255个字符,尝试输入 256个字符,检查程序能否正确处理;
     d,输入默认值,空白,空格;
     e,若只允许输入字母,尝试输入数字;反之;尝试输入字母;
     f,利用复制,粘贴等操作强制输入程序不允许的输入数据;
     g,输入特殊字符集,例如,NUL及\n等;
     h,输入超过文本框长度的字符或文本,检查所输入的内容是否正常显示;
     i,输入不符合格式的数据,检查程序是否正常校验,如,程序要求输入年月日格式为yy/mm/dd,实际输入yyyy/mm/dd,程序应该给出错误提示
    在测试过程中所用到的测试方法:
     1,输入非法数据;
     2,输入默认值;
     3,输入特殊字符集;
     4,输入使缓冲区溢出的数据;
     5,输入相同的文件名; 命令按钮控件的测试
    测试方法:
     a,点击按钮正确响应操作。如,单击确定,正确执行操作;单击取消,退出窗口;
     b,对非法的输入或操作给出足够的提示说明,如,输入月工作天数为32时,单击”确定“后系统应提示:天数不能大于31;
     c,对可能造成数据无法恢复的操作必须给出确认信息,给用户放弃选择的机会; 单选按钮控件的测试
    测试方法:
     a,一组单选按钮不能同时选中,只能选中一个。
     b,逐一执行每个单选按钮的功能。分别选择了“男”“女”后,保存到数据库的数据应该相应的分别为“男”“女”;
     c,一组执行同一功能的单选按钮在初始状态时必须有一个被默认选中,不能同时为空; up-down控件文本框的测试
    测试方法:
     a,直接输入数字或用上下箭头控制,如,在“数目”中直接输入10,或者单击向上的箭头,使数目变为10;
     b,利用上下箭头控制数字的自动循环,如,当最多数字为253时,单击向上箭头,数目自动变为1;反之亦适用;
     c,直接输入超边界值,系统应该提示重新输入;
     d,输入默认值,空白。如,“插入”数目为默认值,点击“确定”;或,删除默认值,使内容为空,单击“确定”进行测试;
     e,输入字符。此时系统应提示输入有误。 组合列表框的测试
    测试方法:
     a,条目内容正确,其详细条目内容可以根据需求说明确定;
     b,逐一执行列表框中每个条目的功能;
     c,检查能否向组合列表框输入数据; 复选框的测试
    测试方法:
     a,多个复选框可以被同时选中;
     b,多个复选框可以被部分选中;
     c,多个复选框可以都不被选中;
     d,逐一执行每个复选框的功能; 列表框控件的测试
    测试方法:
     a,条目内容正确;同组合列表框类似,根据需求说明书确定列表的各项内容正确,没有丢失或错误;
     b,列表框的内容较多时要使用滚动条;
     c,列表框允许多选时,要分别检查shift选中条目,按ctrl选中条目和直接用鼠标选中多项条目的情况; 滚动条控件的测试
    要注意一下几点:
     a,滚动条的长度根据显示信息的长度或宽度及时变换,这样有利于用户了解显示信息的位置和百分比,如,word中浏览100页文档,浏览到50页时,滚动条位置应处于中间;
     b,拖动滚动条,检查屏幕刷新情况,并查看是否有乱码;
     c,单击滚动条;
     d,用滚轮控制滚动条;
     e,滚动条的上下按钮。 各种控件在窗体中混和使用时的测试
     a,控件间的相互作用;
     b,tab键的顺序,一般是从上到下,从左到右;
     c,热键的使用,逐一测试;
     d,enter键和esc键的使用; 在测试中,应遵循由简入繁的原则,先进行单个控件功能的测试,确保实现无误后,再进行多个控件的的功能组合的测试。
    ps:密码输入框测试时要特别注意进行字母大写输入的测试。
    查找替换操作
     案例演示:打开word中的"替换"对话框
     测试本功能有通过测试和失败测试两种情况
     通过测试:

     1,输入内容直接查找,或查找全部
     2,在组合框中寻找已经查找过的内容,再次查找并确认文档的内容正确,如,已经查找过"测试用例",再次进入不用重新输入查找内容,直接在文档中搜寻就可以.
    失败测试:
     1,输入过长或过短的查询字符串.如,假设查询的字符串长度为1到255,那么输入0,1,2,256,255和254进行测试;
     2,输入特殊字符集,如,在word中.^g代表图片,^代表分栏符,可以输入这类特殊字符测试;
    替换测试大体相同.
     关于编辑操作窗口的功能测试的用例:
     1,关闭查找替换窗口.不执行任何操作,直接退出;
     2,附件和选项测试.假如,设定"精确搜寻","向后"搜索等附件选项等等来测试;
     3,控件间的相互作用.如,搜寻内容为空时,按钮"搜寻全部","搜寻","全部替换","替换"都为灰色.
     4,热键, Tab键.回车键的使用.
    插入操作
     1,插入文件
     测试的情况
     a,插入文件;
     b,插入图像;
     c,在文档中插入文档本身;
     d,移除插入的源文件;
     e,更换插入的源文件的内容;
    2,链接文件
     测试方法:
     a,插入链接文件;
     b,在文档中链接文档本身;
     c,移除插入的源文件;
     d,更换插入的源文件的内容.
    3,插入对象
     要测试的内容
     a,插入程序允许的对象,如,在word中插入excel工作表;
     b,修改所插入对象的内容.插入的对象仍能正确显示;
     c,卸载生成插入对象的程序,如,在word中插入excel工作表后卸载excel,工作表仍正常使用.
    编辑操作
     编辑操作包括剪切,复制,粘贴操作.
    测试剪切操作的方法
     a,对文本,文本框,图文框进行剪切;
     b,剪切图像
     c,文本图像混合剪切
     复制操作方法与剪切类似.
    测试时,主要是对粘贴操作的测试,方法是:
     a,粘贴剪切的文本,文本框及图文框;
     b,粘贴所剪切的图像;
     c,剪切后,在不同的程序中粘贴
     d,多次粘贴同一内容,如,剪切后,在程序中连续粘贴3次;
     e,利用粘贴操作强制输入程序所不允许输入的数据.
    界面测试用例的设计方法
     1,窗体
     测试窗体的方法:
     a,窗体大小,大小要合适,控件布局合理;
     b,移动窗体.快速或慢速移动窗体,背景及窗体本身刷新必须正确;
     c,缩放窗体,窗体上的控件应随窗体的大小变化而变化;
     d,显示分辨率.必须在不同的分辨率的情况下测试程序的显示是否正常;
     进行测试时还要注意状态栏是否显示正确;工具栏的图标执行操作是否有效,是否与菜单懒中图标显示一致;错误信息内容是否正确,无错别字,且明确等等;
    2,控件
     测试方法:
     a,窗体或控件的字体和大小要一致;
     b,注意全角,半角混合
     c,无中英文混合.
    菜单
    进行测试时要注意
     a,选择菜单是否可以正常工作,并与实际执行内容一致;
     b,是否有错别字:
     c,快捷键是否重复;
     d,热键是否重复;
     e,快捷键与热键操作是否有效
     f,是否存在中英文混合
     g,菜单要与语境相关,如,不同权限的用户登陆一个应用程序,不同级别的用户可以看到不同级别的菜单并使用不同级别的功能;
     h,鼠标右键快捷菜单
    特殊属性
     1,安装界面应有公司介绍或产品介绍,有公司的图标
     2,主界面及大多数界面最好有公司图标
     3,选择"帮助"->"关于"命令,应看见相关版权和产品信息
  • Error -27728: Step download timeout (120 seconds)的解决方法(转)

    2009-07-03 14:58:45

    一个网友问了我一个问题如下:
    loadruner报错:Error -27728: Step download timeout (120 seconds) 如何解决
    语法检查通过,但是在并发执行一个查询时候报错Action.c(16): Error -27728: Step download timeout (120 seconds) has expired when downloading non-resource(s),请问有啥子解决方法,我使用web_set_timeout ,好象不起作用,直接在option中设置timeout时间为600,(单位应该是秒吧)还是没有起作用,结果都还是提示(120seconds),说明还是以120秒来判断的;使用lrs_set_recv_timeout,语法检查不过,说明库函数里面没有这个函数。

    尝试步骤:
    设置超时时间到600秒,回放还是出错。

    后来我设置了runt time setting中的internet protocol-preferences中的advaced区域有一个winlnet replay instead of sockets选项,选项后再回放就成功了。

    kernzhang解释如下(这里谢谢kernzhang,欢迎访问他的论坛:http://www.kernzhang.com)

    这个问题很有意思!呵呵!首先LR是通过Microsoft WinInet DLL去录制web协议的!但是在Control运行的时候它默认通过socket去模拟请求,因为这些可以真实的模拟带宽,而采用Microsoft WinInet DLL通过这个DLL去访问网卡方式去模拟带宽,使得模拟不是很精确!而且也不支持unix的应用,但是使用这个确实有时无法处理winnet Dll的一些请求,我认为是它的一些BUG,比如说:回放时它会检查Content-Length,但是网页支持receive more data时,这时socket模拟会一直等待直到timeout!

    先说了一些优缺点,最后回到这个问题!这个问题分两个方面分析:
    第一:你要明白web_set_timeout()这个函数的适用范围!比如说一个web_submit_data()中实际涵盖了10个对Server 端的请求,这个函数是针对10个请求的总和时间的!(别犯低级错误,timeout分了connect,receive以及download三个部分:) )
    第二:就是我解释的上面的一些BUG问题!
    WinInet dll在新版本中处理请求时可以异步的,就是不再是那种连接等待然后超时模式!但是LR用的socket是同步请求!只有等到timeout才会退出!microsoft已经明确表示INTERNET_OPTION_RECEIVE_TIMEOUT 不再适用于 Microsoft Internet Explorer 5.0,显而易见,他们处理请求采取了异步处理的方式!呵呵!这下大概可以圆满解释你的问题了!呵呵

    这里,我补充如下:
    VuGen专用的基于套接字的重播是一种可伸缩以便进行负载测试的轻型引擎。使用线程时是准确的。基于套接字的引擎不支持socks代理服务器。如果在这样的环境中录制,应该使用winInet重播引擎。

    欢迎大家继续讨论。
  • QTP日常详细函数库(转)

    2009-06-26 17:50:19

    '''以下为QuickTest和Robot都适用函数''''''''''''''''''''''''''''''''''
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    '获取当前日期
    Public Function Get_Data()
     Dim currentDate
     currentDate = Date
     Get_Data = currentDate
    End Function

    '获取当前时间
    Public Function Get_Time()
     Dim currentTime
     currentTime = Time
     Get_Time = currentTime
    End Function

    '随机函数生成
    '输入值:生成值范围 i~j
    '返回值:随机数
    Public Function Get_RandNum(fromNum,toNum)
     If (fromNum<0) Or (toNum<0) Then
      MsgBox "只接受大于零的输入"
     ElseIf fromNum>toNum then
      MsgBox "起始值必须小于结束值"
     Else
      Dim RunTime
      Randomize  
      RunTime = Int((10 * Rnd) + 1)
      Dim MyValue,i
      For i = 1 To RunTime
       Randomize 
       MyValue = Int(((toNum - fromNum + 1) * Rnd) + (fromNum))
      Next
        Get_randNum=MyValue
       End If
    End Function

    '值交换函数
    Public Sub swap(byref a,byref b)
     Dim c
     c = a
     a = b
     b = c
    End Sub

    '是否是质数函数
    '是质数返回true,否则返回false
    Function IsPrimeNumber(num)
     Dim i,flag
     flag = true
     If num = 1 Then
      flag = False
     ElseIf num < 1 Then
      MsgBox "只能接受大于0的数"
      flag = False
     Else
      For i = 2 To (num - 1)
       If ((num Mod i) = 0) Then
        flag = False
        Exit For
       End If
      Next
     End If
     IsPrimeNumber = flag
    End Function

    '读指定文本文件指定行内容
    Function ReadLine(pathway, rowcount)
     Dim fso,myfile,i,flag
     flag = 1
     Set fso=CreateObject("scripting.FileSystemObject")
     If fso.FileExists(pathway) then
      Set myfile = fso.openTextFile(pathway,1,false)
     Else
      flag = 0
     End If
     
     For i=1 to rowcount-1
      If Not myfile.AtEndOfLine Then
       myfile.SkipLine
      End If
     Next
     
     If flag = 1 then
      If Not myfile.AtEndOfLine Then
       ReadLine = myfile.ReadLine
      Else
       ReadLine = "文本越界"
      End If
      myfile.close
     Else
      ReadLine = "文件不存在"
     End If
    End Function

    '随机生成字符串
    Function MakeString(inputlength)
     Dim I,x,B,A
     If IsNumeric(inputlength) Then
     For I = 1 To inputlength
      A = Array("0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z")
      Randomize
      x=Get_RandNum(0,35)
      B = A(x)
      makestring =makestring +B
     Next
      MakeString = makestring
     else
      msgbox ("只接受数字输入")
     End If
    End Function

    '启动资源管理器
    Sub ZYGLQ()
     Dim WshShell
     set WshShell = CreateObject("Wscript.Shell")
     WshShell.SendKeys "^+{ESC}"
     Set WshShell = nothing
    End Sub

    '启动运行
    Sub Run()
     Dim WshShell
     set WshShell = CreateObject("Wscript.Shell")
     WshShell.SendKeys "^{ESC}R"
     Set WshShell = nothing
    End Sub

    '发送电子邮件
    Function SendMail(SendTo, Subject, Body, Attachment)
     Dim ol,mail
        Set l=CreateObject("Outlook.Application")
        Set Mail=ol.CreateItem(0)
        Mail.to=SendTo
        Mail.Subject=Subject
        Mail.Body=Body
        If (Attachment <> "") Then
            Mail.Attachments.Add(Attachment)
        End If
        Mail.Send
        ol.Quit
        Set Mail = Nothing
        Set l = Nothing
    End Function

    '去掉字符串中的重复项
    Function NoRepeat(Inp,Sp)
    Dim aa,flag,words,length,i,j,k,sp1,sp2,cc
     aa = Inp
     Do
      flag = False
      words = Split(aa,Sp)
      length = UBound(words)
      For i = 0 To (length -1)
       sp1 = words(i)
       For j = (i+1) To length
        sp2 = words(j)
        If sp1 = sp2 Then
         flag = True
         aa = ""
         For k = 0 To (j-1)
          aa = aa & words(k) & sp
         Next
         For k = (j + 1) To length
          aa = aa & words(k) & sp
         Next
        
         cc = Len(aa)
         aa = Left(aa,(cc - 1))
        End If
       Next
       If flag = True Then
        Exit For
       End if
      Next
     Loop Until flag = false
     NoRepeat = aa
    End Function

    '求字符串长度(中文算2个西文字符)
    Function GetLen(Str)
            Dim singleStr, i, iCount
            iCount = 0
            For i = 1 to len(Str)
                    singleStr = mid(Str,i,1)
                    If asc(singleStr) < 0 Then
                            iCount = iCount + 2
                    Else
                            iCount = iCount + 1
                    End If  
            Next
            GetLen = iCount
    End Function

    '运行指定程序
    Sub RunApp(command)
     Dim WshShell
     set WshShell = CreateObject("Wscript.Shell")
     WshShell.Exec command
    End Sub

    '求下一天是几号的函数
    Function Nextday(ByVal inputday)
        Dim temp, num, OPYear, OPMonth, OPDay, ret, flag
        temp = Split(CStr(inputday), "-")
        num = UBound(temp) + 1
        PYear = temp(0)
        PMonth = temp(1)
        PDay = temp(2)
        flag = 0

        If PMonth = 1 Or PMonth = 3 Or PMonth = 5 Or PMonth = 7 Or PMonth = 8 Or PMonth = 10 Or PMonth = 12 Then
            If OPDay > 31 Or OPDay < 1 Then
                flag = 1
            End If
        ElseIf PMonth = 4 Or PMonth = 6 Or PMonth = 9 Or PMonth = 11 Then
            If OPDay > 30 Or OPDay < 1 Then
                flag = 1
            End If
        Else
            If ISLeapYear(OPYear) Then
                If OPDay > 29 Or OPDay < 1 Then
                    flag = 1
                End If
            Else
                If OPDay > 28 Or OPDay < 1 Then
                    flag = 1
                End If
            End If
        End If

        If flag = 1 Or num <> 3 Then
            MsgBox "输入参数不对劲", , "Nextday函数提示"
        Else
            If PMonth = 1 Or PMonth = 3 Or PMonth = 5 Or PMonth = 7 Or PMonth = 8 Or PMonth = 10 Or PMonth = 12 Then 'big month
                If PDay = 31 Then
                    PDay = 1
                    If PMonth = 12 Then
                        PMonth = 1
                        PYear = OPYear + 1
                    Else
                        PMonth = OPMonth + 1
                        PYear = OPYear
                    End If
                Else
                    PDay = OPDay + 1
                End If
            ElseIf PMonth = 4 Or PMonth = 6 Or PMonth = 9 Or PMonth = 11 Then                                          'small month
                If PDay = 30 Then
                    PDay = 1
                    If PMonth = 12 Then
                        PMonth = 1
                        PYear = OPYear + 1
                    Else
                        PMonth = OPMonth + 1
                        PYear = OPYear
                    End If
                Else
                    PDay = OPDay + 1
                End If
            Else                                                                                                           'February
                If ISLeapYear(OPYear) Then
                    If PDay = 29 Then
                        PDay = 1
                        If PMonth = 12 Then
                            PMonth = 1
                            PYear = OPYear + 1
                        Else
                            PMonth = OPMonth + 1
                            PYear = OPYear
                        End If
                    Else
                        PDay = OPDay + 1
                    End If
                Else
                    If PDay = 28 Then
                        PDay = 1
                        If PMonth = 12 Then
                            PMonth = 1
                            PYear = OPYear + 1
                        Else
                            PMonth = OPMonth + 1
                            PYear = OPYear
                        End If
                    Else
                        PDay = OPDay + 1
                    End If
                End If
            End If
            ret = OPYear & "-" & OPMonth & "-" & OPDay
            Nextday = ret
        End If
    End Function

    '是否闰年
    Function ISLeapYear(ByVal inYear)
        If ((inYear Mod 4 = 0 And inYear Mod 100 <> 0) Or inYear Mod 400 = 0) Then
            ISLeapYear = True
        Else
            ISLeapYear = False
        End If
    End Function

    '计算两个日期之间相隔几天
    Function Days(ByVal SourceData, ByVal DesData)
        Dim flag, temp1, temp2, OPYear1, OPYear2, OPMonth1, OPMonth2, OPDay1, OPDay2, i, tempDay
        temp1 = Split(SourceData, "-")
        temp2 = Split(DesData, "-")
        If ((UBound(temp1) + 1) <> 3) Or ((UBound(temp2) + 1) <> 3) Then
            MsgBox "输入参数不对劲", , "Days函数提示"
        End If
        OPYear1 = temp1(0)
        OPMonth1 = temp1(1)
        OPDay1 = temp1(2)
        OPYear2 = temp2(0)
        OPMonth2 = temp2(1)
        OPDay2 = temp2(2)
        If CInt(OPYear1) <> CInt(OPYear2) Then
            If CInt(OPYear1) > CInt(OPYear2) Then
                flag = "big"
            ElseIf CInt(OPYear1) < CInt(OPYear2) Then
                flag = "small"
            End If
        Else
            If CInt(OPMonth1) <> CInt(OPMonth2) Then
                If CInt(OPMonth1) > CInt(OPMonth2) Then
                    flag = "big"
                ElseIf CInt(OPMonth1) < CInt(OPMonth2) Then
                    flag = "small"
                End If
            Else
                If CInt(OPDay1) <> CInt(OPDay2) Then
                    If CInt(OPDay1) > CInt(OPDay2) Then
                        flag = "big"
                    ElseIf CInt(OPDay1) < CInt(OPDay2) Then
                        flag = "small"
                    End If
                Else
                    flag = "="
                End If
            End If
        End If

        If (flag = "big") Then
            i = 1
            tempDay = DesData
            Do
                tempDay = Nextday(tempDay)
                i = i + 1
            Loop Until tempDay = SourceData
            i = i - 1
        ElseIf (flag = "small") Then
            i = 1
            tempDay = SourceData
            Do
                tempDay = Nextday(tempDay)
                i = i + 1
            Loop Until tempDay = DesData
            i = i - 1
        Else
            i = 0
        End If

        Days = i
    End Function

    '检查身份证号是否正确
    Function Identification(Text1)
    xian = Text1
    If (Not IsNumeric(Left(Text1, 15)) And Not IsNumeric(Left(Text1, 18))) Or Text1 = "" Then
      Identification = False
      Exit Function
    End If
    lenx = Len(Trim(Text1))
    If lenx = 15 Or lenx = 18 Then
        If lenx = 15 Then
            yy = "19" & Mid(xian, 7, 2)
            mm = Mid(xian, 9, 2)
            dd = Mid(xian, 11, 2)
            aa = Right(xian, 1)
        End If
        If lenx = 18 Then
            yy = Mid(xian, 7, 4)
            mm = Mid(xian, 11, 2)
            dd = Mid(xian, 13, 2)
            aa = Right(xian, 1)
        End If
        If CInt(mm) > 12 Or CInt(dd) > 31 Then
           Identification = False
           Exit Function
        Else
         Identification = True
         Exit Function
        End If
    Else
      Identification = False
      Exit Function
    End If
    End Function

    '检查是否存在数字
    Function checkString (myString)
     checkString = False
     Dim myChr
     For myChr = 48 to 57
      If InStr(myString,Chr(myChr)) > 0 Then
       checkString = True
       Exit Function
      End If
     Next
    End Function

    '查询Access数据库字符出现次数
    Function Access_GetCount(DBlocation,TableName,Value)
     set con=createobject("adodb.connection")
     con.open "DRIVER={Microsoft Access Driver (*.mdb)};DBQ=" & DBlocation
     set record = createobject("adodb.recordset")
     sql="select * from " & TableName
     
     record.open sql,con
     DO
      if(record("name")=Value)then
       num=num+1
      end If
      record.MoveNext
     loop until record.eof=True
     
     record.close
     set record=Nothing
     con.close
     set con=Nothing
     
     If num = 0 Then
      Access_GetCount = 0
     Else
      Access_GetCount = num
     End If
    End Function

    '按ASCII码值冒泡排序
    Function BubbleSort(VString,Spl,Func)
     Dim Str,StrLength,i,j
     Str = Split(VString,Spl)
     StrLength = UBound(Str) + 1
     For i = 1 To (StrLength-1)
      For j = (i+1) To StrLength
       If Func = 1 then
        If Asc(Str(i-1)) < Asc(Str(j-1)) Then
         Call Swap(Str(i-1),Str(j-1))
        End If
       Else
        If Asc(Str(i-1)) > Asc(Str(j-1)) Then
         Call Swap(Str(i-1),Str(j-1))
        End If
       End If
      Next
     Next
     j = ""
     For i = 1 To StrLength
      j = j & Str(i-1) & Spl
     Next
     j = Left(j,(StrLength * 2 -1))
     BubbleSort = j
    End Function


    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    '''以下为仅QuickTest适用函数'''''''''''''''''''''''''''''''''''''''''
    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

    '让QTP运行时保持最小化
    Public Sub QTP_Small()
     Dim objQTPWin
     Set bjQTPWin = GetObject("" , "QuickTest.Application")
     objQTPWin.WindowState = "Minimized"
     Set bjQTPWin = Nothing
    End Sub

    '恢复QTP窗口
    Public Sub QTP_Big()
     Dim objQTPWin
     Set bjQTPWin = GetObject("" , "QuickTest.Application")
     objQTPWin.WindowState = "Restored"
     Set bjQTPWin = Nothing
    End Sub

    '写文件函数(追加)
    '输入值:写入内容
    Public Function QTP_WriteFile(pathway,words)
        Dim fileSystemObj,fileSpec,logFile,way
        Set fileSystemObj = CreateObject("Scripting.FileSystemObject")
        fileSpec = pathway
        Set logFile = fileSystemObj.OpenTextFile(fileSpec, 8, true)
        logFile.WriteLine (CStr(words))
        logFile.Close
        Set logFile = Nothing
    End Function

    '写文件函数(改写)
    '输入值:写入内容
    Public Function QTP_WriteFile_Change(pathway,words)
        Dim fileSystemObj,fileSpec,logFile,way
        Set fileSystemObj = CreateObject("Scripting.FileSystemObject")
        fileSpec = pathway
        Set logFile = fileSystemObj.OpenTextFile(fileSpec, 2, true)
        logFile.WriteLine (CStr(words))
        logFile.Close
        Set logFile = Nothing
    End Function

    '读Excel文件元素
    Public Function QTP_Read_Excel(pathway,sheetname,x,y)
     Dim srcData,srcDoc,ret
     set srcData = CreateObject("Excel.Application")
     srcData.Visible = True
     set srcDoc = srcData.Workbooks.Open(pathway)
     srcDoc.Worksheets(sheetname).Activate
     ret = srcDoc.Worksheets(sheetname).Cells(x,y).value
     srcData.Workbooks.Close
     Window("text:=Microsoft Excel").Close
     QTP_Read_Excel = ret
    End Function

    '写Excel文件元素并保存退出
    Public Function QTP_Write_Excel(pathway,sheetname,x,y,content)
     Dim srcData,srcDoc,sp1,sp2,num,use,a1,a2,a3
     set srcData = CreateObject("Excel.Application")
     srcData.Visible = True
     set srcDoc = srcData.Workbooks.Open(pathway)
     srcDoc.Worksheets(sheetname).Activate
     srcDoc.Worksheets(sheetname).Cells(x,y).value = content
     
    ' sp1 = Split(pathway,".")
    ' sp2 = Split(sp1(0),"\")
    ' num = UBound(sp2)
    ' use = sp2(num)

    ' Set a1 = Description.Create()
    ' a1("text").value="Microsoft Excel - " + use + ".xls"
    ' a1("window id").value="0"

    ' Set a3 = Description.Create()
    ' a3("Class Name").value="WinObject"
    ' a3("text").value= use + ".xls"

    ' Window(a1).WinObject(a3).Type micCtrlDwn + "s" + micCtrlUp

     Dim WshShell
     Set WshShell=CreateObject("Wscript.Shell")
     WshShell.SendKeys "^s"
     wait(1)
     
     srcData.Workbooks.Close
     Set srcDoc = nothing
     
     Window("text:=Microsoft Excel").Close
    End Function

    '定时停留弹出框函数
    Sub QTP_Msgbox(Value,waitTime,Title)
     Dim WshShell
        Set WshShell = CreateObject("WScript.Shell")
        WshShell.Popup Value, waitTime, Title
        Set WshShell = nothing
    End Sub

    '改变Excel的单元格颜色
    Public Function QTP_Change_Color(pathway,sheetname,x,y,color)
     Dim srcData,srcDoc,sp1,sp2,num,use,a1,a2,a3
     set srcData = CreateObject("Excel.Application")
     srcData.Visible = True
     set srcDoc = srcData.Workbooks.Open(pathway)
     srcDoc.Worksheets(sheetname).Activate
     If color = "red" Then
      srcDoc.Worksheets(sheetname).Cells(x,y).Interior.color=vbred
     ElseIf color = "green" Then
      srcDoc.Worksheets(sheetname).Cells(x,y).Interior.color=vbgreen
     Else
      MsgBox "输入的颜色参数不正确,只接收""red""和""green"""
     End If

     Dim WshShell
     Set WshShell=CreateObject("Wscript.Shell")
     WshShell.SendKeys "^s"
     wait(1)
     
     srcData.Workbooks.Close
     Set srcDoc = nothing
     Window("text:=Microsoft Excel").Close
    End Function

    '捕获当前屏幕(截图)
    Public Function QTP_Capture(pathway)
      Dim datestamp
      Dim filename
      datestamp = Now()
      filename = Environment("TestName")&"_"&datestamp&".png"
      filename = Replace(filename,"/","")
      filename = Replace(filename,":","")
      filename = pathway + "\" + ""&filename
      Desktop.CaptureBitmap filename
      'Reporter.ReportEvent micFail,"image","<img src='" & filename & "'>"
    End Function

    '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    '''''QuickTestPlus 帮助文件对于Excel库函数  仅QTP适用''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    Dim ExcelApp 'As Excel.Application
    Dim excelSheet 'As Excel.worksheet
    Dim excelBook 'As Excel.workbook
    Dim fso 'As Scripting.FileSystemObject

    Function CreateExcel() 'As Excel.Application
        Dim excelSheet 'As Excel.worksheet
        Set ExcelApp = CreateObject("Excel.Application") 'Create a new excel Object
        ExcelApp.Workbooks.Add
        ExcelApp.Visible = True
        Set CreateExcel = ExcelApp
    End Function

    Sub CloseExcel(ExcelApp)
        Set excelSheet = ExcelApp.ActiveSheet
        Set excelBook = ExcelApp.ActiveWorkbook
        Set fso = CreateObject("Scripting.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

    Function SaveWorkbook(ExcelApp, workbookIdentifier, path) 'As String
        Dim workbook 'As Excel.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("Scripting.FileSystemObject")
                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 = 1
        Else
            SaveWorkbook = 0
        End If
    End Function

    Sub SetCellValue(excelSheet, row, column, value)
        On Error Resume Next
        excelSheet.Cells(row, column) = value
        On Error GoTo 0
    End Sub

    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

    Function GetSheet(ExcelApp, sheetIdentifier) 'As Excel.worksheet
        On Error Resume Next
        Set GetSheet = ExcelApp.Worksheets.Item(sheetIdentifier)
        On Error GoTo 0
    End Function

    Function InsertNewWorksheet(ExcelApp, workbookIdentifier, sheetName) 'As Excel.worksheet
        Dim workbook 'As Excel.workbook
        Dim worksheet 'As Excel.worksheet
        'In case that the workbookIdentifier is empty we will work on the active workbook
        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)
        If sheetName <> "" Then
            worksheet.Name = sheetName
        End If
        Set InsertNewWorksheet = worksheet
    End Function

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

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


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

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

    Function CompareSheets(sheet1, sheet2, startColumn, numberOfColumns, startRow, numberOfRows, trimed) 'As Boolean
        Dim returnVal 'As Boolean
        returnVal = True
        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)
                If trimed Then
                    Value1 = Trim(Value1)
                    Value2 = Trim(Value2)
                End If
                If Value1 <> Value2 Then
                    Dim cell 'As Excel.Range
                    sheet2.Cells(r, c) = "Compare conflict - Value was '" & Value2 & "', Expected value is '" & Value1 & "'."
                    Set cell = sheet2.Cells(r, c)
                    cell.Font.Color = vbRed
                    returnVal = False
                End If
            Next
        Next
        CompareSheets = returnVal
    End Function

    '写入word文件
    Sub QTP_WriteWord(pathway,content)
     Dim oWord,oRange,oDoc
     Set Word = CreateObject("Word.Application")
     oWord.documents.open pathway,forwriting, True
     Set Doc = oWord.ActiveDocument
     Set Range = oDoc.content
     oRange.insertafter content
     oWord.ActiveDocument.Save
    ' Dim WshShell
    ' Set WshShell=CreateObject("Wscript.Shell")
    ' WshShell.SendKeys "^s"
    ' wait(1)
        oWord.Application.Quit True
     Set Range = Nothing
     Set Doc = Nothing
     Set Word = Nothing
    End Sub

     

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/daisyysiad/archive/2009/05/05/4152699.aspx

  • QTP Excel函数(转)

    2009-06-26 17:45:11

    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")
    ' *********************************************************************************************

    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

  • QTP参考代码框架(转)

    2009-06-26 17:39:56

    Dim logdata,sou,ExpectedResult1,ExpectedResult2,ExpectedResult3,ExpectedResult4,ExpectedResult5,ExpectedResult6
    sou="F:\work\protocol\bintext\bin\_Debug.log"                                                                                                                              'log文件地址自己填加
    '--------------------
    Function readlog(sou)
    Dim fso,f1,f2
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set f1 = fso.OpenTextFile(sou)
    f2 = f1.ReadAll
    f1.close
    readlog=f2
    End Function
    '-----------------------------------------------------------
    Function getdata(x,y)
    getdata = CStr(ExcelSheet1.Cells(x, y))
    End Function
    '---------------------------------------------------------------------------
    Function savedata(x,y,z)
    ExcelSheet.ActiveSheet.Cells(x,y).Value =z
    End Function
    '-------------------------------------------------------------
    Sub over()
     Set shell = Nothing
    Set Shell = Nothing
    Set ExcelSheet = Nothing
    Set ExcelSheet1 = Nothing
    ''Excel.Application.Quit
    'ExcelSheet.Application.Quit
    End Sub
    '-----------------------------------------------------------
    Dim Excel,ExcelSheet,ExcelSheet1,ExcelSheet2
    Set Excel=CreateObject("Excel.Application")
    Set ExcelSheet = Excel.Workbooks.Open("F:\work\protocol\qtp\协议测试数据驱动表.xls")        '驱动表格地址自己添加
    Set ExcelSheet1= ExcelSheet.Worksheets("测试数据")
    ExcelSheet.Application.Visible = True
    '------------------------------
    Dim oShell,shell,black
    SystemUtil.Run "F:\work\protocol\bintext\bin\test.bat","","F:\work\protocol\bintext\bin\" ,"open"  
    '测试程序路径和QTP工作路径自己填加修改
    Set shell=createobject("Wscript.shell")
    '----------------------------------------------------------
    '登陆过程
    Sub login(userx,usery,pwdx,pwdy,resultx,resulty,savex,savey)  
    shell.sendkeys "login:" & getdata(userx,usery) & "," & getdata(pwdx,pwdy) & ",5222 {enter}"
    ExpectedResult1 = getdata(resultx,resulty)
    logdata = readlog(sou)
    If InStr(logdata, ExpectedResult1) Then
    call savedata(savex,savey,"PASS")
    Else
    call savedata(savex,savey,"FAIL")
    End If
    End Sub
    '-------------------------------------------------------------
    '   shell.sendkeys 作用是在cmd中输入字符串  如下
    '预期结果--可以有任意多的预期结果,变量在顶部填加。
    '   getdata(x,y)      用来从表格取数据  x为横向列数  y为纵向列数
    '   savedata(x,y)   用来把数据记录到表格中  x为横向列数  y为纵向列数
    '检查 --  每次检查预期结果的时候需要从log中取得数据   logdata = readlog(sou)   的作用就是从输入的路径取log数据
    '--------------------------------------------------------------------------------------
    '函数表
    '           login(userx,usery,pwdx,pwdy,resultx,resulty,savex,savey)          userx 表示用户名在excel上的横坐标,usery表示用户名在excel上的纵坐标,依次类推
    '  其他函数过程自己写

     


    '-------------------------------------------------------------------------------------

    Call login(5,6,5,7,5,12,5,16)    '举例

     


    Call over()

  • Database Query

    2009-06-19 15:53:41

        几乎没怎么用QTP自带的数据库检查点方法,一般是conn = createobject("ADODB.Connection")这样的方式,取出的数值与界面的数据进行比对。今天看了一个帖子,是关于使用Database Query 方式进行数据库检查的。因为从未使用过这种方式,于是想把自己的操作记录下来。 
       方法一. 首先,点击控制面板,在数据源中设置数据源,在选择数据库类型后,显示
      

      在Data Source Name中写入数据源名字,可任意取,最好取名有意思,有益于识别, TNS Service Name 中选择在oracle中设置的网络服务名,测试连接成功后,建立数据源成功,然后在Database Query Wizard选择该数据源。


      方法二. 在QTP中插入数据库检查点,打开Database Query Wizard对话框

    点击next,进入选择数据源页面(注意:中间有跳步)

    建立新数据源,在数据源名称中输入数据源名称,选择数据库的驱动程序,如下图:

    在Service Name 中输入要连接的网络服务名,输入账号和密码,连接成功。

    下面的步骤在学习后,继续写。

    晕倒,用这种方法选择表的时候有点麻烦,比较起来还是用SQL快,不过对于大批量数据比对还是有帮助的。

  • 细说LoadRunner参数化(转)

    2009-06-18 10:53:35

    前言:为什么这里说是细说LoadRunner参数化,在书和网上到处都能找到关于LoadRunner参数化的内容,但是细心的读者不能难发现,虽然现在很多资料都有关于参数化的内容,但写的都不够详细,对于初学者来说是一件很困难的事,而参数化又是编辑脚本最重要的一部分之一,没有学好参数化就不能算是一名合格的性能测试工程师,因此,在这里我将自己理解的关于参数化的内容写出来和初学者共享,希望这份资料对大家学好参数化部分的知识有帮助。

    首先:为什么要对脚本进行参数化

    a)         为了减少脚本的大小和脚本数量,借助参数化我们可以减少脚本的数量,如果不进行参数化我们为了达到目标可能要拷贝并修改很多个脚本。

    b)        使业务更接近其实的客户的业务,每个虚拟用户使用不同参数值来模拟这样才接近客户的实际情况。

    第二:怎么进行参数化

    首先在这里先声明一下,下面所有使用的例子都是录制LoadRunner中自带的的那个例子的注册过程。


    这里包括两部分的部分:

    a)         编辑脚本,使用参数代替常量;

    b)        设置参数的属性和数据源;

    那么如何进行参数化呢?选中要参数化的内容点右键­->Replace with a parameter(如下图)。输入参数化的名称,假设为password。

     

    这时要我们要注意的一个问题是,当参数化结束后,脚本保存的根目录下会多出一个参数化的文件,

     

    接下来的工作就是将参数化文件合并,这里只有两个参数化文件,合不合并可能不会有多大影响,但是如果当有多个参数化文件并且每个文件都占很大空间时,

    图中多出两个参数化的文件(pw和user)就是刚才对两个数进行参数化后的文本文件,当然一般的情况下不要将这个参数化的文件放到脚本的目录下,而应该是放到一个专门的文件下,这样可以保证参数化文件与脚本分离,如我们新建一个文件夹parameter,将所有参数化的文本文件都放到这个文件夹下。

     

    这里我们只是两个参数化文件,那么当有很多参数化文件怎么办呢,因为当一个项目很大时,其录制的业务很多时,参数化文件会很多,甚至上几百MB时,这时为了方便管理参数化文件和节约空间我们会对参数化文件进行合并到一个文件夹中,如果上面两个参数化文件就可以合并,参数化之间用逗号隔开即可,如下图合并好后的参数化文件。

     

     

    再看一下参数化的属性:

    a)        参数类型属性:

    1.         "Date/Time"(日期/时间)参数类型:

    "Date/Time"类型用当前的日期和/或时间替换参数。要指定日期/时间的格式,可以从菜单列表中选择,或者指定实际需要的格式。该格式应该与脚本中录制的日期/时间格式相对应。还可以单击该对话框中相应的按钮对格式进行添加、删除、还原等操作。

    2.         "Group Name"(组名)参数类型:

    用Vuser组的名称替换参数。创建方案时,要指定Vuser组的名称,否则运行VuGen的脚本时,组名始终为"无"。但在VuGen中运行时,Group Name将会是None。

    3.         "Iteration Number"(迭代编号)参数类型:用当前的迭代编号替换参数。

    4.         "Load Generator Name"(负载生成器名)参数类型:用Vuser脚本的负载生成器名替换参数。负载生成器是运行Vuser的计算机。

    5.         "Random Number"(随机编号)参数类型:用一个随机生成的整数替换参数,可以通过指定最小和最大值,设置随机编号的范围。

    6.         "Unique Number"(唯一编号)参数类型:用一个唯一编号替换参数。"Block size"(块大小)指明分配给每个Vuser的编号块的大小。每个Vuser都从其范围的下限(start)开始,在每次迭代时递增该参数值。

    7.         "Vuser ID"参数类型:LoadRunner使用该虚拟用户的ID来代替参数值,该ID是由Controller来控制。在VuGen中运行脚本时,VuGen将会是-1。

    8.         File参数类型:可以在参数属性中编辑参数文件,也可以直接编辑好参数文件通过路径来选择,还有从现成的数据库中提取。这是参数化最常的一种参数类型。

    b)        Browse属性:

    这里是用来选择参数文件的路径,这里要注意的一个问题是,一般我们在做参数化的时候没有单独把参数文件放到一个文件夹下,所以一般我们都没有更改过这块,但我们上面已经讲过,一般都会将参数化文件合并到一个文件下并放到一个专门管理参数的文件夹下,这样我说就要选择参数的路径,否则无法读到参数文件中的参数,具体的如下图。

     

    选择好之后,会列出参数化文件中所有的项,如下图:


    注意:读者可能会发现,这样如果我们换一个把这个脚本拷贝到另外一台机器上去这个路径不就出错了吗?也就是我们的脚本可移植性不好,对是的,会出错,因为这里写的是绝对路径,如果换到其它的一个盘或机器,运行就报错了,那么怎么解决这个问题?这里我们采用相对路径来解决这个问题,这是我们Browse设置为相对路径,将脚本的根目录使用“。“来代替。见下图,这样就不会出错了。


    这样就解决了上面的那个问题,具体更好的可移植性了。

    c)         导入数据方法:

    LoadRunner允许使用Microsoft Query或者指定数据库连接字符串与SQL语句,利用参数化从已存在的数据库中导入数据。在这里这两种导入数据的方法的区别在于使用Microsoft Query时,不要新建数据源,在导入向导过程中直接连接数据库,而手动指定数据库字符器,需要先做好数据源,现在一般都使用这种方法。

    下面我们来看一下使用Data Wizard中的Specify SQL statement manually如何导入数据库中的数据。

    首先建立一个数据源,在这里我个做一个数据源,名称为LR,点击Data Wizard按钮,选择使用SQL语句(如下图)。


    接下来是选择数据源和写SQL语句(如下图)。


    连接成功后,数据将会被成功的导入,下面我们看一下数据库中数据被导入到的情况。


    d)        Select next now属性:

    注意:这里要注意的是所有的Select next now属性选择是针对虚拟用户来说的,也就是这里的策略是针对Controller设置的,在调试脚本的过程中是看不出来的,其决定虚拟用户如何选择参数的过程。

    Ø         Sequential:虚拟用户Vuser按照行顺序的进行读取参数文件中的数据,如果参数文件中没有足够的数据,则返回到第一个值,并一直循环到结束。

    例:如上图我们这里有arivn01到arivn07七个数据,假设我们有10个Vuser,那么第1个Vuser读到的参数为arivn01,于此类推,到第8个Vuser的时候,这里表中已经没有数据了,于是又从第一个数据开始读取,故第8个Vuser读到的数据是arivn01,第9个Vuser读到的数据是arivn02。

    Ø         Random:每个Vuser从表中随机的读起参数数据,假设有50个数据,那么随机数

    将在1~50之间随机取一个,然后把这个数做为行号,去读取相应行的参数数据。

    Ø         Unique:唯一的数,即每个Vuser取到的参数均不一致,这里强调了用户的差异性。

    Ø         Same link as ***:如果一个脚本中定义了多个参数,而有一些参数应该是对应的关系,如上图中的用户名和密码就是对应关系,即密码应该始终和用户名对,这时就要用到这个选项。

    e)        Update value on属性:

    注意:这里设置的策略是针对脚本的迭代来讲的,也就是说这里的一切策略其仅仅在脚本迭代次数发挥作用,而对Vuser选择参数没有影响。

    Ø         Each iteration:脚本每迭代一次都访问数据表中的下一个值。

    注意:如果在一次迭代过程中,某个参数使用到两次,如下图这个例子中,在一次迭代中使用到两次用户名和密码,这两次使用的同一个数据,而并不是两个数据。


    下面我们来看一下编辑的结果

    第一次迭代使用表中数据的结果

     

    再看第二次迭代使用表中数据的结果

    Ø         Each occurrence:参数在每次迭代的过程中,参数的值都的更新。

    注意:如果一个参数在一次迭代过程中出现多次,在同一次迭代过程中也得更新,下面同样看这个例子,其迭代的结果。


    Ø         Once:在同一个Vuser中一直取同一个参数,表中的数据不参于迭代的过程。

    还是看我们上面的例子的结果:


    到这里参数化的过程已经全部讲完,这里总结一下,参数化过程中要注意的问题:

    1)        参数化文件尽可能少,因为参数是放在内存中的,占用了内存的资源;

    2)        参数化文件与脚本分离;

    3)        参数文件的路径应该以相对路径来取;

    4)        一些时候为了使参数更具有真实性,参数应该从数据库中来获得;

    5)        参数类型的选择;

    6)        参数的数据一般要由业务决定;

    后记:参数化到这里已经彻底讲完了,主要涉及的内容是:

    1)        为什么要进行参数化;

    2)        如何进行参数化;

    3)        参数化过程中要注意那些问题:

Open Toolbar