Solved

switch 'set x = new xxxx.yyyyy'  to late binding for arbitrary object types

Posted on 2013-12-15
9
511 Views
Last Modified: 2013-12-30
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

Open in new window



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
0
Comment
Question by:rberke
9 Comments
 
LVL 15

Assisted Solution

by:ChloesDad
ChloesDad earned 100 total points
Comment Utility
Late binding is bad and should be avoided as it makes code difficult to maintain.

I'm assuming that by portable you mean it will work with any browser.

A better method would be have a overriding routine that works out which browser is being used and then calls a specific method for that browser.
0
 
LVL 57

Expert Comment

by:Jim Dettman (Microsoft MVP/ EE MVE)
Comment Utility
<<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.
0
 
LVL 5

Author Comment

by:rberke
Comment Utility
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
     
End Sub
0
 
LVL 76

Assisted Solution

by:GrahamSkan
GrahamSkan earned 70 total points
Comment Utility
The object SHDocVw.ShellWindows is a different class from Shell.Application, which has no explorers in the collection.

 To get your particular application working, use the Windows collection:

Function QuitIE() As Long
    ' returns number of quits performed  (up to 50)
    Dim shellWins As Object '  SHDocVw.ShellWindows
    Dim explorer As Object

    'Set shellWins = New SHDocVw.ShellWindows 'this works
    Set shellWins = CreateObject("Shell.Application")  '<===== (1) does NOT WORK
 
    Set explorer = CreateObject("InternetExplorer.Application")
    Dim repeat As Boolean
    
    Do
        repeat = False
       ' next line fails object does not support this method
        For Each explorer In shellWins.Windows

Open in new window

0
Get up to 2TB FREE CLOUD per backup license!

An exclusive Black Friday offer just for Expert Exchange audience! Buy any of our top-rated backup solutions & get up to 2TB free cloud per system! Perform local & cloud backup in the same step, and restore instantly—anytime, anywhere. Grab this deal now before it disappears!

 
LVL 5

Author Comment

by:rberke
Comment Utility
grahamSkan:

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.
0
 
LVL 5

Author Comment

by:rberke
Comment Utility
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
0
 
LVL 5

Author Comment

by:rberke
Comment Utility
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.
0
 
LVL 57

Accepted Solution

by:
Jim Dettman (Microsoft MVP/ EE MVE) earned 330 total points
Comment Utility
I don't think your saying anything that has not already been said, but I think some of the things implied by what your saying are not exatacly right either.

<<
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.
>>

 Often impossible, but often is quite possible.  It depends on the object and how it was developed.  It's not a result of early vs late binding itself.

 Late binding is not "bad" per say, it simply represents a different method of doing something and a different set of choices.

 In fact Micrsoft recommends late binding for Office Developers to avoid version issues.

<<
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.
>>

 Sometimes you can and sometimes you can't.

<<
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.)
>>

 This is not true because early binding ties you to a specific type lib.  That can lead to install problems.

 For example, if I write an Access app that uses Outlook 9.0 and I early bind, the only version someone can have with my app is version 9.0.  If they have anything else installed, my app breaks.   But if I late bind and stick to properties and methods that work from a minimum version up (say 9.0, which means 10, 11, 12, etc will all work), then I can have one version of my app that supports far more situations.

 As I said, Microsoft itself recommends late binding for Office Developers, so NEVER is not correct.

<<
Since these two objects have totally different methods and properties, the subsequent code has to be changed and retested.
>>

 That's a fault of the class your using and not something that is specific to the early vs late binding methods in of themselves.

 You are implying it is somehow the fault of the method of binding that is causing you a problem and it is not.   It's the paticular class that your using.

 Early vs late binding is simply a matter of choices where in specific situations, it may make sense to use one vs the other.

Jim.
0
 
LVL 5

Author Comment

by:rberke
Comment Utility
Thanks for taking the time to reply.

I think we are in general agreement.

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
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

Suggested Solutions

I see at least one EE question a week that pertains to using temporary tables in MS Access.  But surprisingly, I was unable to find a single article devoted solely to this topic. I don’t intend to describe all of the uses of temporary tables in t…
Describes a method of obtaining an object variable to an already running instance of Microsoft Access so that it can be controlled via automation.
This Micro Tutorial will demonstrate how to create pivot charts out of a data set. I also added a drop-down menu which allows to choose from different categories in the data set and the chart will automatically update.
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now