Copie de cellule d'une liste a une autre selon un critère commun(variable)
Bonjour,
En pratique j'ai un classeur avec deux listes, concernant les mêmes clients, chacune sur une feuille propre.
Ces deux listes ont étés exploitées et enrichies, on se retrouve donc avec deux listes pour les mêmes clients avec des infos différentes mais complémentaires.
J'aimerais récupérer dans un premier temps les infos d'une colonne en faisant une comparaison ligne à ligne de la valeur commune, ainsi je pourrais mettre en lumière les lignes ou l'info commune diffère (saisie manuelle erronée) et surtout je n'aurais pas la nécessité de trier mes deux liste de la même manière.
Pour L'exemple dans mon classeur j'ai une feuille 1 avec une liste client comportant l'adresse de ceux ci, j'ai ensuite une feuille 2 avec cette même liste client (avec des lignes en plus ou en moins) triée aléatoirement.
Je souhaiterais que l'adresse soit récupérée de la feuille 1 et recopié dans la colonne adresse de la feuille 2 quand le client est identique.
Mes essais ne sont pour le moment pas concluant et le code vba que j'essai d'écrire est il totalement dans le faux?
J'espère que ma problématique vous intéresse et vous remercie par avance de l'aide que vous m'apporterez.
Bonjour,
Et dans une second temps ?
Bonjour,
Et dans une second temps ?
Bonjour MFerrand,
Effectivement je ne suis pas allé jusqu'au bout de mon idée, et cela a forcément son importance.
Donc dans un second temps il s'agirait de copier une plage de cellules contiguës ou non de la feuille 1 et de les coller dans une plage contiguë ou non de la feuille 2.
Mais a vrais dire le premier temps est mon besoin et le second temps est à titre (in)formatif.
Tu n'as que 3 colonnes de servies sur feuille 1 et les noms seulement sur la 2, ce qui ne correspond pas vraiment à ta description de départ !
Si tu as d'autres éléments qui sont à reprendre de feuille 1 il faut indiquer les colonnes, indiquer aussi la disposition que tu veux avoir à l'arrivée. On peut toujours tout faire en une fois dans ce type d'opération, et on gagne du temps à l'arrivée.
Tu n'as que 3 colonnes de servies sur feuille 1 et les noms seulement sur la 2, ce qui ne correspond pas vraiment à ta description de départ !
Si tu as d'autres éléments qui sont à reprendre de feuille 1 il faut indiquer les colonnes, indiquer aussi la disposition que tu veux avoir à l'arrivée. On peut toujours tout faire en une fois dans ce type d'opération, et on gagne du temps à l'arrivée.
MFerrand,
Alors voici un fichier de test qui reprend les actions que j'aimerais faire faire à mon code Vba.
Comme précédemment pour chaque client commun aux deux liste on copie l'adresse,le CP et le n° de client depuis la feuille 1 et on va les coller dans les colonnes définies tel quel de la feuille 2.
Bonjour josef
Voici un fichier à tester :
recupadr.xlsm
Tiens-moi au courant
A+
Patty,
Merci pour ton code, je l'ai intégré à mon fichier et ça fonctionne comme il se doit, comme tu peux le voir avec MFerrand nous discutons pour aller plus loin si tu as aussi des idées, tu es le bienvenu
Bonsoir,
Petit problème à élucider, la liste en Feuil2 comporte deux fois le nom C ! Y a-t-il possibilité de doublons ? Si c'est le cas, il faut les éliminer avant tout transfert d'info. Si c'est une coquille du modèle, je corrige...
Cordialement.
Effectivement le Nom C ne doit pas apparaître 2 fois, le doublon n'est logiquement pas possible.
Question en retour, pour différencier deux clients de même nom on y ajoutera le prénom ou autre, l'espace entre le nom et le prénom peut il poser problème, si oui faut il le remplacer par un underscore?
Aucun problème avec les espaces... il faut juste que les noms soient strictement identiques dans les deux listes.
J'ai pris la liberté de supprimer les lignes vides au-dessus du tableau Feuil2... Dans des bases de données, où ce qui s'en approche, avoir la ligne d'en-têtes en 1 et les données qui commencent ligne 2 permet d'éviter bien des erreurs...
Voilà une méthode :
Sub TestInfo()
Dim d As Object, k, itm, info, i%, j%, Tbl()
Set d = CreateObject("Scripting.Dictionary")
info = Worksheets("Feuil1").Range("A1").CurrentRegion.Value
For i = 2 To UBound(info)
k = info(i, 2)
itm = info(i, 1) & ";" & k & ";" & info(i, 4) & ";" & info(i, 3)
d(k) = itm
Next i
With Worksheets("Feuil2")
i = .Cells(.Rows.Count, 2).End(xlUp).Row
info = .Range("B1:B" & i).Value
ReDim Tbl(2 To UBound(info), 3)
For i = 2 To UBound(info)
k = info(i, 1)
If d.exists(k) Then
itm = Split(d(k), ";")
For j = 0 To 3
Tbl(i, j) = itm(j)
Next j
Tbl(i, 0) = CLng(Tbl(i, 0))
Else
Tbl(i, 1) = k
End If
Next i
.Range("A2").Resize(UBound(Tbl, 1) - 1, 4).Value = Tbl
.Activate
End With
End SubExplications :
- On utilise l'outil dictionnaire, un dictionnaire est une collection d'éléments composés d'une clé et d'un item ou valeur (le contenu quoi !), il ne peut y avoir de clé doublon. Sa particularité est d'être particulièrement rapide...
- 1re phase : sur Feuil1, on affecte tout le tableau (défini par CurrentRegion, la zone rectangulaire utilisée qui inclut A1) à une variable de type Variant. On obtient un tableau de valeurs à deux dimensions, de mêmes dimensions que la plage source, dont les indices lignes et colonnes débutent toujours à 1.
- Recueil des données, opéré hors Excel, pour chaque ligne on affecte le nom à une variable k, on concatène toutes les données de la ligne dans l'ordre où elles doivent être sur Feuil2 en les séparant par des ";" qu'on affecte à une variable itm, et on crée l'élément dico de clé k et de contenu itm.
Ainsi pour la 1re ligne on aura un élément dont la clé sera "A" et l'item : "1;A;dsQSKL;11111". On inclut le nom dans les données transférer, car il se trouve au milieu des éléments à rapatrier sur Feuil2, et il sera plus rapide de l'inclure dans le tableau final de résultats pour n'avoir qu'une seule affectation, plutôt que de scinder les affectations de données transférées...
- On passe sur Feuil2 que l'on met sous bloc With (en évitant surtout de l'activer, ce qui n'aurait pour effet que ralentir l'exécution, sans aucun profit) car aura à y référer pour identifier les noms puis pour l'affectation finale [dès que l'on doit se référer plus d'une fois à un objet, le mettre sous bloc With est un élément d'accélération, cela permet de qualifier toutes les expressions en évitant toute référence implicite à un quelconque élément actif, et sans avoir à répéter...]
- On fait comme sur Feuil1, on dimensionne la longueur du tableau sur la colonne B et on affecte la colonne B à notre variable info (qu'on réutilise, le travail sur les données de Feuil1 étant terminé).
- La suite se déroule encore une fois hors Excel : on va produire un tableau de résultats pour l'affecter en une seule fois sur la plage A2:D13 de notre Feuil2, on dimensionne donc un tableau de résultats (déclaré comme tableau dynamique, c'est à dire dont on ne fixe pas les dimensions préalablement) : de 2 à la longueur de la colonne B (2 parce qu'on a inclu la colonne à partir de 1 mais que les données commencent à 2, cela permet d'aligner les indices) pour les lignes et 0 à 3 pour les colonnes (on s'aligne aussi sur les indices qu'on va utiliser, on va le voir).
- On parcourt donc notre tableau info (à une colonne, qui contient les noms), on affecte ce nom à la variable k, on teste si l'on a un élément de dico de clé k, si c'est le cas on splitte son contenu, c'est à dire qu'en utilisant la fonction Split on récupère dans une variablela chaîne scindée sur notre séparateur ";" pour la transformer en tableau, on obtient donc un tableau des données des 4 colonnes, tableau d'indice minimal 0, on affecte les données de ce tableau à la ligne de notre tableau final au moyen d'une boucle. Par précaution, on reconvertit en nombre le numéro de la 1re colonne qui risquerait sinon d'être affecté comme texte.
Si l'élément dico n'existe pas, pas de données donc, mais on réintroduit alors le nom (que l'on a dans la variable k) dans sa colonne du tableau final.
- On affecte à la fin : une ligne redimensionnant la plage cible, et = Tbl et toutes nos données sont en place.
- Là on active la feuille, pour aller voir le résultat, on peut c'est fini !
Ces explications pour te permettre de voir comment on ajuste chaque détail pour obtenir le maximum de rapidité d'exécution lors du codage...
Cordialement.
Merci beaucoup pour cette solution, je l'ai vu apparaître ce matin et depuis j'ai hâte d'essayer et de tout comprendre, donc je vais regarder ça dans le détail ce soir, avec toutes ces explications je ne peux que dire un grand merci.
Au final l'important n'est pas que cela fonctionne mais c'est d'apprendre des choses et de nouvelle approches de nos problématiques.
À bientôt pour mon retour.