我正在尝试做的示例

在 MS Office 中,可以获得 的智能感知:Application.Documents(1).Application.Documents.
我正在尝试为我自己的类(class)做同样的事情,我认为这称为覆盖?

我被智能感知困住了......

下图显示了我试图为自己的类(class)实现的目标(即获得 Things.Things(i). 的智能感知...):

Image 1 (下图)显示文档集合的智能感知,例如.count 属性。

vba - 如何通过 VBA 覆盖获得智能感知-LMLPHP

Image 2 (下图)显示文档的智能感知,它完全不同。
vba - 如何通过 VBA 覆盖获得智能感知-LMLPHP

是)我有的

我首先修改了这个答案中的代码(一个提供基本结构的“计算器”):https://stackoverflow.com/a/38704040/3451115

修改后的代码有 2 个新类,它们是“要返回的对象”(而不是原始代码的计算值):

  • 集合类 ( cThings )
  • 对象类 ( oThing )

  • 所以,就像 .Documents 一样,我希望能够:
    Things.Things(i). 并获得智能感知...

    我认为添加索引 (i)item:=index 必须是可选的,所以我将参数设为可选。

    尽管在使用 Documents 集合时我注意到,当打开括号 (... 时, item 参数没有用 [方括号] 括起来(据我所知,这通常表示可选)。

    问题: 可能吗?如何实现?

    以下是类和模块:

    用于测试的标准模块(有效但没有智能感知):
    Attribute VB_Name = "overrideExample"
    Sub test()
        Dim bar As IFoo
    
        Set bar = New cFoo
        Debug.Print bar.Things.count     ' No intellisense for count
    
        Set bar = New oFoo
        Debug.Print bar.Things(1).name   ' No intellisense for name
    
    End Sub
    

    接口(interface),IFoo
    VERSION 1.0 CLASS
    BEGIN
      MultiUse = -1  'True
    END
    Attribute VB_Name = "IFoo"
    Attribute VB_GlobalNameSpace = False
    Attribute VB_Creatable = False
    Attribute VB_PredeclaredId = False
    Attribute VB_Exposed = False
    Option Explicit
    
    Function Things(Optional index As Integer) As Object
    End Function
    

    Foo, cFoo 的集合
    VERSION 1.0 CLASS
    BEGIN
      MultiUse = -1  'True
    END
    Attribute VB_Name = "cFoo"
    Attribute VB_GlobalNameSpace = False
    Attribute VB_Creatable = False
    Attribute VB_PredeclaredId = False
    Attribute VB_Exposed = False
    Option Explicit
    
    Implements IFoo
    
    Private mFunctions As Foo
    
    Private Sub Class_Initialize()
        Set mFunctions = New Foo
    End Sub
    
    Private Sub Class_Terminate()
        Set mFunctions = Nothing
    End Sub
    
    Private Function IFoo_Things(Optional x As Integer) As Object
        Set IFoo_Things = mFunctions.Things ' Uses the standard aFunction
    End Function
    

    Foo, oFoo 的对象
    VERSION 1.0 CLASS
    BEGIN
      MultiUse = -1  'True
    END
    Attribute VB_Name = "oFoo"
    Attribute VB_GlobalNameSpace = False
    Attribute VB_Creatable = False
    Attribute VB_PredeclaredId = False
    Attribute VB_Exposed = False
    Option Explicit
    
    Implements IFoo
    
    Private mFunctions As Foo
    
    Private Sub Class_Initialize()
        Set mFunctions = New Foo
    End Sub
    
    Private Sub Class_Terminate()
        Set mFunctions = Nothing
    End Sub
    
    Private Function IFoo_Things(Optional x As Integer) As Object
        Dim tempThing As oThing
        Set tempThing = New oThing
        tempThing.name = "FooBar"
        Set IFoo_Things = tempThing
    End Function
    

    事物的集合,cThings
    VERSION 1.0 CLASS
    BEGIN
      MultiUse = -1  'True
    END
    Attribute VB_Name = "cThings"
    Attribute VB_GlobalNameSpace = False
    Attribute VB_Creatable = False
    Attribute VB_PredeclaredId = False
    Attribute VB_Exposed = False
    Option Explicit
    
    Private Type TThings
        m_objmyThings As Collection
    End Type
    
    Private this As TThings
    
    Public Function count() As Integer
        count = this.m_objmyThings.count
    End Function
    
    Public Property Get myThings() As Collection
        Set myThings = this.m_objmyThings
    End Property
    
    Public Property Set myThings(ByVal objNewValue As Collection)
        Set this.m_objmyThings = objNewValue
    End Property
    
    Private Sub Class_Initialize()
    Set this.m_objmyThings = New Collection
    End Sub
    

    事物的对象,oThing
    VERSION 1.0 CLASS
    BEGIN
      MultiUse = -1  'True
    END
    Attribute VB_Name = "oThing"
    Attribute VB_GlobalNameSpace = False
    Attribute VB_Creatable = False
    Attribute VB_PredeclaredId = False
    Attribute VB_Exposed = False
    Option Explicit
    
    Private Type TThing
        m_sName As String
    End Type
    
    Private this As TThing
    
    Public Property Get name() As String
        name = this.m_sName
    End Property
    
    Public Property Let name(ByVal sNewValue As String)
        this.m_sName = sNewValue
    End Property
    

    对象 Foo, Foo
    VERSION 1.0 CLASS
    BEGIN
      MultiUse = -1  'True
    END
    Attribute VB_Name = "Foo"
    Attribute VB_GlobalNameSpace = False
    Attribute VB_Creatable = False
    Attribute VB_PredeclaredId = False
    Attribute VB_Exposed = False
    Option Explicit
    
    Function Things(Optional x As Integer) As cThings
        Set Things = New cThings
    End Function
    

    最佳答案

    Intellisense 需要 Object 以外的返回类型 - 您需要返回 oThing 类型。

    有多种方法可以得到你想要的东西以及关于你想如何去做的各种问题 - 即 - 你想在 cThings 类中隐藏内部集合,还是想像在你的例子中那样公开它(哪个IMO 似乎很糟糕)。

    我只会回答你的直接问题:



    答:您将 bar.Things 上的返回类型设置为某物。它可能是您的 cThings 集合类型,也可能是您在 cThings 集合类型中的集合(IMO 返回内部集合对象是不好的)。

    所以类型 Foo 需要一个返回 ThingscThings 属性:

    Property Get Things() As cThings
        Set Things = myThings
    End Property
    

    此外,cThings 需要一个 Count 属性。您可以只传递内部集合的 Count 属性:
    Property Get Count() As Long
        Count = myInternalCollection.Count
    End Property
    



    答:首先,Documents(i) 的 MSWord 示例等价于 Documents.Item(i),其中 ItemDocuments 的默认属性,它采用索引。在 VBA 中创建默认属性很痛苦。您必须将模块作为文本文件进行编辑并导入。糟透了。

    如果您打算在 bar.Things.Item(1).name 上为 Name 设置智能感知并放弃默认属性的快捷语法,那么您只需将以下内容添加到 cThings :
    Property Get Item(index) As oThing
        Set Items = myInternalCollection.Item(index)
    End Property
    

    现在您将在 bar.Things.Item(1).name 上拥有智能感知。

    但是,如果你真的想让 bar.Things(1) 工作,那么你需要这样做:

    导出您的模块并在 Item 属性中插入一个属性:
    Property Get Item(index) As oThing
        Attribute Value.VB_UserMemId = 0
        Set Items = myInternalCollection.Item(index)
    End Property
    

    然后,将其导入回来。

    现在,bar.Things(1) 将转换为 bar.Things.Item(1),它将返回一个项目并在智能感知中显示。

    关于vba - 如何通过 VBA 覆盖获得智能感知,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49040244/

    10-10 11:40