Background
Recently I answered a question which involved looking at a file's properties. Eventually the code I put up worked fine, but there is one thing about it that got me puzzled.
Problem
There are two specific lines where I wanted to replace a (to me what looks like) a string, with a variable, more specifically, try the following:
Sub TestForSO()
Dim oDir As Object: Set oDir = CreateObject("Shell.Application").Namespace("C:\Users\...\")
Debug.Print oDir.GetDetailsOf(oDir.Items, 1)
End Sub
Replace the pathname to a directory which includes an excel file, and it should return the property value just fine.
Now when I try to replace the full path with a variable the following throws an "Runtime Error 91: Object variable or with block variable not set" on the debug.print line:
Sub TestForSO()
Dim MainPath As String: MainPath = "C:\Users\...\"
Dim oDir As Object: Set oDir = CreateObject("Shell.Application").Namespace(MainPath)
Debug.Print oDir.GetDetailsOf(oDir.Items, 1)
End Sub
Solution
A bit peculiar to me that the following did work:
Sub TestForSO()
Dim MainPath As String: MainPath = "C:\Users\...\"
Dim oDir As Object: Set oDir = CreateObject("Shell.Application").Namespace(CStr(MainPath))
Debug.Print oDir.GetDetailsOf(oDir.Items, 1)
End Sub
I do not understand the difference per se as the code below will give the same result through "Watches":
Sub test()
Dim check1 As String, check2 As String
check1 = "Hello"
check2 = CStr("Hello")
End Sub
Question
Does somebody understand why the string variable on itself was not enough and would throw an error? Why would adding Cstr()
make the code work when seemingly it's the same data type?
First you must declare the object variable. Then you must assign a valid reference to the object variable using the Set statement. Similarly, a With... End With block must be initialized by executing the With statement entry point.
Error: "Runtime Error 91" is a Visual BASIC error which means "Object variable not set". This indicates that the object was never created using the "Set" command before being used. Remedy: Be sure to use the SET statement to create the new oject.
"Runtime Error 91: Object variable or with block variable not set" is a runtime error that can happen on any Windows-based operating system version. The DCOMCnfg.exe file, which is frequently used to establish rights and set system-wide security settings, is usually the problem.
According to documentation about Namespace, it needs a parameter that must be a Variant or can be a string that specifies the path of the folder.
That explains why these 2 methods work with no problems:
Set oDir = CreateObject("Shell.Application").Namespace("C:\Users\...\ 'string path
Or defining a Variant variable:
Dim MainPath As Variant: MainPath = "C:\Users\...\"
Dim oDir As Object: Set oDir = CreateObject("Shell.Application").Namespace(CStr(MainPath))
But defining MainPath
as string causes error Runtime Error 91: Object variable or with block variable not set
OP found a solution. If MainPath
declared as string, and combined with Cstr, the code works.
It's just a theory, but some unnoficial sources (not directly related to VBA) mention that Cstr
converts the value to a variant with a subtype.
http://www.csidata.com/custserv/onlinehelp/vbsdocs/vbs89.htm https://docs.oracle.com/cd/E57185_01/HFMAD/ch10s06s04s03.html
Actually, the official documentation it's kind of confusing, because at first lines it says:
Each function coerces an expression to a specific data type.
and later on it says
The function name determines the return type
But if we read carefully, there is also some important information like this:
"...In general, you can document your code using the data-type conversion functions to show that the result of some operation should be expressed as a particular data type rather than the default data type..."
And also:
"...This technique is consistent with the conversion of all other intrinsic types to their equivalent Variant subtypes..."
So after doing some research and thinking about it in the last 24 hours, and reading a lot of times the previous paragraphs I've posted, I would dare to say that all conversion functions returns a Variant with a subtype. In this case, CStr
does return a Variant that is being coerced to be expressed as string being string the subtype, but the data is Variant.
That would explain why doing Cstr(MainPath)
makes the code works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With