Pergunta

Eu gostaria de iterar através de membros de qualquer classe em uma biblioteca referenciada como é feita usando o navegador de objetos. Como isso pode ser feito usando VBA?

Foi útil?

Solução 2

Achei um KB da Microsoft O que me permitiu fazer exatamente isso. Também abrange a iteração sobre os detalhes dos membros.

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

Outras dicas

Na verdade, como fazer isso não é documentado, mas é possível. Se você deseja implementar um para ... cada sintaxe para uma coleção, você pode fazer o seguinte:

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

Observe as configurações de atributo no acima. Você deve usar o código SAVETETEXT e editar como acima no bloco de notas. Em seguida, você reimporta o código usando o LoadFromText na linha de comando Debug. Depois de fazer o acima, você pode ir:

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

E, se você não quer usar para ... cada uma de uma coleção, você pode/também pode configurar uma propriedade padrão da classe: indo:

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

Então, você pode ir:

Dim n       As clstest1
Dim i       As Integer

Set n = New clstest1

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

No entanto, não tenho consciência de como você pode adicionar automático cada método/membro da classe a uma coleção de objetos embutida automática (não há como serializar isso com as opções do compilador, mas vi código com cada procedimento com item de atributo.vb_usermemid = 1, então 2 então 3). Talvez alguém com mais conhecimento possa entrar).

No entanto, como mostra o acima, você pode implementar um para ... cada uma para coleções. E você pode implementar um índice para cada uma das propriedades/métodos se criar uma propriedade de item personalizado. E, como mostra o acima, você pode definir a propriedade de item que você cria como o padrão. Eu coloquei o "opcional" e, portanto, até:

debug.print n

Vai funcionar, ou

debug.print n.Item(1)

Infelizmente, o Access VBA não suporta a reflexão. Você pode tentar criar sua própria abstração da hierarquia de objetos que inspecionará os valores das propriedades etc. para você. Você pode começar com algo assim:

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

Se você tiver o VB6 instalado - você pode experimentar o TLBINF32.DLL. AFAIR - Se tiver número de classes para obter informações de qualquer typelibrary ver http://support.microsoft.com/kb/224331

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top