Mar*_*ler 21 excel vba excel-vba
请考虑以下代码:
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
Run Code Online (Sandbox Code Playgroud)
当我编译它时,我得到一个编译器错误,用于引用一个不存在的成员Worksheet.但是,如果我注释掉最后一行,则没有编译器错误,即使它们既Application没有Workbook方法或属性也没有XXX.这是因为如果我声明Ap,并Wb作为Object变量.
为什么编译器处理Application/ Workbook不同Worksheet?
有没有像这样的其他类,编译器似乎对待它们好像Object?
GSe*_*erg 22
正如我已经解释过的那样(分别是kudos),这是一个COM功能.
默认情况下,COM假定接口是可扩展的,也就是说,它允许在运行时添加成员.如果这不是所需的行为,则可以将该 [nonextensible]属性应用于接口定义,该接口定义声明接口仅接受在类型库中显式定义的方法.
dispinterface _Application并且dispinterface _Workbook没有在Excel类型库中设置此标志dispinterface _Worksheet.
同样,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
Run Code Online (Sandbox Code Playgroud)
您将看到几乎所有接口都是可扩展的,因此大多数接口都被推出调试窗口,您只能看到最后的接口.更改<>到=打印那些不能扩展,也有少得多他们.
一点假设:
您可以像 ADODB.Connection对象一样调用存储过程(如底部).(在几个 msdn网站上的这个例子看起来很奇怪).
所以在VBS/VBA中有一些像'匿名/动态方法'的机制.它可能是这里为类Application和Workbook类激活的类似机制- 虽然我没有看到确切的位置和方式.
一个测试支持基本的想法:
我已经测试了这个参考Microsoft ActiveX Data Objects 2.8 Library:
Public Sub testCompiler()
Dim cn As ADODB.Connection
Dim cmd As ADODB.Command
Debug.Print cn.XXX
Debug.Print cmd.XXX
End Sub
Run Code Online (Sandbox Code Playgroud)
cn.XXX也没有抛出一个编译错误,cmd.XXX确实.
| 归档时间: |
|
| 查看次数: |
703 次 |
| 最近记录: |