J'utilise (comme exemple) un UserForm avec six TextBoxes sur une matrice 3x2 : comme ceci :

c1  c2  c3
c4  c5  c6

J'essaie d'ajouter ces deux lignes de zones de texte à une collection (secondaire), puis d'ajouter ces collections à une collection (primaire) de collection. Et puis faites référence à un objet dans la collection imbriquée (secondaire) avec une variable pour la collection dans la collection principale. Comme : La « Collection (primaire). Premier élément. Collection (secondaire).Troisième élément.nom” est c3.

J'ai essayé de lire et de mettre en œuvre Référencer un objet dans une collection de collections par clé ou Collection de collections - Comment faire des sous-collections par valeur plutôt que par référence ?, et j'ai également essayé avec un dictionnaire comme suggéré Créer dynamiquement une collection de collections VBA, mais je reçois toujours :

Erreur d'exécution '438' : l'objet ne prend pas en charge cette propriété ou cette méthode

Sur cette ligne (ou dans l'une des variantes de ligne affichées dans le code ci-dessous) :

If rigavar.ItemCollection(q)(3).Name = "c3" Then

J'ai essayé de comprendre et d'adapter ces exemples mais je n'y arrive tout simplement pas et je ne sais pas si j'ai raté quelque chose ou si je le fais complètement mal ou si je ne comprenais tout simplement pas comment les choses fonctionnent ou tous.

J'ai trouvé une solution de contournement en créant juste une collection pour chaque ligne et en créant une procédure spécifique pour chaque collection. Lorsque la routine atteint une certaine collection, elle déclenche la routine avec les références spécifiques pour cette collection, quelque chose comme ceci :

Private Sub workaround_Click() 
    Set rigaAA = New Collection
    rigaAA.Add c1
    rigaAA.Add c2
    rigaAA.Add c3
    
    Set rigaBB = New Collection
    rigaBB.Add c4
    rigaBB.Add c5
    rigaBB.Add c6
    
    If rigaAA.ItemCollection(3).Name = "c3" Then
    
    Call rigaAAspecificRoutine
        
        End if
    End sub

    Private Sub rigaAAspecificRoutine()
        MsgBox c1.value & c2.value  & c3.value
    End sub

Mais j'espérais le faire par des variables au lieu de spécifiques, quelque chose comme:

Private Sub test_Click()

Dim rigaAA As VBA.Collection
Dim rigaBB As VBA.Collection
Dim rigavar As VBA.Collection

Set rigaAA = New Collection
rigaAA.Add c1
rigaAA.Add c2
rigaAA.Add c3

Set rigaBB = New Collection
rigaBB.Add c4
rigaBB.Add c5
rigaBB.Add c6

Set rigavar = New Collection
rigavar.Add rigaAA
rigavar.Add rigaBB

'none of this works:

For q = 1 To 2
    If rigavar.ItemCollection(q)(3).Name = "c3" Then
        MsgBox c1.value & c2.value  & c3.value
    End If
Next

For q = 1 To 2
    If rigavar.ItemCollection(q)(3).Name = "c3" Then
        MsgBox c1.value & c2.value  &  c3.value
    End If
Next

For q = 1 To 2
    If rigavar.ItemCollection(q, 3).Name = "c3" Then
        MsgBox c1.value & c2.value  & c3.value
    End If
Next

For q = 1 To 2
    If rigavar.ItemCollection(q).ItemCollection(3).Value <> "" Then
        MsgBox c1.value & c2.value  & c3.value
    End If
Next
    
End Sub

Toute suggestion? Merci beaucoup

0
Artemis 15 oct. 2020 à 15:37

1 réponse

Meilleure réponse

Un Collection n'a pas de propriété ItemCollection. Pour accéder à l'élément q de la collection rigavar, vous pouvez utiliser l'une des méthodes suivantes

rigavar(q)
rigavar.Item(q)

(Habituellement, la forme plus courte est utilisée, il s'agit essentiellement d'une abréviation de la forme plus longue car la propriété Item est la soi-disant propriété par défaut d'une collection).

Comme l'élément rigavar(q) est à nouveau une Collection, vous pouvez accéder au 3ème élément avec

rigavar(q)(3)
rigavar.Item(q)(3)
rigavar.Item(q).Item(3)

Le moyen le plus simple de vérifier le nom du contrôle, utilisez rigavar(q)(3).Name

Ce que vous ne pouvez pas faire, c'est d'écrire rigavar(q, 3) car maintenant VBA prendrait les deux paramètres comme paramètres dans rigavar.Item (comme s'il s'agissait d'un tableau à 2 dimensions).

1
FunThomas 15 oct. 2020 à 13:18