如何使用VBA覆盖获取intellisense 我正在尝试做的例子
在MS Office中,可以同时获得以下两个方面的智能感知:如何使用VBA覆盖获取intellisense 我正在尝试做的例子,vba,oop,Vba,Oop,在MS Office中,可以同时获得以下两个方面的智能感知:Application.Documents(1)。和Application.Documents。 我试图对我自己的类做同样的事情,我认为这叫做重写 我被智能感知卡住了。。。 以下图像显示了我试图为自己的类实现的目标(即获取事物的intellisense。和事物(I)。…: 图像1(下图)显示文档集合的intellisense,例如.count属性 图2(下图)显示了文档的intellisense,它完全不同。 我所拥有的 我首先修改
Application.Documents(1)。
和Application.Documents。
我试图对我自己的类做同样的事情,我认为这叫做重写
我被智能感知卡住了。。。
以下图像显示了我试图为自己的类实现的目标(即获取事物的intellisense。
和事物(I)。
…:
图像1(下图)显示文档集合的intellisense,例如.count
属性
图2(下图)显示了文档的intellisense,它完全不同。
我所拥有的
我首先修改了这个答案中的代码(提供基本结构的“计算器”):
修改后的代码有2个新类,它们是“要返回的对象”(而不是原始代码中的计算值):
- 集合类(
)cThings
- 对象类(
)oThing
.Documents
,我希望能够:
事物。
或事物(i)。
并获得智能感知
我认为添加索引(I)
即项:=index
必须是可选的,因此我将参数设置为可选的
尽管在使用Documents集合时,我注意到,当打开括号(…
)时,item参数没有被[方括号]括起来(据我所知,通常表示可选)
问题:可能吗?如何实现
以下是课程和模块: 用于测试的标准模块(工作但不具备智能感知): 接口
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
收集物品、物品
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
事物的对象
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
编辑:有可能是我做得不对。@andrew提供了一种根据问题中的图像完全按照我想要的方式进行设置的方法。然而,这(不正确)答案提供了一些有用的背景信息和上下文给其他人谁也可能是挣扎与此
我认为这是不可能的(见公认的答案) 此处阅读:说明VBA是一种动态类型的语言,为了正确支持重载,它需要静态类型,即强制执行更显式的变量类型 而且,正如@TimWilliams所提到的,返回一个对象基本上会阻止intellisense 也就是说,我认为我改进(简化)了重载示例(但仍然没有intellisense): 修订的cFoo:
Public Property Get things(Optional x As Integer) As Object
Set things = IFoo_Things
End Property
Private Function IFoo_Things(Optional x As Integer = -1) As Object
Select Case x
Case -1 ' Return Collection of Things
Set IFoo_Things = mFunctions.things
Case Else ' Return specific Thing
Dim tempThing As oThing
Set tempThing = New oThing
tempThing.name = "FooBar"
Set IFoo_Things = tempThing
End Select
End Function
Intellisense需要除
对象
以外的返回类型-您需要返回其他类型
类型
有多种方法可以获取您想要的内容,以及关于如何实现的各种问题-即,您是想在cThings
类中隐藏内部集合,还是想像在示例中那样公开它(IMO似乎很糟糕)
我只回答你的直接问题:
我如何获得intellisense for Count onbar.Things.Count
回答:您在bar.Things上设置了返回类型。它可以是您的cThings
集合类型,也可以是您在cThings
集合类型中拥有的集合(在我看来,返回内部集合对象是不好的)
因此键入Foo
需要一个Things
属性,该属性返回cThings
:
Property Get Things() As cThings
Set Things = myThings
End Property
Property Get Item(index) As oThing
Set Items = myInternalCollection.Item(index)
End Property
另外,cThings
需要一个Count
属性。您只需通过内部集合的Count属性即可:
Property Get Count() As Long
Count = myInternalCollection.Count
End Property
Property Get Item(index) As oThing
Attribute Value.VB_UserMemId = 0
Set Items = myInternalCollection.Item(index)
End Property
如何在bar.Things(1).Name
答:首先,Documents(i)
的MSWord示例相当于Documents。Item(i)
其中Item
是Documents
的默认属性,它采用索引。在VBA中创建默认属性是一件痛苦的事情。您必须将模块作为文本文件编辑并导入。糟糕透了
如果您满足于在bar.Things.Item(1).Name上使用intellisense作为Name,并放弃默认属性的快捷语法,那么您只需将以下内容添加到cThings
:
Property Get Things() As cThings
Set Things = myThings
End Property
Property Get Item(index) As oThing
Set Items = myInternalCollection.Item(index)
End Property
现在您将在bar.Things.Item(1.name)上拥有intellisense
但是,如果您确实希望bar.Things(1)
正常工作,则需要执行以下操作:
导出模块并在Item属性中插入属性:
Property Get Count() As Long
Count = myInternalCollection.Count
End Property
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)
它将返回一个项目并以intellisense显示。如果属性Things
将Object
作为返回类型,那么intellisense将没有多大用处:它无法预测由该类型的对象包装的集合中包含的内容。您可以通过使用具有特定r的属性来获得intellisenseeturn类型。@TimWilliams-我开始意识到这一点。我不认为有什么办法,即将发布一个解释…Documents(I)的答案
只是文档默认属性的快捷方式,即文档。返回类型id为Document
的项
。但这与您为什么看不到intellisense无关,正如您自己指出的,这是因为您正在返回类型对象
。为什么不返回具体类型?@andrew。…但是怎么做?Documents(i)
是一个文档,而Documents
是一个文档集合。我确实使用了默认成员,但没有用。@SlowLearner-因为文档(i)与文档不是同一属性。文档(i)是实际的