考虑以下代码:
Public Sub VBACompilerIsMad()
Dim Ap As Application
Dim Wb As Workbook
Dim Ws As Worksheet
Debug.Print Ap.XXX ' No compile error
Debug.Print Wb.XXX ' No compile error
Debug.Print Ws.XXX ' Compile error
End Sub
当我编译它时,我收到一个编译器错误,因为引用了 Worksheet
中不存在的成员。但是,如果我注释掉最后一行,则不会出现编译器错误,即使 Application
和 Workbook
都没有方法或属性 XXX
。就好像我将 Ap
和 Wb
声明为 Object
变量。
为什么编译器对 Application
/Workbook
的处理方式与 Worksheet
不同?
是否还有其他类似的类,编译器似乎将它们视为 Object
?
最佳答案
正如我所解释的(分别值得称赞),这是一个 COM 功能。
默认情况下,COM 假定接口(interface)是可扩展的,即它允许在运行时添加成员。如果这不是所需的行为,可以应用 [nonextensible]
attribute到接口(interface)定义,声明该接口(interface)仅接受类型库中显式定义的方法。
dispinterface _Application
和dispinterface _Workbook
Excel 类型库中没有设置此标志,dispinterface _Worksheet
确实如此。
Similarly ,ADO 的 dispinterface _Connection
没有[nonextensible]
, dispinterface _Command
确实如此。
要了解哪些是可扩展的,请添加对 TypeLib Info
的引用在项目的引用中并运行:
Dim t As tli.TLIApplication
Set t = New tli.TLIApplication
Dim ti As tli.TypeLibInfo
Set ti = t.TypeLibInfoFromFile("excel.exe")
Dim i As tli.InterfaceInfo
For Each i In ti.Interfaces
If (i.AttributeMask And tli.TYPEFLAG_FNONEXTENSIBLE) <> tli.TYPEFLAG_FNONEXTENSIBLE Then
Debug.Print i.Name
End If
Next
您将看到这里几乎所有接口(interface)都是可扩展的,因此大多数接口(interface)都会被推出调试窗口,您只能看到最后一个。更改<>
至=
打印那些不可扩展的,它们的数量要少得多。
关于vba - 由于方法名称错误而缺少 VBA 编译器消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28218373/