在VBA中迭代对象浏览器

在VBA中迭代对象浏览器,vba,class,ms-access,member,tlbinf32,Vba,Class,Ms Access,Member,Tlbinf32,我希望遍历引用库中任何类的成员,就像使用对象浏览器一样。如何使用VBA实现这一点?不幸的是,Access VBA不支持反射。您可以尝试创建自己的对象层次抽象,以便为您检查属性值等。您可以从以下内容开始: 实际上,如何做到这一点没有文档记录,但是可能的。如果您希望为集合实现for..Each语法,则可以执行以下操作: Option Compare Database Option Explicit Public colT As New Collection Public Functi

我希望遍历引用库中任何类的成员,就像使用对象浏览器一样。如何使用VBA实现这一点?

不幸的是,Access VBA不支持反射。您可以尝试创建自己的对象层次抽象,以便为您检查属性值等。您可以从以下内容开始:


实际上,如何做到这一点没有文档记录,但是可能的。如果您希望为集合实现for..Each语法,则可以执行以下操作:

Option Compare Database
Option Explicit

Public colT       As New Collection

Public Function NewEnum() As IUnknown

   Set NewEnum = colT.[_NewEnum]

End Function

Public Property Get NextItem() As IUnknown
Attribute NextItem.VB_UserMemId = -4
Attribute NextItem.VB_MemberFlags = "40"

   Set NextItem = colT.[_NewEnum]

End Property
请注意上面的属性设置。您必须在记事本中使用上述SaveAsText和编辑代码。然后在调试命令行中使用loadfromText重新导入代码。完成上述操作后,您可以:

Dim n       As clstest1
Dim v       As Variant

Set n = New clstest1

[ code here that adds to collection]

For Each v In n
   Debug.Print v
Next
Dim n       As clstest1
Dim i       As Integer

Set n = New clstest1

For i = 1 To n.count
   Debug.Print n(i)
Next
而且,如果您不希望为集合使用…每个,您还可以通过以下方式设置类的默认属性:

Public Property Get Item(Optional ndx As Integer = 1) As Variant
Attribute Item.VB_UserMemId = 0
   Select Case ndx
      Case 1: Item = Me.s1
      Case 2: Item = Me.s2
      Case 3: Item = Me.s3
   End Select

End Property

Public Property Get count() As Integer

   count = 3

End Property
然后,你可以去:

Dim n       As clstest1
Dim v       As Variant

Set n = New clstest1

[ code here that adds to collection]

For Each v In n
   Debug.Print v
Next
Dim n       As clstest1
Dim i       As Integer

Set n = New clstest1

For i = 1 To n.count
   Debug.Print n(i)
Next

但是,我不知道如何将类的每个方法/成员自动添加到内置的对象集合automatic(没有办法使用编译器选项将其序列化,但我看到了每个过程都有属性Item.VB_UserMemId=1,然后是2然后是3的代码)。也许有更多知识的人可以加入进来)

但是,如上所示,您可以为集合实现for..each。如果创建自定义项属性,则可以为每个属性/方法实现索引。而且,如上所示,您甚至可以将创建的item属性设置为默认属性。我输入了“可选”,因此甚至:

debug.print n
将起作用,或

debug.print n.Item(1)

如果已安装VB6,则可以尝试tlbinf32.dll。AFAIR-if有许多类可以获取任何类型库的信息 请看

我找到了一个可以让我做到这一点的方法。它还包括对成员细节的迭代

Private Sub ListClassesInAccess()        
    Dim TypeLibrary As TypeLibInfo
    Dim ClassList As CoClasses
    Dim i As Integer    
    Dim Path As String
    Path = "C:\Program Files\Microsoft Office\OFFICE11\MSACC.OLB"

    Set TypeLibrary = TypeLibInfoFromFile(Path)
    Set ClassList = TypeLibrary.CoClasses

    For i = 1 To ClassList.Count
        MsgBox ClassList.Item(i).Name     
    Next

    Set TypeLibrary = Nothing
    Set ClassList = Nothing
End Sub

这可能会有帮助

而且,您为什么要这样做呢?请参见,由于VBA项目在内存中存储和链接的方式的性质,自修改VBA将变得不稳定。也许可以使用外接程序库来完成,但是当当前项目也被破坏时,外接程序也无法工作,因此我不知道如何可靠地实现它。我甚至更难弄明白为什么人们会认为它在运行时是有用的(而不是在开发项目中)。这看起来像是另一个mis应用程序,用于访问来自其他环境的不适当编程实践。它的存储和链接会使其变得不稳定吗?VBA项目都存储在系统表中单个记录的单个BLOB字段中。在运行数据时试图修改这些数据,至少可以说是充满危险的。“我不知道如何将类的每个方法/成员自动添加到集合自动”——我愿意插话,但恕我直言,您的句子扫描不正确。你能纠正一下吗?我把文字改成了“内置对象集合”。许多语言(编译器)允许将对象的方法添加到某种类型的内置对象集合中(然后可以在不知道方法名称的情况下在代码中对其进行迭代或检查)。序列化对象时也是如此。在这两种情况下,放置在每个方法中的某些编译器指令将确定该方法是否包含在该内置对象列表中(或将被序列化),这是很常见的。Attribute Item.VB_UserMemId=N表明有可能检查这组方法。+1给出了一个启发性的答案,但我仍然看不出原始问题中概述的努力要点。