为什么从标准模块(而不是用户表单)调用时VBA代码运行得更快?

时间:2017-07-26 11:45:29

标签: vba excel-vba word-vba excel

备用标题:为什么按 Esc 使我的MS-Word宏运行得更快

在等待某些代码运行的过程中,我偶然发现了一些有趣的事情。

代码运行缓慢...按 Esc 代码运行速度很快。例如:

  • 执行后立即按 Esc - 2秒完成
  • 根本不要按 Esc - 最多 30秒才能完成

对我来说这毫无意义。事实证明其他人已经注意到类似的行为,例如:

他们找到了各种解决方案或解决方法。 然而,这些帖子适用于MS-Excel;它似乎对 Esc 键有不同的行为。

In MS-Excel pressing the Esc key可以(取决于Application.EnableCancleKey的设置)中断代码或引发错误(Err 18),或什么都不做。另一方面, in MS Word no such thing happens ,而不是Application.EnableCancleKey改变 Ctrl + Pause 的行为。尽管如此,按 Esc 会大大加快代码执行速度。

除了这个区别之外,我的问题更多地与用户表单中的代码放置有关。例如,在我的Userform中:

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

我应该注意以下几点:

  1. 这在64位版本的MS Word中最为明显,32位版本似乎与原始代码运行得相当快(我还没有用修改后的代码进行测试)
  2. 与第一个链接中的作者一样,我没有使用选择对象等。
  3. 我更感兴趣的是有关为什么代码执行速度受以下因素影响的原因:
    • Esc
    • 将来自用户表单的调用移至标准模块
  4. Macro1,Macro2& Macro3创建和编辑文档样式,(FWIW)涉及多次读取INI文件
  5. 在旁注 上,我试图使用sendKeys来发送 Esc 键,但是它有一个聪明的尝试没有影响。

    编辑 - 代码计时结果:

    我最终使用计时器函数来计算代码的时间,我已经实现了一个从这里改编的堆栈类: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++

    由于计时器与调用堆栈一起工作的方式,我必须测试代码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 之后运行得更快但是它确实与修改样式有关... < / p>

1 个答案:

答案 0 :(得分:0)

只需在@Florent Bs上发表评论,您是否尝试过在点击事件中运行宏之前可以禁用哪些内容?像

这样的事情
Application.EnableEvents = False
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual

'code
Module1.Macro1
Module1.Macro2
Module1.Macro3

Application.EnableEvents = True
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic

只是为了看看事情是否更快?可能还有其他命令可以取消人们可以添加的其他内容。