excel - 用字符串变量替换字符串 - 错误 91
问题描述
背景
最近我回答了一个涉及查看文件属性的问题。最终我提交的代码运行良好,但有一点让我感到困惑。
问题
有两个特定的行我想用一个变量替换一个(对我来说看起来像)一个字符串,更具体地说,尝试以下操作:
Sub TestForSO()
Dim oDir As Object: Set oDir = CreateObject("Shell.Application").Namespace("C:\Users\...\")
Debug.Print oDir.GetDetailsOf(oDir.Items, 1)
End Sub
将路径名替换为包含 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
解决方案
我有点奇怪,以下确实有效:
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
我不明白它们本身的区别,因为下面的代码将通过“Watches”给出相同的结果:
Sub test()
Dim check1 As String, check2 As String
check1 = "Hello"
check2 = CStr("Hello")
End Sub
问题
有人明白为什么字符串变量本身不够而且会引发错误吗?当看似相同的数据类型时,为什么添加Cstr()
会使代码工作?
解决方案
根据有关Namespace的文档,它需要一个参数,该参数必须是 Variant 或可以是指定文件夹路径的字符串。
这就解释了为什么这两种方法没有问题:
Set oDir = CreateObject("Shell.Application").Namespace("C:\Users\...\ 'string path
或者定义一个 Variant 变量:
Dim MainPath As Variant: MainPath = "C:\Users\...\"
Dim oDir As Object: Set oDir = CreateObject("Shell.Application").Namespace(CStr(MainPath))
但是定义MainPath
为字符串会导致错误Runtime Error 91: Object variable or with block variable not set
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
确实返回一个变体,该变体被强制表示为作为字符串子类型的字符串,但数据是变体。
这可以解释为什么做Cstr(MainPath)
使代码有效。
推荐阅读
- javascript - 如何将一个函数作为另一个函数的参数调用?
- python - L-BFGS-B 中的拉格朗日乘数
- powershell - Powershell 使用 foreach 循环将变量相加
- php - odbc_fetch_array(): SQL 错误是说字段引用了多个表但不应该。微软访问 ODBC PHP
- angular - 打字稿中的异步和等待方法(角度)
- flutter - 尝试在颤动中打开抽屉时出现意外的空值
- laravel - Laravel - 代码在任务调度程序中有效,但在队列作业中无效
- python - 使用python连接文件
- javascript - 如何实时回放 CSV 数据?
- mysql - 更改 MYSQL 工作台视图上的定义器