switch 'set x = new xxxx.yyyyy' to late binding for arbitrary object types
I have posted a snippet of some working code.
Right now the only way to make it work is to set a reference to "microsoft internet controls". I want the code to be portable, so I tried to use late binding to eliminate the need for a reference. I can't figure out what to put into the createobject. line 13 fails
Function QuitIE() As Long ' returns number of quits performed (up to 50) Dim shellWins As Object ' SHDocVw.ShellWindows' this works Set shellWins = New SHDocVw.ShellWindows Set shellWins = CreateObject("Shell.Application") '<===== (1) does NOT WORK Dim explorer As SHDocVw.InternetExplorer ' (2) changing this to As Object does not help Dim repeat As Boolean Do repeat = False ' next line fails object does not support this method For Each explorer In shellWins
I will give points to whoever can solve this particular problem.
But, I will give the Accepted Answer to anyone that can give me a general answer, In other words I want to be able to change working code from
set x = new wwwwwww.xxxxxx
into set x = createobject ("yyyyy.zzzzz") where w,x,y and z are anything
Microsoft ExcelMicrosoft AccessVisual Basic Classic
<<In other words I want to be able to change working code from
set x = new wwwwwww.xxxxxx
into set x = createobject ("yyyyy.zzzzz") where w,x,y and z are anything
>>
When you use the CreateObject call (or Getobject), you must use the program ID, which in most cases is the fully qualified class name.
For example:
Dim xlApp as Object
Set xlApp = CreateObject("Excel.Application")
You find the class name by reviewing the programs documentation.
With that said, you late bound reference is correct. It is Shell.Application
What error message do you get?
I also have to add that late binding is not "bad"; it's just another way to do something.
Early binding has the advantage of giving you intellisense and better performance. However as you are aware, you are then version specific.
Late binding is slower (about 15%), but your not tied to a specific version. Only thing there is to be carefull to use methods/properties of the lowest version you want to support.
Many developers use early binding while developing, then switch to late binding for deployment.
Jim.
Robert Berke
ASKER
Jim,
error is "object does not support this method.
Test it yourself by running the following code from your favorite office app. (outlook, excel, access word etc)
you can see for yourself by running the attached code.
Sub t1043()
Dim shellWins As Object ' SHDocVw.ShellWindows
' Set shellWins = New SHDocVw.ShellWindows '<====== (1) this works
Set shellWins = CreateObject("Shell.Application") '<===== (2) this does NOT WORK
Dim explorer As SHDocVw.InternetExplorer ' (3) changing this to As Object does not help
For Each explorer In shellWins
Debug.Print explorer.fullname
Next
your code creates an IShellDispatch5 object whereas my early binding code created an IShellWindows object.
While these objects have similar methods and properties, they are not identical.
For this simple example, I can substitute one object type for the other, but in bigger projects, it is likely to cause problems.
That is why I am looking for a more general solution.
For instance, I recently asked myself this related question:
I want to copy this line of code from a working program to a new program.
What reference is need for it to work?
<set myobj = new sHDocVw.ShellWindows>
My "general" answer is as follows.
1). Select the line of code
2) Use f2 to get to object browser
3). in the top window pane Type "ShellWindows" to the left of the binocular icon, then click the icon.
4). in the bottom window pane you will see
Class ShellWindows
Member of SHDocVw
<============ the libary name will be in green
5). Click on the green library name and you will see
Library SHDocVw
C:\Windows\SysWOW64\ieframe.dll
Microsoft Internet Controls < ====== this is the name that must be referenced.
That answer can be applied to ANY line of code that say set myobj = new wwwwww.xxxxxxxx
I am looking for a way to extend that answer to CreateObject.
Maybe Oleview will come to the rescue? Does anybody have experience with it?
It appears to come with the window 7 sdk, but the SDK is a 7 gigabyte download, so I don't want to start on it until I know it is worth pursuing.
In theory it will show me the exposed classes from a specific .dll
Bob
I am going home now but will check in tomorrow
Robert Berke
ASKER
After some independent research, I have concluded my goal of switching from early binding to late binding is often impossible.
That is similar to the “late binding is bad” answer from ChloesDad, so he will get some points.
But, the truth is a little more complicated, so I plan on PAQing this question and providing my own answer. My answer still feels pretty superficial and skips important concepts like classIds and ProgramIds and COM objects. If any expert can improve the following answer substantially, they will get most of the 500 points.
-------- Question ------------
My goal was to make code more portable by switching from early binding to late binding. I wanted to do this for ARBITRARY object types while keeping the same object type, methods and properties.
-------- Proposed Answer ------------
In general, if the early binding code has been thoroughly tested, it is best to NEVER switch to late binding unless an identical object type can be created. (While I like code portability, I hate rewriting and retesting previously working code.)
It is sometimes easy to keep the same object type, but is often difficult or even impossible during a switch.
An example where it is easy follows: Both of these lines of code create a RegExp2 object:
changefrom: Set obj = New VBScript_RegExp_55.regexp
changeto: Set obj = createobject("vbscript.regexp")
But, it is only possible to keep the same object type if the class provider was a COM module that exposes the underlying class so that it can be created with CreateObject.
An example where the easy approach does not work:
Changefrom: set myobj = new sHDocVw.ShellWindows ' this creates an IShellWindows object
Changeto: set myobj = createobject("shell.application") ‘ this creates an IShellDispatch5 object
Since these two objects have totally different methods and properties, the subsequent code has to be changed and retested.
I agree late binding vs early binding is not a choice between bad and good, both have their advantages.
And I COMPLETELY agree that it is the particular class that cause the problem, and that other classes cause no problems. For instance regular expressions is a particular class that does not cause a problem whereas shell windows does cause a problem.
But, that was really the goal of my question - I hoped to find a more general way of at least knowing if the conversion from early to late would be easy. Unfortunately, there does not seem to be any easy way to know.
Naturally, I will take the more general solution, when I have a choice between solution#1 that only works with early binding and solution#2 that will work with both. But often a forum will have a potential solution where the choice is not clear.
For instance, if the forum code says <Dim MyMail as Mailitem>, experience has shown it will work just fine if I say Dim MyMail as Object.
But, when the forum code says <set MyItemr = New xxxxxx.yyyyyy> there is no easy way to know if it can be changed to late binding.
I posted this thread in the hope that I could come up with a general solution, but things are never easy in this world.
Thanks for the discussion, and I am closing the problem
set x = new wwwwwww.xxxxxx
into set x = createobject ("yyyyy.zzzzz") where w,x,y and z are anything
>>
When you use the CreateObject call (or Getobject), you must use the program ID, which in most cases is the fully qualified class name.
For example:
Dim xlApp as Object
Set xlApp = CreateObject("Excel.Applic
You find the class name by reviewing the programs documentation.
With that said, you late bound reference is correct. It is Shell.Application
What error message do you get?
I also have to add that late binding is not "bad"; it's just another way to do something.
Early binding has the advantage of giving you intellisense and better performance. However as you are aware, you are then version specific.
Late binding is slower (about 15%), but your not tied to a specific version. Only thing there is to be carefull to use methods/properties of the lowest version you want to support.
Many developers use early binding while developing, then switch to late binding for deployment.
Jim.