views:

202

answers:

5

I would like to iterate through members of any class in a referenced library much like is done using the Object Browser. How can this be done using VBA?

+1  A: 

Unfortunately, Access VBA doesn't support reflection. You could try creating your own abstraction of the object hierarchy that will inspect property values, etc. for you. You might start with something like this:

http://msdn.microsoft.com/en-us/library/aa663065%28office.11%29.aspx

Andy West
+6  A: 

Actually, how to do this is undocumented, but is possible. If your looking to implement a for..Each syntax for a collection, then you can do the following:

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

Note the Attribute settings in the above. You have to use the SaveAsText and edit code as above in notepad. You then re-import the code using loadfromText in the debug command line. Once you do the above, then you can go:

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

And, if you not looking to use for...each for a collection, you could/can also setup a default property of the class by going:

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

Then, you can go:

Dim n       As clstest1
Dim i       As Integer

Set n = New clstest1

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

However, I not aware how you can automatic add each method/member of the class to a built-in object collection automatic (there is no way to serialize this with compiler options, but I have seen code with each procedure having Attribute Item.VB_UserMemId = 1, then 2 then 3). Perhaps someone with more knowledge can jump in).

However, as the above shows, you can implement a for..each for collections. And you can implement an index for each of the properties/methods if you create a custom item property. And, as the above shows, you can even set that item property you create as the default. I put in the "optional", and thus even:

debug.print n

Will work, or

debug.print n.Item(1)
Albert D. Kallal
"I not aware how you can automatic add each method/member of the class to a collection automatic" -- I'm willing to jump in but, with respect, your sentence does not scan correctly. Can you correct this, please?
onedaywhen
I changed the text to "built-in object collection". Many languages (compilers) allow a methods of an object to be added to some type of built-in object collection (that can be then iterated or inspected in code without knowing the names of the methods). Same thing when you serialize an object. In both cases it is common to have some compiler directive that placed in each method will thus determine if the method will be included in that built-in object list (or will be serialized) . Attribute Item.VB_UserMemId = N suggests that there is a possibility of inspecting this collection of methods.
Albert D. Kallal
+1 For understanding the question:)
Oorang
+1 for an illuminating answer, but I still cannot see the point of the endeavor outlined in the original question.
David-W-Fenton
+1  A: 

If you have VB6 installed - then you can try tlbinf32.dll. AFAIR - if has number of classes to get info of any typelibrary See http://support.microsoft.com/kb/224331

Alex Dybenko
+1  A: 

I found a KB from Microsoft which allowed me to do just that. It also covers iteration over Member details as well.

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
Curtis Inderwiesche
+1  A: 

This may be helpful http://msdn.microsoft.com/en-us/magazine/bb985086.aspx

Art