我正在尝试做的示例
在 MS Office 中,可以获得 和 的智能感知:Application.Documents(1).
和 Application.Documents.
我正在尝试为我自己的类(class)做同样的事情,我认为这称为覆盖?
我被智能感知困住了......
下图显示了我试图为自己的类(class)实现的目标(即获得 Things.
和 Things(i).
的智能感知...):
Image 1 (下图)显示文档集合的智能感知,例如.count
属性。
Image 2 (下图)显示文档的智能感知,它完全不同。
是)我有的
我首先修改了这个答案中的代码(一个提供基本结构的“计算器”):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
需要一个返回 Things
的 cThings
属性:
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)
,其中 Item
是 Documents
的默认属性,它采用索引。在 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/