Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用VBA覆盖获取intellisense 我正在尝试做的例子_Vba_Oop - Fatal编程技术网

如何使用VBA覆盖获取intellisense 我正在尝试做的例子

如何使用VBA覆盖获取intellisense 我正在尝试做的例子,vba,oop,Vba,Oop,在MS Office中,可以同时获得以下两个方面的智能感知:Application.Documents(1)。和Application.Documents。 我试图对我自己的类做同样的事情,我认为这叫做重写 我被智能感知卡住了。。。 以下图像显示了我试图为自己的类实现的目标(即获取事物的intellisense。和事物(I)。…: 图像1(下图)显示文档集合的intellisense,例如.count属性 图2(下图)显示了文档的intellisense,它完全不同。 我所拥有的 我首先修改

在MS Office中,可以同时获得以下两个方面的智能感知:
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 on
bar.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)是实际的