Arrays : petites fonctions utiles

Quelques fonctions personnalisées d'usage courant pour travailler avec les arrays dans excel.

Vous pouvez télécharger le classeur fc-pap-arrays qui illustre les exemples présentés sur les pages pas à pas traitant des arrays

Attention, le code présenté dans ce tutoriel et dans le classeur exemple a été écrit et vérifié avec la version 2010 d'excel. Certaines propriétés peuvent ne pas fonctionner avec des versions antérieures, et avec les versions Mac d'excel antérieures à 2011.
Merci d'utiliser les commentaires pour poser des questions directement en rapport avec CE tutoriel EXCLUSIVEMENT et de poser les questions sur vos développements particuliers sur le forum microsoft answers excel.

Les arrays existent dans de nombreux langages de programmations. Certains comme le PHP ont de façon native des fonctions qui permettent de faire certaines opérations avec les arrays. Voici une équivalence en VBA de certaines d'entre elles.

Nombre de dimensions d'un array
IsInArray : présence d'un élément dans un array
Doublons et valeurs uniques dans un array
Filtrer un array sur une valeur exacte
Tirage aléatoire de valeurs sans doublons

Nombre de dimensions

Il n'existe pas de fonction native dans excel pour déterminer le nombre de dimensions d'un array. On doit pour cela utiliser le gestionnaire d'erreur.

Function NombreDim(Tblo)

Dim NbDim as long
Dim ErrorCheck as integer

'On initialise le gestionnaire d'erreur   
On Error GoTo Dimension

   For NbDim = 1 To 60000 'un array dans excel peut avoir jusqu'à 6000 dimensions !
      ErrorCheck = LBound(Tblo, NbDim)
   Next NbDim
   Exit Function
  
Dimension:
   NombreDim = NbDim - 1

End Function

Utilisation : debug.print NombreDim(NomDeArray)

IsInArray

Comment déterminer si un élément est inclus dans un array :
Cette fonction est très rapide car elle évite de faire une boucle sur tous les élémentsz de l'array.
Elle ne fonctionne qu'avec des arrays à 1 dimension !

Public Function IsInArray(ValeurCherchée As Variant, ArrayDeRecherche As _
   Variant) As Boolean
    If Not IsArray(ArrayDeRecherche) Then Exit Function
    IsInArray = InStr(1, vbNullChar & Join(ArrayDeRecherche, _
     vbNullChar) & vbNullChar, vbNullChar & ValeurCherchée & _
     vbNullChar) > 0
End Function

Cette fonction renvoie vrai ou faux. Join (ArrayDeRecherche, vbNullChar) concatène tous les éléments de l'array en les séparant par un caractère nul pour en faire une chaîne de texte à laquelle on ajoute avant et après un autre caractère nul (VbNullChar représente un caractère nul pour l'impression et les fonctions d'affichage). On recherche alors dans cette chaîne de texte la valeur elle même encadrée par des caractères VbNullChar.

Pour les versions antérieures, un code avec une boucle :

Public Function IsInArray(ByRef ArrayDeRecherche as Variant, ByVal ValeurCherchée as Value) As Boolean 
Dim a 
For a = LBound(ArrayDeRecherche) To UBound(ArrayDeRecherche)    
   If ArrayDeRecherche(a) = ValeurCherchée then         
     IsInArray = True         
     Exit For    
   End If 
Next a 
End Function

Exemple d'utilisation (simpliste !)

Sub estdansarray()
Dim Tblo
Tblo = Array(10, 20, 30, 40, 21, 25, 26, 27, 29)
msgbox (IsInArray(21, Tblo))

End Sub

Si l'array a 2 dimensions, on ne peut pas utiliser join pour éviter de boucler. On peut utiliser une fonction comme celle-ci:

Public Function IsInArray2D(ByRef ArrayDeRecherche As Variant, ByVal ValeurCherchée As Value) As Boolean
Dim i As Integer, j As Integer
For i = LBound(ArrayDeRecherche, 1) To UBound(ArrayDeRecherche, 1)
    For j = LBound(ArrayDeRecherche, 2) To UBound(ArrayDeRecherche, 2)
        If ArrayDeRecherche(i, j) = ValeurCherchée Then
        IsInArray2D = True
        Exit For
        End If
    Next j
Next i
End Function

Recherche de doublons et de valeurs uniques

On peut utiliser la fonction IsInArray ci-dessus pour trier dans deux arrays  les valeurs uniques d'un côté et les doublons de l'autre :

Sub doublonsetvaleursuniques()
Dim Tblo
Dim Doublons
Dim ValUniques
Dim elt As Variant
Dim d As Integer, u As Integer
ReDim Doublons(1)
ReDim ValUniques(1)

Tblo = Array(10, 20, 30, 40, 21, 25, 26, 27, 29, 10, 23, 21, 30)
For Each elt In Tblo
    If IsInArray(elt, ValUniques) Then
        d = d + 1
        ReDim Preserve Doublons(1 To d)
        Doublons(d) = elt
    Else
        u = u + 1
        ReDim Preserve ValUniques(1 To u)
        ValUniques(u) = elt
    End If
Next elt

For d = LBound(Doublons) To UBound(Doublons): Debug.Print Doublons(d): Next d
For u = LBound(ValUniques) To UBound(ValUniques): Debug.Print ValUniques(u): Next u

End Sub

Filtrer sur un terme exact

La fonction Filter renvoie un array contenant tous les éléments d'un array qui contiennent une chaîne de caractère (ou un chiffre).
Il n'y a pas d'argument dans cette fonction qui permette de ne séléctionner que les éléments qui sont exactement identiques à la valeur cherchée.
Cette fonction répond à cette spécification.
Elle commence par filtrer le tableau sur la valeur cherchée, puis mets les éléments ainsi sélectionnés qui sont exactement identiques à la valeur cherchée dans un second array.

Function FiltreExact1D(ArrRecherche(), ValCherchée)
Dim Tmp() As String
Dim OK() As String
Dim i, T
i = 1: k = 1

Tmp = Filter(ArrRecherche(), ValCherchée, True, 1)

For i = LBound(Tmp) To UBound(Tmp)
    If Tmp(i) = ValCherchée Then
        ReDim OK(1 To k)
        OK(k) = Tmp(i)
        k = k + 1
    End If
Next i
FiltreExact1D = OK
End Function

Attention, comme Filter ne travaille QUE sur des arrays à 1 dimension, cette fonction ne peut pas être utilisée sur des arrays à 2 dimensions.
Pour la tester :

Sub test()
Dim Tblo() As Variant
Dim Res() As String
Dim MaRecherche As String

MaRecherche = "JULIE"

Dim i, T
i = 1
'rappel : on ne peut pas remplir un array à une seule dimension à partir d'une colonne de la feuille
'l'array créé à partir d'une feuille est toujours à 2 dimensions
For Each T In Sheets("ex5-tri2").Range("A2:A35")
    ReDim Preserve Tblo(1 To i)
    Tblo(i) = T
    i = i + 1
Next T

Res = FiltreExact1D(Tblo, MaRecherche)
For Each T In Res: Debug.Print T: Next

End Sub

Tirage aléatoire sans doublons

Comment tirer 32 nombres entre 1 et 100 sans doublons ? Voici une fonction personnalisée de laurent Longre pour faire ça.
100 correspond à l'argument nombre, 32 à l'argument tirages

Function ALEA2(Optional Nombre As Long, Optional Tirages As Long)
Application.Volatile True
Dim Arr, i As Integer, j As Integer, k As Integer

On Error Resume Next

If Nombre = 0 Then Nombre = Application.Caller.Cells.Count
If Tirages = 0 Then Tirages = Application.Caller.Cells.Count

ReDim Arr(1 To Nombre, 1 To 1)
For i = 1 To Nombre: Arr(i, 1) = i: Next
    Randomize Timer
For i = 1 To Tirages
    j = Int(Rnd * (Nombre + 1 - i)) + i
    k = Arr(i, 1): Arr(i, 1) = Arr(j, 1): Arr(j, 1) = k
Next i
If Application.Caller.Rows.Count = 1 Then
    ALEA2 = Application.Transpose(Arr)
Else: ALEA2 = Arr
End If
End Function

Utilisation :
Si vous voulez entrer dans une plage de la feuille X nombres aléatoires et sans répétition :
Sélectionnez une plage de votre feuille. tapez = alea() et validez par ctrl+maj+enter (saisie matricielle).
La fonction alea2 compte le nombre de cellules de la plage et utilise ce nombre comme argument dans la fonction aléa grace à la ligne

Tirages = Application.Caller.Cells.Count

Vous pouvez aussi appeler cette fonction depuis une macro, en lui passant les arguments de votre choix : tirages = nombre de valeurs aléatoires à générer, nombre = valeur maxi. Si nombre = tirages = X, vous mélangez cela revient à mélanger aléatoirement X nombres entre eux.
Remarque : si vous avez besoin de générer 12 nombres aléatoires sans doublons compris entre 0,2  et 5,  il vous suffit de multiplier les valeurs générées par la fonction par 0.2  (borne inférieure) et  de diviser par 0,2 la valeur de nombre :
= 0,2 * alea2(250;12)

Cette fonction est très utile pour mélanger de façon aléatoire les éléments d'un array.

Mots clefs associés à cette page : , , ,