问题
I'm writing a robust Word macro that will be used on wide range of Words on several different machines.
I have red on many expert VBA forums, that early binding is always preferred to late binding, as being far superior in performance, etc.
For my logic it feels so however -unless benefits are proven convincingly-, that the exact opposite applies in terms of usability, because i don't want the pain of assuring those lib-references ticked on all machines it might run on.
I have experimented with ThisWorkbook.VBProject.References.AddFromGUID "{420B2830-E718-11CF-893D-00A0C9054228}", 1, 0
. It would add the reference programatically, BUT it then needs the Security trust to be enabled on the machine for code manipulation.
So then i have set up a test to compare 1000 runs of early vs late bindt Dictionary operations. I have played around with other test settings also, like ScreenUpdating, DoEvents, Debug.Print to see the performance impact of each.
So far what i see is that Early vs Late binding itself had NO measurable performance difference in any setup (except a 10% random fluctuation between any runs).
VBA Guru-s I'm interested in your catch on this story, why should i use Early binding then, or is it really such an advantage in REAL LIFE USAGE.
My TestCode was this:
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
回答1:
Not sure this should go as answer but hey,
Early binding is preferred for development work (speed and intellisense). Late binding is frequently used for distribution for exactly the reasons you mention. Far safer to go with Late binding in production unless you can be absolutely 100% certain of your users set-ups.
To quote from the Word MVP website
Advantages of Early Binding
Your code will run considerably faster, because it can all be compiled up front. With late binding, the code relating to an application you declared as an object has to, in effect, be compiled as it runs.
Because your code can all be compiled up front, debugging is far easier – select Debug + Compile, and the compiler will be able to spot syntax errors which would have been missed had you used late binding.
You have full access in your project to intellisense (type a keyword and a dot to get a popup list of properties and methods supported by that keyword, select one to insert it; type a keyword and press F1 to launch the Help topic on that keyword).
You have full access to the application's object model via the Object Browser and VBA Help.
You have access to the application's built-in constants. For instance, if you are automating Word from Excel, you can use:
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
Furthermore, when you type
.WindowState =
you'll get a pop-up list of the supported constants, and can simply pick wdWindowStateMaximize
from the list.
If you used late binding, you would need to use:
.WindowState = 1
.. and you would need to know (by looking it up in Word's Object Browser) that the value of the constant "wdWindowStateMaximize"
happens to be 1.
All this makes programming using early binding immeasurably easier than using late binding.
Advantages of Late Binding
The main advantage is that code which uses late binding is more certain to be version-independent
If you set a reference in a Word 97 project to “Microsoft Excel 8.0 Object Library”, then the project will run OK on a machine which has Office 2000 installed. Word 2000 changes the reference on the fly to the “Microsoft Excel 9.0 Object Library”.
But as they famously say, YMMV. Problems have been found in certain circumstances. For instance, if you run a Word 97 project containing a reference to the Excel 8.0 object library on a machine with Office 2000 installed, it will run OK, but you may get the occasional “cannot open macro storage” error unless you save the project in Word 2000. If you do save it in Word 2000, the reference will change to the Excel 9.0 object library.
So if you use early binding and support a mixed environment, it may be safest to create separate Word 97 and Word 2000 versions of your addins, despite the maintenance overhead.
The more references your project contains, the larger the file size and the longer it takes to compile.
Some programming environments don't allow you to create references to another application.
If you really want to start delving into COM objects, v-tables and the like maybe start with the following reference:
References:
- Microsoft Blurb: Using early binding and late binding in Automation
来源:https://stackoverflow.com/questions/49789611/vba-early-vs-late-binding-real-life-performance-differences