Question about CreateObject() in VB6 / VBA - vba

I can do this:
Dim fso As New FileSystemObject
or I can do this:
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
How do I know what string to use for CreateObject? For example, how would I know to use the "Scripting." part of "Scripting.FileSystemObject"? Where do you go to look that up?

It is the ProgID of the component which is registered in Windows registry under HKCR key:
HKEY_CLASSES_ROOT\Scripting.FileSystemObject
ProgID's are human readable identifiers for COM objects. They point to the actual CLSIDs, which in this case is:
HKEY_CLASSES_ROOT\CLSID\{0D43FE01-F093-11CF-8940-00A0C9054228}
This is the place where you can find the actual COM .dll that includes the implementation of the component.
In the first sample code you have provided you are doing an early-binding, and in the second one you are doing a late-binding.

Using the VB6 IDE, choose Project, References, then to pick the reference 'Microsoft Scripting Runtime'.
If you didn't know what the reference is called, you could use the References dialog's Browse button to pick the file /system 32/scrrun.dll.
With the reference chosen, close the References dialog then open the Object Browser (View menu). Change the dropdown to the most likely candidate, being 'Scripting'. This will reveal the library's classes, one of which is 'FileSystemObject'. Hence, you will have discovered the the string required for CreateObject is 'Scripting.FileSystemObject'.
If you didn't know the Reference name or the file name but you did know the class name then you could search the registry for "FileSystemObject" and it should soon be revealed that the fully-qualified name you require is 'Scripting.FileSystemObject'.

I would start by searching for FileSystemObject in the MSDN library at http://msdn.microsoft.com/library
The site is chock full of documentation, including the details of how to call CreateObject.

Related

vba: locate reference for a type (e.g. "Dictionary") in an Excel xlsm file

in this line,
'Dictionary is included in the reference "Microsoft Scripting Runtime" in a working project that already has that reference:
Dim myVar as Dictionary
How can I locate which library it references to, without googling it ? In this case, without knowing that Dictionary is included in "Microsoft Scripting Runtime", how could I have guessed it ?
Thanks !
As the reference is already added you can search all libraries, or a specific library, using the object browser F2 within the VBE.
Open the object browser, select all/single library, enter your search term, hit the binoculars and review search results.
See image below:

VBA CreateObject versus Type Library References

I have build a COM object via ATL, to use compiled C++ in VBA. My type library is (say) "MyObjLib", and the object is "MyObj".
If I use the Object Browser in VBA, all looks good: it shows me the Library as MyObjLib, and within that I see a class MyObj as a member of the library.
If, in VBA, I include this library through the References menu, I can write:
Dim obj as MyObj
Set obj = new MyObj
and it all works fine. However if I try:
Dim obj as Object
Set obj = CreateObject("MyObjLib.MyObj")
it fails with "Runtime Error 429: ActiveX component can't create object."
This is unfortunate as I now want to use the COM object from Python. Any ideas what I am missing?
Thanks for the comments. I spent some time searching my C++ code for the ProgId. Then I stumbled across another SO answer, about someone who had left the ProgId field blank in the ATL Simple COM object Wizard ... which is exactly what I had done! Hence I had never registered the ProgId for the class (and hence no entry in HKCR in the Registy).
I created another project using the Wizard, this time entering a ProgID and copied the syntax from the .rgs file in the new project to my existing one.
Hey presto, CreateObject() works fine now.

Close Shell.Application Instance

I'm writing a script to open documents using the default program via the Windows shell based on this SO answer:
Dim Shex As Object
Set Shex = CreateObject("Shell.Application")
tgtfile = "C:\Nax\dud.txt"
Shex.Open (tgtfile)
I notice the instance of Shell.Application never gets closed. In my code, I Set Shex = Nothing, but is that enough? If I create a Word or Outlook instance, for example, I would need to close it with .Quit before setting the variable to nothing. There's nothing obviously analogous going on here.
I set a reference to Microsoft Shell Controls and Automation to explore the Shell object, but couldn't find any methods for the .Application or .Parent properties, let alone one that looked like .Quit.
Am I missing something obvious? Does the garbage collector somehow also get rid of the instance? Is it something specific to the shell object itself?
Thinking about it, I'm pretty sure #jamheadart is right and I'm just instancing a VBA class rather than creating an application class in Windows.
To be sure, though, I'm taking #Mert Y's suggestion of using a context manager to limit scope.
Final code:
With CreateObject("Shell.Application")
.Open (strPath)
End With

Document type not defined in VBA

I'm following this mail merge work that I found in a related Stack Exchange question which looks to do something similar to what I'd like but I'm having trouble getting started. I"ve narrowed the problem down to the below...
Sub TestEmailer()
Dim Source As Document, Maillist As Document, TempDoc As Document
End Sub
With the error "User-defined type not defined."
It appears I'm missing a reference, but the reference recommended "Microsoft Office 16.0 Object Library" doesn't seem to fix the issue when I enable it.
Has this Document object moved to a different library? How do I find the right library in the future?
If you're doing this in Excel, you need to add a reference to Microsoft Word 16.0 Object Library and then use:
Sub TestEmailer()
Dim Source As Word.Document, Maillist As Word.Document, TempDoc As Word.Document
End Sub
Each application will only load it's own objects by default, along with other common Office objects. If you want to use other objects from another application you either need to add a reference to that application's object library or use late binding.
In this instance I'd recommend early binding (adding a reference manually) so that you get the benefit of IntelliSense in your code, this will make it easier working across applications.

What reference I should add to be able to access a particular class?

I have this code in vb.net
dim WebBrowser = New SHDocVw.InternetExplorer
Obviously this code requires some library. Which one?
The code uses to work. I remove all references, and I forget which one I should add.
This page shows https://msdn.microsoft.com/en-us/library/ms970672.aspx that it should be microsoft.internetcontrol
However, I cannot find microsoft.internetcontrol among list of references.
Based on the following, you need to add the Microsoft Internet Controls COM object (not .NET assembly) for it to work.
In Visual Studio 2015: