Jvd*_*vdV 5 string excel vba namespaces
背景
最近,我回答了一个问题,其中涉及在寻找一个文件的属性。最终,我提出的代码运行良好,但是有一点让我感到困惑。
问题
我想在两行中用一个变量替换一个字符串(在我看来是这样),更具体地说,请尝试以下操作:
Sub TestForSO()
Dim oDir As Object: Set oDir = CreateObject("Shell.Application").Namespace("C:\Users\...\")
Debug.Print oDir.GetDetailsOf(oDir.Items, 1)
End Sub
Run Code Online (Sandbox Code Playgroud)
将路径名替换为包含excel文件的目录,它应该可以正确返回属性值。
现在,当我尝试用变量替换完整路径时,以下内容会在debug.print行上引发“运行时错误91:对象变量或未设置块变量”:
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
Run Code Online (Sandbox Code Playgroud)
解
对我而言,以下功能确实有用:
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
Run Code Online (Sandbox Code Playgroud)
我不了解其本质上的区别,因为下面的代码将通过“ Watches”给出相同的结果:
Sub test()
Dim check1 As String, check2 As String
check1 = "Hello"
check2 = CStr("Hello")
End Sub
Run Code Online (Sandbox Code Playgroud)
题
有人知道为什么字符串变量本身不够用并会引发错误吗?Cstr()当看起来是相同的数据类型时,为什么要添加代码才能使代码正常工作?
根据有关Namespace的文档,它需要一个参数,该参数必须是 Variant 或可以是指定文件夹路径的字符串。
这解释了为什么这两种方法没有问题:
Set oDir = CreateObject("Shell.Application").Namespace("C:\Users\...\ 'string path
Run Code Online (Sandbox Code Playgroud)
或者定义一个 Variant 变量:
Dim MainPath As Variant: MainPath = "C:\Users\...\"
Dim oDir As Object: Set oDir = CreateObject("Shell.Application").Namespace(CStr(MainPath))
Run Code Online (Sandbox Code Playgroud)
但定义MainPath为字符串会导致错误运行时错误 91:未设置对象变量或块变量
OP找到了解决方案。如果MainPath声明为字符串并与Cstr组合,则代码可以工作。
这只是一个理论,但一些非官方来源(与 VBA 没有直接关系)提到Cstr将值转换为具有子类型的变体。
http://www.csidata.com/custserv/onlinehelp/vbsdocs/vbs89.htm https://docs.oracle.com/cd/E57185_01/HFMAD/ch10s06s04s03.html
实际上,官方文档有点令人困惑,因为第一行它说:
每个函数将表达式强制为特定的数据类型。
后来它说
函数名决定返回类型
但如果我们仔细阅读的话,还有一些重要的信息是这样的:
“......一般来说,您可以使用数据类型转换函数记录代码,以表明某些操作的结果应表示为特定数据类型而不是默认数据类型......”
并且:
“...该技术与所有其他内在类型到其等效 Variant 子类型的转换是一致的...”
因此,在过去 24 小时内进行了一些研究和思考,并多次阅读了我之前发布的段落之后,我敢说所有转换函数都会返回带有子类型的 Variant。在这种情况下,CStr确实返回一个 Variant,该 Variant 被强制表示为 string子类型,但数据是 Variant。
这可以解释为什么这样做Cstr(MainPath)会使代码有效。