替代标题:为什么按下Esc键会使我的MS-Word宏运行更快
在等待代码运行时,我发现了一些有趣的事情。
代码运行缓慢...按下Esc键代码运行得很快。例如:
- 执行后立即按下Esc键-完成需要2秒钟
- 根本不按Esc键-最多需要30秒钟才能完成
对我来说这毫无意义。事实证明其他人也注意到了类似的行为,例如:
他们发现了各种解决方案或解决方法。然而,这些帖子是针对MS-Excel的;似乎Esc键有不同的行为。
在MS-Excel中按下Esc键可以(取决于Application.EnableCancleKey的设置)中断代码或引发错误(Err 18),或者什么也不做。另一方面,在MS Word中没有这样的事情发生,相反,Application.EnableCancleKey改变了Ctrl+Pause的行为。尽管如此,按下Esc可以显著加速代码执行。
除了这个差异,我的问题更多地涉及将代码放置在用户窗体中。例如,在我的用户窗体中:
Private Sub Cmd_Click()
Module1.Macro1
Module1.Macro2
Module1.Macro3
End Sub
经测试,使用上述结构,在64位版本的Word 2010上运行速度显著较慢。相比之下,以下结构速度更快:
用户窗体:
Private Sub Cmd_Click()
Module1.RunMacro123
End Sub
标准模块:
Private Sub RunMacro123()
Module1.Macro1
Module1.Macro2
Module1.Macro3
End Sub
需要注意的是:
- 在MS Word 64位版本中,这一点最为明显,32位版本使用原始代码似乎运行得相当快(我还没有测试修订后的代码)。
- 和第一个链接中的作者一样,我没有使用选择对象等。
- 我更感兴趣的是关于代码执行速度为什么如此受以下因素影响的任何见解:
- 按下Esc键
- 将调用从用户窗体移动到标准模块
- Macro1、Macro2和Macro3创建和编辑文档样式,并且(FWIW)涉及多次读取INI文件。
附注:在一个毛脑袋的尝试中,我试图使用sendKeys发送Esc键,但它没有任何作用。
编辑-代码计时结果:
最终,我使用timer函数来计时代码,我已经实现了一个堆栈类,该类是从这里改编而来:http://www.tek-tips.com/viewthread.cfm?qid=1468970
我在函数调用堆栈中添加了一个“绝对”计时器(debug.print timer - startTime
),以便记录每次推送之间的时间并在每次弹出时重置计时器(startTime = timer
)。这样做可以使比较时间更容易在NotePad++中进行。
这使我能够确定将样式应用于文档的子过程花费了大约0.04秒来应用样式(NB计时器返回的值=午夜过去的秒数)。
下面的图像显示了代码计时结果的示例。基本上,据我所知,代码执行的延迟来自许多与同一基本任务相关的增量延迟。
![Comparing code execution times in NotePad++](https://istack.dev59.com/c6rBI.webp)
由于计时器与函数调用堆栈的工作方式,我不得不测试代码getStyleElement
以确保它没有对额外时间产生显著贡献。我通过直接计时代码来完成这个测试,并确认其运行速度一直很快。
检查剩余的代码证实问题出现在applyStyleFormat
(调用getStyleElement
)中。
样式被应用于文档——代码结构包括With块和For循环;类似于这样:
For i = 1 to Styles.Count
With aDocument.Styles(i)
.Font.??? = Something
' or .Paragraph.??? = Something
End With
Next i
我仍不清楚为什么代码在用户窗体外部运行得更快,或者在按下Esc后运行得更快,但它确实有些与修改样式相关的东西……
Debug.print Now [代码位置]
更简单且足够了。它只需要几秒钟就能完成。 - Thomas G