2016-11-21 1 views
0

J'ai une liste - que je viens de trouver cette syntaxe qui permettra multi-sélections de ma liste:Check Array Dans VBA

Dim Oldvalue As String 
Dim Newvalue As String 

On Error GoTo Exitsub 
If Target.Address = "$B$1" Then 
    If Target.SpecialCells(xlCellTypeAllValidation) Is Nothing Then 
    GoTo Exitsub 
    Else: If Target.Value = "" Then GoTo Exitsub Else 
    Application.EnableEvents = False 
    Newvalue = Target.Value 
    Application.Undo 
    Oldvalue = Target.Value 
    If Oldvalue = "" Then 
     Target.Value = Newvalue 
    Else 
     Target.Value = Oldvalue & ", " & Newvalue 
    End If 
    End If 
End If 
Application.EnableEvents = True 

Exitsub: 
Application.EnableEvents = True 

je peux dire que la liste des valeurs sélectionnées seront stockées dans la variables Target.Value - mais comment puis-je:

1) Vérifiez la longueur Target.Value (donc je sais que si j'ai 1 sélectionné ou plusieurs)

2) itérer chaque sélection?

+0

Les deux GoTo Exitsub peuvent être remplacés par simplement 'Exit'. – Andreas

+0

Voulez-vous dire que vous voulez que la longueur de la chaîne soit dans une valeur numérique? 'Len (target.value)' – Andreas

+0

@Andreas - Disons que les valeurs de la liste sont rouge, vert, bleu - J'ai besoin d'un moyen de savoir ce qui a été sélectionné quelque chose comme foeach (sélection de la chaîne dans Target.Value) msgBox.Show (pick) next –

Répondre

1

Vous devez affecter Target.Value à une variable Variant. N'oubliez pas d'inclure des parenthèses après le nom de la variable, pour indiquer que vous assignez un tableau.

Vous pouvez ensuite trouver les dimensions de la matrice en utilisant LBound et UBound, vous pouvez également parcourir la matrice. Assez sûr que c'est ce que vous essayez de faire.

Sub get_vals() 

    Dim arr() As Variant 
    Dim i As Long 

    arr = Range("A1:A5").Value 

    Debug.Print UBound(arr, 1) ' Print rows 
    Debug.Print UBound(arr, 2) ' Print columns 

    For i = LBound(arr, 1) To UBound(arr, 1) ' Iterate through the rows of the array 

     Debug.Print arr(i, 1) 

    Next i 

End Sub 

Modifier

Comme soulevé, vous ne seriez pas en mesure d'attribuer une plage d'une cellule à un tableau Variant. Vous pouvez utiliser simplement Dim arr As Variant. Cela vous permettra d'assigner une seule plage de cellules à la variable. Vous pouvez ensuite vérifier le type pour déterminer si vous devez parcourir un tableau ou simplement travailler avec une seule chaîne/entier.

If TypeName(arr) = "Variant()" Then 
    ' Iterate 
Else 
    ' Work with single string/integer 
End If 
+0

Il y a une mise en garde avec cette solution: Si la plage cible est une seule cellule, vous obtiendrez une différence de type car '.Value' renverra une variante et non un tableau variant. Selon l'application, il peut être nécessaire de vérifier si la plage contient plusieurs cellules en premier. – arcadeprecinct

+0

Très vrai, @arcadeprecinct. Une vérification devrait être effectuée avant d'attribuer la variable. –

2

Sans l'attribution d'un tableau, vous pouvez utiliser

Target.Rows.Count 'number of rows 
Target.Columns.Count 'number of columns 
Target.Cells.Count 'number of cells 

Vous pouvez faire une boucle à travers eux à l'aide des indices ou

Dim cl As Range 
For Each cl In Target.Cells 'For Each loops are much faster then looping using indices 
    'do something with cl 
Next cl 

Notez également le commentaire de Thomas Inzina que cette façon, vous obtiendrez toutes les cellules même si vous avez une gamme discontinue.

Edit: La boucle For Each est plus rapide que boucle à travers les cellules en utilisant des indices, à savoir

For i = 1 To Target.Rows.Count 
    For j = 1 To Target.Columns.Count 
     'do something with Target.Cells(i, j) 
    Next j 
Next i 

En utilisant un tableau comme suggéré luke_t pourrait être encore plus rapide.

+0

Pour chaque boucle, il est beaucoup plus rapide que d'utiliser des indices si vous comparez des pommes à des pommes. luke_t utilise un tableau de valeurs, où vous itérez sur les cellules. Ma conjecture est que le tableau serait plus rapide. Cependant, vous avez la bonne réponse.1) Si la cible est une plage non contiguë, seule la première zone de la plage sera copiée dans la matrice. 2) Il est plus intuitif de travailler directement avec les cellules plutôt que d'éditer un tableau et de recopier les valeurs. +1 –

+0

@ThomasInzina Oui, j'aurais dû préciser qu'il est plus rapide que de boucler les cellules en utilisant des indices. – arcadeprecinct