为什么VBA的VarType函数说这个COM对象是一个字符串?(对象是.NET的System.Object类的COM版本的实例。)这是一个错误吗?

Mar*_*des 5 .net com excel vba .net-4.0

问题总结

当我使用VBA的VarType 功能时,将mscorlib.dll库引用(.NET库引用)中Object可用的类的实例传递给它,返回的值为。8

根据此处的 VBA文档,这意味着该对象是字符串。这似乎很荒谬。

我的问题是,为什么VarType函数Object从.NET库VBA参考返回此类的实例的字符串类型值?是虫子吗?

背景资料

我怀疑VBA的VarType功能在说某个COM对象是一个字符串,这可能是为什么我在DispCallFunc某些COM对象的某些方法上使用该函数时遇到问题的原因。COM对象是.NET对象的COM版本,可通过.NET框架使用。

我正在使用mscorlib.dll VBA参考来获取这些对象的早期绑定功能。该参考引用.NET框架的版本4.0.30319。在我的计算机上,引用的类型库存储在:

C:\ Windows \ Microsoft.NET \ Framework \ v4.0.30319 \ mscorlib.tlb。

它看上去就像当对象的方法指定一个参数或返回值是类型的System.ObjectDispCallFunc没有为我工作。无论如何,这是一个单独的问题,与该问题专用于该问题的情况密切相关。


在撰写本文时,我正在运行Excel的最新版本(1903版,内部版本11425.20202)。我的操作系统是Windows 8.1。


当我将VarType函数与mscorlib.dll库中其他类的实例一起使用时,有时会得到913VbVarType.vbObjectVbVarType.vbDataObject常数)的返回值,这似乎是正确的。

我在互联网上进行了调查,看看是否有人遇到了问题,但找不到任何东西。

可用于重现问题的代码

Dim o As mscorlib.Object
Set o = New mscorlib.Object
Debug.Print "TypeName(o) = " & TypeName(o) ' TypeName function seems to work correctly.
Debug.Print "o.Equals(o) = " & o.Equals(o) ' System.Object.Equals method is working.

Debug.Print "VarType(CVar(o)) = " & VarType(CVar(o)) ' IMPORTANT LINE
' VBA VarType function says o is string (type 8) but it isn't?!

Debug.Print "VbVarType.vbString = " & VbVarType.vbString
Run Code Online (Sandbox Code Playgroud)

我希望VarType(CVar(o))返回913或其他一些适当的整数。相反,它返回8了似乎根本不合适的(8代表字符串)。

Sim*_*ier 8

例如,如果您C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.tlb使用OleView打开typeLib ,并导航至该_Object接口(不是第一个_Object,dispinterface,而是第二个),您将看到以下内容:

在此处输入图片说明

因此,.NET方法Object.ToString()向COM / Automation客户端声明为

[id(00000000), propget, custom(54FC8F55-38DE-4703-9C4E-250351302B1C, 1)]
HRESULT ToString([out, retval] BSTR* pRetVal);
Run Code Online (Sandbox Code Playgroud)

这意味着COM客户端将这种“语法糖”(VB / VBA / VBScript / JScript / .NET等)理解为返回字符串(BSTR)的属性(propget + out + retval )。ToString

现在,这id(0)意味着它是默认属性,因为0代表DISPID_VALUE,这是一个众所周知的特殊ID。

最后,VB / VBA VarType的文档指出:

如果对象具有默认属性,则VarType(object)返回对象的默认属性的类型。

(我总是发现一个非常奇怪的设计决定...)