Salut.
En 2020, on travaille évidemment les données au sein d'un tableau structuré (voir mon tuto à ce sujet). La manipulation des tableaux structurés par VBA permet d'écrire un code qui n'est pas lié à la position des données dans le classeur. Que ce soit par les références structurées ou par le tableau structuré lui-même (le Listobject), le code VBA qui doit être écrit peut être rendu générique en sortant du code les données "métier" (nom du tableau, noms des colonnes, position de la ligne ajoutée, ...) et en les faisant "entrer" dans la procédure par une liste d'arguments.
On manipulera donc un tableau structuré par code et le tableau structuré porte le doux nom de ListObject dans le modèle objet Excel.
Je vous propose ici une procédure générique d'ajout d'une ligne dans un tableau structuré. Ce code pourra être enregistré dans un module nommé par exemple TableManager qui contiendrait tous les codes génériques de manipulation des tableaux structurés. C'est une bonne pratique que de se créer des modules génériques.
Je baserai mes explications sur un tableau structuré nommé t_Personnel, illustré ci-dessous. Ce tableau structuré contient une ligne de total, dont la présence ici sert à illustrer que la méthode Add de l'objet ListObject supprime le besoin de savoir s'il y a une ligne de total présente ou non.
Avant de vous exposer le code, quelques mots d'explications s'imposent.
L'idée ici, est de travailler avec un objet ListRow de transférer les valeurs reçues dans les colonnes de la nouvelle plage créée.
Pour cela, on va d'abord récupérer le tableau structuré VBA (le ListObject) au sein d'une variable:
Set l = Range("NomTableau").ListObject
Un tableau structuré en VBA expose une méthode qui renvoie une nouvelle ligne de données du tableau structuré. Cette ligne est ajoutée soit à la fin du tableau (après la dernière ligne existante du tableau) ou insérée à un emplacement précis...
ListObject.ListRows.Add(Position)
Cette méthode Add de ListObject renvoie un objet de type ListRow qui pointe vers la ligne du tableau structuré ajoutée.
Un object ListObject expose également la liste des colonnes (des objets Listcolumn) que l'on peut adresser soit par le nom, soit par l'index (la position dans le tableau). L'idée ici est de déterminer la position de la cellule sur la ligne ajoutée grâce à la priorité Index d'un ListColumn("MonNom") qui permet de récupérer la position d'une colonne dans un tableau structuré.
L'idée ici est donc de créer une fonction qui reçoit le nom du tableau, ainsi qu'un array (un tableau VBA) qui contient des paires de valeurs constituées du nom de la colonne et de la valeur à y ajouter.
Voici donc la fonction générique qui reçoit le nom du tableau, la liste des paires "Clé/Valeur", c'est-à-dire la les paires NomDeColonne/Valeur à pousser sur la nouvelle ligne, et optionnellement la position de la nouvelle ligne. Si la position n'est pas spécifiée, on ajoutera la ligne à la fin du tableau.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Sub AddRow(TableName, Values, Optional Position As Long)
Dim r As ListRow
Dim l As ListObject
Dim i As Long
Set l = Range(TableName).ListObject
If Position = 0 Or Position > l.ListRows.Count Then Position = l.ListRows.Count + 1
Set r = l.ListRows.Add(Position)
For i = LBound(Values) To UBound(Values) Step 2
r.Range(l.ListColumns(Values(i)).Index).Value = Values(i + 1)
Next
Set r = Nothing
Set l = Nothing
End Sub |
On remarque que dans ce code, il n'y a aucune notion métier: Le nom du tableau n'est pas spécifié, les noms des colonnes non plus. Toutes ces notions sont passées par paramètres.
Lorsque l'on veut ajouter une ligne, on peut dès lors utiliser le code d'appel suivant pour ajouter une ligne et y placer des valeurs:
AddRow "t_Personnel", VBA.Array("Prénom", "Jean", "Nom", "Aymar", "DN", DateSerial(1967, 12, 14), "Actif", True, "Salaire", 123.45)
Si l'on veut insérer la ligne au début du tableau, on précisera la valeur 1 pour l'argument Position.
AddRow "t_Personnel", VBA.Array("Prénom", "Jean", "Nom", "Aymar", "DN", DateSerial(1967, 12, 14), "Actif", True, "Salaire", 123.45), 1
On remarque avec le code suivant que l'on n'a pas à se soucier de la position des colonnes, ce sont les noms passés dans l'argument Array qui déterminent oµ l'on place les valeur. On peut également ne pas préciser certaines colonnes, ce qui donne une grande souplesse d'utilisation de la fonction générique.
AddRow "t_Personnel", VBA.Array("Actif", True, "DN", DateSerial(1967, 12, 14), "Salaire", 123.45, "Prénom", "Jean")
Cette fonction est à stocker dans un module spécifique de gestion des tableaux structurés, par exemple nommé TableManager
Que pensez-vous de cette façon de programmer avec des fonctions génériques?
Utilisez-vous des codes génériques dans vos applications ou codez-vous toujours du spécifique?
Trouvez-vous plus simple de travailler avec les tableaux structurés dans vos codes VBA?