【问题标题】:VBA Early vs Late binding - real life performance differencesVBA Early vs Late binding - 现实生活中的性能差异
【发布时间】:2023-03-09 12:30:01
【问题描述】:

我正在编写一个强大的 Word 宏,该宏将用于几台不同机器上的各种单词。
我在许多 VBA 专家论坛上阅读过,就性能而言,早期绑定总是比后期绑定更受欢迎。

然而,就我的逻辑而言,它感觉如此 - 除非令人信服地证明了好处 - 在可用性方面正好相反,因为我不希望确保在它可能运行的所有机器上勾选这些库引用的痛苦。

我已经尝试过 `ThisWorkbook.VBProject.References.AddFromGUID "{420B2830-E718-11CF-893D-00A0C9054228}", 1, 0`。它将以编程方式添加引用,但随后需要在机器上启用安全信任以进行代码操作。
因此,我设置了一个测试来比较 1000 次早期和晚期 bindt 字典操作的运行。我也尝试过其他测试设置,例如 ScreenUpdating、DoEvents、Debug.Print,以查看每个设置的性能影响。
到目前为止,我看到的是,早期绑定与后期绑定本身在任何设置中都没有可测量的性能差异(任何运行之间的随机波动除外 10%)。
VBA Guru-s 我对您对这个故事的了解很感兴趣,那我为什么要使用早期绑定,或者它在现实生活中真的有这样的优势。

我的测试代码是这样的:
Sub HeadingDefinitionWords_test()
    Application.ScreenUpdating = False
    Dim tm As Long
    tm = timeGetTime
    Dim DefinitionRangeBackup As Range, DefinitionRange As Range
    Dim kEy As Variant, i As Long, k As Integer
    Dim TempList As Object: Set TempList = CreateObject("Scripting.Dictionary")
    'Dim TempList As Scripting.Dictionary: Set TempList = New Scripting.Dictionary
    For i = 1 To 1000
    'Call HeadingDefinitionWords(Selection.Range.Duplicate, TempList)
    '''
         Set DefinitionRange = Selection.Range.Duplicate
         Set DefinitionRangeBackup = DefinitionRange.Duplicate
         '-
            With DefinitionRange.Find: .ClearFormatting: .Text = "([a-z])([A-Z])"
                .Forward = True: .Wrap = wdFindStop: .Format = False: .MatchCase = False: .MatchWholeWord = False: .MatchAllWordForms = False
                .MatchSoundsLike = False: .MatchWildcards = True
            End With
        '-
            With DefinitionRange: While .Find.Execute And .InRange(DefinitionRangeBackup)
            '-
                .Expand Unit:=wdWord
            '-
                If Not TempList.Exists(Trim(DefinitionRange.Text)) Then TempList.Add Trim(DefinitionRange.Text), Trim(DefinitionRange.Text)
            '-
                DefinitionRange.Collapse wdCollapseEnd
            Wend: End With
        
        '''
        For Each kEy In TempList
            'Debug.Print kEy
            If k = 50 Then
                'Debug.Print k
                k = 1
            Else
                k = k + 1
            End If
            'DoEvents
        Next
    
    Next
    
    Dim tma As Long
    tma = timeGetTime
    Debug.Print tma - tm
    
    Application.ScreenUpdating = True
End Sub

【问题讨论】:

  • 与其他操作的成本相比,在您的示例中调用字典的成本微不足道。这就是为什么您在早期绑定和后期绑定之间没有任何区别。

标签: vba performance binding ms-word


【解决方案1】:

不确定这应该作为答案,但是嘿,

早期绑定是开发工作的首选(速度和智能感知)。正是由于您提到的原因,后期绑定经常用于分发。除非您可以绝对 100% 确定您的用户设置,否则在生产中使用后期绑定要安全得多。

引用Word MVP website

早期绑定的优势

您的代码将运行得更快,因为它都可以预先编译。使用后期绑定,与您声明为对象的应用程序相关的代码实际上必须在运行时进行编译。

因为您的代码都可以预先编译,所以调试要容易得多 - 选择 Debug + Compile,编译器将能够发现如果您使用后期绑定可能会遗漏的语法错误。

您可以在项目中完全访问智能感知(键入关键字和点以获取该关键字支持的属性和方法的弹出列表,选择一个插入它;键入关键字并按 F1 启动帮助主题在那个关键字上)。

您可以通过对象浏览器和 VBA 帮助完全访问应用程序的对象模型。

您可以访问应用程序的内置常量。例如,如果您要从 Excel 自动化 Word,您可以使用:

Dim objWord As Word.Application 
Set objWord = New Word.Application 

With objWord 
    .Visible = True 
    .Activate 
    .WindowState = wdWindowStateMaximize 
    .Documents.Open ("c:\temp\temp.doc") 
End With 

此外,当您键入时

.WindowState =

您将获得支持的常量的弹出列表,并且可以简单地从列表中选择wdWindowStateMaximize

如果您使用后期绑定,则需要使用:

.WindowState = 1

.. 你需要知道(通过在 Word 的对象浏览器中查找)常量 "wdWindowStateMaximize" 的值恰好是 1。

所有这些都使得使用早期绑定的编程比使用后期绑定更容易。

后期绑定的优点

主要优点是使用后期绑定的代码更确定是版本无关的

如果您在 Word 97 项目中将引用设置为“Microsoft Excel 8.0 对象库”,则该项目将在安装了 Office 2000 的计算机上正常运行。 Word 2000 动态地将引用更改为“Microsoft Excel 9.0 对象库”。

但正如他们所说的那样,YMMV。在某些情况下发现了问题。例如,如果您在安装了 Office 2000 的计算机上运行包含对 Excel 8.0 对象库的引用的 Word 97 项目,它会运行正常,但除非您保存项目,否则您可能偶尔会收到“无法打开宏存储”错误在 Word 2000 中。如果您将其保存在 Word 2000 中,则引用将更改为 Excel 9.0 对象库。

因此,如果您使用早期绑定并支持混合环境,那么创建单独的 Word 97 和 Word 2000 版本的插件可能是最安全的,尽管会产生维护开销。

您的项目包含的引用越多,文件越大,编译时间就越长。

某些编程环境不允许您创建对另一个应用程序的引用。

如果您真的想开始深入研究 COM 对象、v-tables 等,可以从以下参考开始:

参考资料:

  1. 微软简介:Using early binding and late binding in Automation

【讨论】:

  • 感谢您的快速回答。我认为这很有用。我会等几天看看有没有其他的 cmets 到货,这会改变我们的看法,否则我会把你的作为解决方案。
  • 感谢您提供的其他信息,我基本上同意这一点,除了“您的代码将运行得更快”部分,因为我上面的测试并没有证明这一点。 (已授予解决方案)
猜你喜欢
  • 2022-12-01
  • 1970-01-01
  • 2015-09-30
  • 2019-02-09
  • 2017-07-09
  • 2019-04-21
  • 2010-10-15
  • 2018-09-28
  • 2012-01-03
相关资源
最近更新 更多