概括
在为某些对象类型声明数组后,该类型不使用派生自COM接口的IDispatch
接口(&因此未正确设置以启用 [OLE] Automation的后期绑定技术),尝试根据我的期望,将数组分配给Variant
变量不起作用。
具体来说,似乎发生的是指向数组的整数指针被分配给Variant
变量,而不是数组的副本。
谁能解释这种行为?它是 VBA 7.1 语言的标准行为吗?[EDIT-A1]是不是 VBA 的Variant
类型不能处理这样的数组?[编辑-A2]
[EDIT-A1] -目前(2019 年 4 月 6 日),它看起来像是一个错误。
[EDIT-A2] -不,因为参数的内部过程参数ByRef
Variant
可以正确指向此类数组,如果此类数组作为此类参数的值传递。
背景
有关似乎正在发生的事情的更多详细信息
在检查了各种内存地址和指针之后,似乎正在发生的事情是,当将此类数组分配给Variant
变量时,指向数组的“VB 安全数组指针”Long
的(或LongPtr
)指针被分配了。这与 VBA 语言规范中记录的数组复制行为相反,这是预期的行为。在查看了关于 VB 数组及其内存布局的 VB6 文档(存储在此处)后,我推断出这种指针分配正在发生。
我对以前是否记录过问题的研究
我搜索了互联网、Office VBA 参考文档和VBA 语言规范,以查看其他人是否记录了此问题。我发现这个问题可能已经部分记录的唯一地方是在此处发布的 Stack Overflow 答案中。不幸的是,这篇文章并没有对这个问题说太多。
我已经测试过这个问题的特定数组类型
我在以下对象类型的数组中遇到了这个问题,这些对象类型使用的接口不是来自IDispatch
:
stdole.IUnknown
*stdole.IFont
mscoree.CorRuntimeHost
†mscorlib.AppDomain
†mscorlib.Type
* 来自stdole2.tlb
. † 来自.NET 框架v4.0.30319
的 COM 类型库。
更多关于使用非派生接口的对象类型IDispatch
是
这样的对象类型就是vbDataObject
类型。不幸的是,当前关于vbDataObject
常量的 VBA 文档是不准确的。我正在更新文档,您可以在此处查看我对常量的更新定义。
[编辑 - COM 规范链接已删除,因为它不再相关。]
关于其他对象类型的数组
类型数组vbObject
(支持 [OLE] 自动化后期绑定技术的 COM 对象类型)似乎以Variant
直接和预期的方式分配给变量 -数组被复制并直接分配。
使用 VBE 手表检查此类数组时,VBE 曾经崩溃
一个可能相关的问题与一个错误有关,当 VBE监视表达式被放置在一个类型的数组上时,该数组使用的接口不是从IDispatch
. 用于导致 VBE 意外崩溃的错误。微软似乎已在上个月修复了此错误。
软件版本
软件 | 版本 -------------+---------------
VBA | 7.1 ‡</sup>
-------------+---------------
Microsoft Excel | 2016 §
-------------+---------------
Microsoft Windows (OS) | 8.1 ¶
‡ 版本全文为“Retail 7.1.1088”——最新版本。
§ 更具体地说,最新版本和内部版本(2019 年 6 月 3 日发布,版本 1905,内部版本 11629.20214),以及更早的内部版本号 11629.20196 和 11601.20204(首次发布于 2019 年 5 月 14 日)。
¶ver.exe
程序打印“Microsoft Windows [版本 6.3.9600]”。
代码
代表:
Dim MyArray() As stdole.IUnknown ' Type from OLE Automation
' COM type library in stdole2.tlb.
Dim MyVariant As Variant
MyVariant = MyArray
我希望存储数组MyVariant
的副本。MyArray
相反,在 32 位版本的 VBA 中,MyVariant
存储一个Long
看起来是指向MyArray
.
调试问题
单击此处 获取 VBA 代码以帮助调试问题。