TOP

VBA-Leçon 13.3. Utiliser des tableaux (Arrays) (Exercices)

Pour nous entraîner à utiliser les tableaux, nous allons créer notre propre version de la macro que nous avons utilisée pour démontrer l'avantage de vitesse des tableaux, étape par étape...


Voici le point de départ de cet exercice (vous verrez que l'ensemble de données a été réduit à 1 000 lignes) :

Ici, vous pouvez télécharger le fichier d'exemple Excel : arrays_exercise.xls

Objectif de l'exercice : La procédure doit parcourir les données de l'ensemble de données et compter le nombre de réponses OUI ou NON pour chaque année et pour chaque numéro de client (soit OUI ou NON selon le choix de l'utilisateur) et saisir cette quantité dans la cellule spécifiée de la feuille de travail.

Complétez la macro suivante pour enregistrer les données de la feuille de calcul « DS » dans un tableau :

Sub actualize()
     Dim last_row As Integer
     
     'La dernière ligne de l'ensemble de données
     '...
        
     'Enregistrer un ensemble de données dans un tableau dynamique
     Dim array_db()
     '...
        
End Sub

Voici un exemple de solution :

Sub actualize()
     Dim last_row As Integer
     
     'La dernière ligne de la base de données
     last_row = Sheets("DS").Range("A1").End(xlDown).Row

     'Enregistrer un ensemble de données dans un tableau dynamique
     Dim array_db()
     ReDim array_db(last_row - 2, 2)
     
     For row_number = 2 To last_row
         array_db(row_number - 2, 0) = Sheets("DS").Range("A" & row_number)
         array_db(row_number - 2, 1) = Sheets("DS").Range("B" & row_number)
         array_db(row_number - 2, 2) = Sheets("DS").Range("C" & row_number)
     Next
End Sub

Cela répète essentiellement ce que nous avons fait dans la leçon précédente…

Mais maintenant nous devons modifier notre macro en ajoutant les actions suivantes :

  • Déterminer le choix de l'utilisateur (« OUI » ou « NON » );
  • Compter le nombre de réponses « OUI » ou « NON » dans l'ensemble de données afin de déterminer la taille du tableau (Redim) ;
  • Nous enregistrons uniquement les lignes de l'ensemble de données qui contiennent les réponses « OUI » ou « NON » dans le tableau (cela signifie qu'il n'est pas nécessaire de sauvegarder les données de la troisième colonne).
  • Voici un exemple de solution :

    Sub actualize()
         Dim last_row As Integer, search_value As String, insert_row As Integer, value_yes_no As String, rows_number As Integer
         
         'La dernière ligne de la base de données
         last_row = Sheets("DS").Range("A1").End(xlDown).Row
    
         'Valeur de recherche (YES ou NO)
         If Sheets("RES").OptionButton_yes.Value = True Then
             search_value = "YES"
         Else
             search_value = "NO"
         End If
         
         'Nombre de réponses YES ou NO
         rows_number = WorksheetFunction.CountIf(Sheets("DS").Range("C2:C" & last_row), search_value)
         
         'Enregistrer un ensemble de données dans un tableau
         Dim array_db()
         ReDim array_db(rows_number - 1, 1)
    
         insert_row = 0
         
         For row_number = 2 To last_row
             value_yes_no = Sheets("DS").Range("C" & row_number)
             
             If value_yes_no = search_value Then
                 array_db(insert_row, 0) = Sheets("DS").Range("A" & row_number)
                 array_db(insert_row, 1) = Sheets("DS").Range("B" & row_number)
                 insert_row = insert_row + 1
             End If
         Next
    End Sub
    

    La recherche au choix de l'utilisateur est déterminée en début de procédure par le code suivant :

     'Valeur de recherche (YES ou NO)
     If Sheets("RES").OptionButton_yes.Value = True Then
         search_value = "YES"
     Else
         search_value = "NO"
     End If
    

    Nous utiliserons la fonction CountIF pour déterminer le nombre de réponses « OUI » ou « NON » :

     'Nombre de réponses YES ou NO
     rows_number = WorksheetFunction.CountIf(Sheets("DS").Range("C2:C" & last_row), search_value)
    

    Le tableau a été redimensionné pour s'adapter au nombre de réponses OUI ou NON et réduit à deux colonnes :

    ReDim array_db(rows_number - 1, 1)
    

    Ces données seront désormais stockées dans le tableau lorsque sa troisième colonne correspondra à la sélection de l'utilisateur :

     'Insérer un nombre dans un tableau
     insert_row = 0
    
     'Traitement des ensembles de données
     For row_number = 2 To last_row
         'Valeur de la colonne C (YES ou NO)
         value_yes_no = Sheets("DS").Range("C" & row_number)
         
         'Si la valeur correspond à la sélection de l'utilisateur, la chaîne est stockée dans le tableau
         If value_yes_no = search_value Then
             'Enregistrer la valeur dans la colonne A
             array_db(insert_row, 0) = Sheets("DS").Range("A" & row_number)
             'Enregistrer la valeur dans la colonne B
             array_db(insert_row, 1) = Sheets("DS").Range("B" & row_number)
             'Une ligne a été enregistrée => le numéro d'insertion dans le tableau est incrémenté de 1
             insert_row = insert_row + 1
         End If
     Next
    

    Notre tableau contient uniquement les données qui nous intéressent.

    Il ne reste plus qu'à :

  • Traitez chaque élément du tableau de la feuille de calcul "RES" à l'aide de 2 boucles (même idée que l'exercice du damier) ;
  • Insérez le nombre total d'occurrences sur cette feuille pour chaque année par chaque numéro de client pour chaque cellule.
  • Voici un exemple de solution :

     'Nombre de réponses "YES"/"NO"
     For no_years = 2011 To 2026
         For no_client = 1 To 30
             counter = 0
             
             For i = 0 To UBound(array_db)
                 If Year(array_db(i, 0)) = no_years And array_db(i, 1) = no_client Then
                     counter = counter + 1
                 End If
             Next
             
             Cells(no_years - 2009, no_client + 1) = counter
         Next
     Next
    

    Problème résolu avec des commentaires l'expliquant en détail :

     'Boucle pour chaque ligne
     For no_years = 2011 To 2026
     
         'Boucle pour chaque colonne
         For no_client = 1 To 30
             'Réinitialisation du compteur
             counter = 0
             
             'Traitement des tableaux
             For i = 0 To UBound(array_db)
                 'Vérifier que la ligne du tableau correspond à l'année et au numéro de client
                 If Year(array_db(i, 0)) = no_years And array_db(i, 1) = no_client Then
                     'Si l'année et le numéro de client correspondent, le compteur augmente de 1
                     counter = counter + 1
                 End If
             Next
             
             'Après traitement du tableau, le résultat est inscrit dans la cellule correspondante
             Cells(no_years - 2009, no_client + 1) = counter
         Next
     Next
    

    Et enfin, le code de l'intégralité de notre macro :

    Sub actualize()
         Dim last_row As Integer, search_value As String, insert_row As Integer, value_yes_no As String, rows_number As Integer, counter As Integer
         
         'Suppression de contenu
         Range("B2:AE17").ClearContents
         
         'La dernière ligne de l'ensemble de données
         last_row = Sheets("DS").Range("A1").End(xlDown).Row
    
         'Valeur de recherche (YES ou NO)
         If Sheets("RES").OptionButton_yes.Value = True Then
             search_value = "YES"
         Else
             search_value = "NO"
         End If
         
         'Nombre de réponses YES ou NO
         rows_number = WorksheetFunction.CountIf(Sheets("DS").Range("C2:C" & last_row), search_value)
         
         'Sauvegarder les valeurs dans un tableau
         Dim array_db()
         ReDim array_db(rows_number - 1, 1)
    
         insert_row = 0
         
         For row_number = 2 To last_row
             value_yes_no = Sheets("DS").Range("C" & row_number)
             
             If value_yes_no = search_value Then
                 array_db(insert_row, 0) = Sheets("DS").Range("A" & row_number)
                 array_db(insert_row, 1) = Sheets("DS").Range("B" & row_number)
                 insert_row = insert_row + 1
             End If
         Next
         
         'Compter les réponses YES ou NO
         For no_years = 2011 To 2026
             For no_client = 1 To 30
                 counter = 0
                 
                 For i = 0 To UBound(array_db)
                     If Year(array_db(i, 0)) = no_years And array_db(i, 1) = no_client Then
                         counter = counter + 1
                     End If
                 Next
                 Cells(no_years - 2009, no_client + 1) = counter
             Next
         Next
    End Sub
    

    Ici, vous pouvez télécharger le fichier d'exemple Excel : arrays_exercise_completed.xls