错误的方法名称缺少VBA编译器消息

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)

您将看到几乎所有接口都是可扩展的,因此大多数接口都被推出调试窗口,您只能看到最后的接口.更改<>=打印那些不能扩展,也有少得多他们.

  • 来吧小伙子们.这个出色的答案需要更多的认可. (5认同)
  • @ vba4all奖励赏金,我再给它一个!:) (3认同)

Kek*_*mau 6

一点假设:

您可以 ADODB.Connection对象一样调用存储过程(如底部).(在几个 msdn网站上的这个例子看起来很奇怪).
所以在VBS/VBA中有一些像'匿名/动态方法'的机制.它可能是这里为类ApplicationWorkbook类激活的类似机制- 虽然我没有看到确切的位置和方式.

一个测试支持基本的想法:
我已经测试了这个参考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确实.

  • +1用于解决*"是否还有其他这样的类,编译器似乎将它们视为对象?"*问题的一部分:) (3认同)