In a previous article, I wrote about how COM is like a Chinese restaurant.
A programming object written in one language (say, C++) can be called from a different language (say, VBA) because the two languages agree on a common interface. VBA can call the functions in the C++ object one of two basic ways:
- Early Binding: Faster and Safer (compile-time checks)
- Late Binding: More Flexible and Forgiving (run-time lookups)
Let's expand the Chinese restaurant metaphor to illustrate these two approaches.
Early Binding: Order From the Menu
In our scenario, the customer speaks only English while the chef speaks mostly Chinese, but does understand English numbers.
How do these two communicate? First, the chef puts together a numbered menu with meal descriptions in both Chinese and English. With a copy of the menu, the customer tells the chef the number of her selection ("number 5"... the chicken lo mein).
The chef hears number 5, checks his menu for the Chinese description, and prepares the meal. Very efficient.
The Menu is the Type Library
This approach only works if the customer has a copy of the menu.
In VBA, the menu corresponds to a COM object's type library, which gets incorporated at runtime via the Tools > References... dialog. Of course, this only works if both the customer and the chef are using the same menu. My menu from the Great Wall Restaurant says that chicken lo mein is #5. But if I call China Palace instead of Great Wall and order a #5, I could end up with shrimp fried rice.
It's very important that the type library on the development computer is identical (or at least binary compatible) with the COM object on the end user's computer.
Late Binding: Order By Meal Name
What if I was visiting a new city and I didn't have a menu for the local Chinese place?
I call up the restaurant to place my order. I can't provide them with a number for my order because I don't have the menu. Instead, I order by name. Luckily, the employee who answers the phone is bilingual. I tell her I want the chicken lo mein. She translates my order into Chinese as she passes it along to the chef.
Being able to order by name gives me some flexibility. I don't have to limit myself to only those Chinese restaurants for which I already have a menu. I could call any restaurant so long as it could serve me "chicken lo mein."
Notice that in this scenario there was no guarantee that the restaurant I called even served chicken lo mein. In other words, there was no compile-time checking. If my order failed, I would not know until runtime (i.e., while I was on the phone ordering).
It's important to note that ordering my meal by name was only an option because the Chinese restaurant had a bilingual employee answering the phone.
The Bilingual Employee is the IDispatch Interface
In COM, late binding is only available for objects that implement the IDispatch interface.
There's no real way to know from VBA whether a given COM object supports late-binding. You would need to have access to the COM object's source code to know for sure. Lacking that, you have to rely on either the COM object's documentation or trial and error.
Just know that some COM objects do not support late binding.
A COM object that supports both early binding and late binding is said to have dual interfaces.
This would be like a Chinese restaurant with both a numbered menu and a bilingual employee. Notably, all of the Microsoft Office application COM objects support dual interfaces. The best practice when writing code against those COM objects is to develop using early binding (to get the benefits of compile-time checking and IntelliSense), but deploy using late binding (i.e., switch declarations to
As Object) to avoid version incompatibilities at runtime.