我们时常需要一个计时器来记录一段代码的运行时间,而 VBA 的 Time 函数只能精确到秒,精度不够。Windows 操作系统提供了两个函数用来进行高精度的计时,这两个函数分别是 QueryPerformanceCounter 和 QueryPerformanceFrequency。QueryPerformanceCounter 的函数原型为:BOOL QueryPerformanceCounter(LARGE_INTEGER *lpCounter);
这个函数用来获取当前的时钟滴答计数(ticks),返回值在 lpCounter。如果函数成功,则返回非零值,否则返回零值。QueryPerformanceFrequency 的函数原型为:BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);
这个函数用来获取当前的时钟频率(每秒钟滴答多少次),返回值在 lpFrequency 中。如果函数成功,则返回非零值,否则返回零值。用来构造计时器的思路是:在代码开始前调用 QueryPerformanceCount 来获取开始时的时钟滴答数,在代码结束后再调用调用 QueryPerformanceCount 来获取结束时的时钟滴答数,两数相减,再除以时钟频率,则是代码的执行时间(秒)。我们可以在 VBA 中创建一个类模块 Stopwatch,来封装以上介绍的两个函数,并通过 Start、Stop、ElapsedTime 来呈现这个类模块的接口。首先是以上函数在 VBA 中的声明,以及用来保存信息的变量:QueryPerformanceCounter 和 QueryPerformanceFrequency 都要求传入的参数是 LARGE_INTEGER 类型,也就是 64 位整型。64 位的 VBA 定义了 LongLong 类型,对应于 LARGE_INTEGER,但 32 位的 VBA 中没有这个类型,不过可以用 Currency 代替,这也是一种 64 位的类型。以上的声明中,llStartCounter 用来记录开始时的滴答数,llStopCounter 用来记录结束时的滴答数,llFrequency 用来记录时钟的频率。- ElapsedTime:首先获取时钟的频率(每秒钟的滴答数),将结束时的滴答数减去开始时的滴答数,再除以每秒钟的滴答数,就是所经历的时间(以秒为单位),乘以 1000 就是毫秒(Milliseconds)。
Dim sw As New Stopwatchsw.StartWatcher' 需要计时的代码段sw.StopWatcherMsgBox sw.ElapsedTime