Macro: suppression de doublons et copier/coller à la suite
Résolu/Fermé
Koalacid
Messages postés
70
Date d'inscription
vendredi 5 septembre 2014
Statut
Membre
Dernière intervention
8 mars 2016
-
8 janv. 2016 à 15:38
Koalacid Messages postés 70 Date d'inscription vendredi 5 septembre 2014 Statut Membre Dernière intervention 8 mars 2016 - 14 janv. 2016 à 15:36
Koalacid Messages postés 70 Date d'inscription vendredi 5 septembre 2014 Statut Membre Dernière intervention 8 mars 2016 - 14 janv. 2016 à 15:36
A voir également:
- Macro supprimer les doublons
- Supprimer les doublons excel - Guide
- Supprimer une page word - Guide
- Supprimer compte instagram - Guide
- Supprimer les doublons photos gratuit - Télécharger - Nettoyage
- Doublons photos - Guide
6 réponses
michel_m
Messages postés
16603
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
16 décembre 2023
3 310
Modifié par michel_m le 11/01/2016 à 12:16
Modifié par michel_m le 11/01/2016 à 12:16
Bonjour,
Il faut qu'il y ait quelque chose en C3 de blabla2 (un espace suffit)
Michel
Il faut qu'il y ait quelque chose en C3 de blabla2 (un espace suffit)
Option Explicit
'---------------------
Sub copier_uniques_26_fois()
Dim Derlig As Integer, T_in, Cptr As Integer, D_uniq As Object
Dim T_out, Nbre As Integer, Ligvid As Integer
'----------------------initialisation
Application.ScreenUpdating = False ' fige l'écran: confort et rapîdité
With Sheets("blabla1")
Derlig = .Columns("A").Find(what:="*", searchdirection:=xlPrevious).Row
T_in = Application.Transpose(.Range("A2:A" & Derlig)) 'mise en mémoire RAM des données:rapidité
Set D_uniq = CreateObject("scripting.dictionary")
End With
'-------------------------Traitement
For Cptr = 1 To UBound(T_in)
'si la valeur en cours n'existe pas dans le dico elle est ajoutée au dico
If Not D_uniq.exists(T_in(Cptr)) Then D_uniq.Add T_in(Cptr), ""
Next
' --------------------restitution
With Sheets("blabla2")
'nettoyage
Range("C4:C" & 30000).ClearContents
'caractéristiques des blocs à restituer
T_out = Application.Transpose(D_uniq.keys)
Nbre = D_uniq.Count
'26 restitutions des blocs
For Cptr = 1 To 26
Ligvid = .Columns("C").Find("", .Range("C3"), xlValues).Row
.Cells(Ligvid, "C").Resize(Nbre, 1) = T_out
Next
.Activate
End With
End Sub
Michel
JYM42009
Messages postés
2
Date d'inscription
vendredi 8 janvier 2016
Statut
Membre
Dernière intervention
8 janvier 2016
8
8 janv. 2016 à 22:34
8 janv. 2016 à 22:34
Bonjour,
Tu trouveras de nombreuses procédures VBA toutes prêtes sur le site de boisgontier j. (http://boisgontierjacques.free.fr/ Dommage qu'elles ne soient pas commentées, ça aiderai pour les adapter à son besoin.
En voici une qui supprime les doublons de la colonne A et met le résultat dans le colonne C ligne2
Set mondico = CreateObject("Scripting.Dictionary")
For Each c In Range("a2", [a65000].End(xlUp))
mondico(c.Value) = ""
Next c
[c2].Resize(mondico.Count, 1) = Application.Transpose(mondico.keys)
si tu remplace la dernière ligne par:
Worksheets("blabla2").[c4].Resize(mondico.Count, 1) = Application.Transpose(mondico.keys)
tu auras le résultat dans la feuille blabla2 à partir de la cellule C4.
Si tu veux le répéter 26 fois, tu le mets dans une boucle =for/next
for i = 1 to 26
ta procédure
.....
next i
évidemment, comme ça, cela n'a aucun intérêt de le répéter 26 fois. Je suppose que soit la liste de départ est différente ou alors c'est la cible qui est modifié.
bon courage
Tu trouveras de nombreuses procédures VBA toutes prêtes sur le site de boisgontier j. (http://boisgontierjacques.free.fr/ Dommage qu'elles ne soient pas commentées, ça aiderai pour les adapter à son besoin.
En voici une qui supprime les doublons de la colonne A et met le résultat dans le colonne C ligne2
Set mondico = CreateObject("Scripting.Dictionary")
For Each c In Range("a2", [a65000].End(xlUp))
mondico(c.Value) = ""
Next c
[c2].Resize(mondico.Count, 1) = Application.Transpose(mondico.keys)
si tu remplace la dernière ligne par:
Worksheets("blabla2").[c4].Resize(mondico.Count, 1) = Application.Transpose(mondico.keys)
tu auras le résultat dans la feuille blabla2 à partir de la cellule C4.
Si tu veux le répéter 26 fois, tu le mets dans une boucle =for/next
for i = 1 to 26
ta procédure
.....
next i
évidemment, comme ça, cela n'a aucun intérêt de le répéter 26 fois. Je suppose que soit la liste de départ est différente ou alors c'est la cible qui est modifié.
bon courage
Koalacid
Messages postés
70
Date d'inscription
vendredi 5 septembre 2014
Statut
Membre
Dernière intervention
8 mars 2016
2
11 janv. 2016 à 09:53
11 janv. 2016 à 09:53
Hello JYM42009,
Merci beaucoup pour ton aide, cela fonctionne à la perfection.
Pour la boucle: oui en effet il n'y a pas d'intérêt à la faire répéter plusieurs sur toute la même plage de cellule, il faut juste que je rajoute dans cette boucle une partie de code qui va rechercher la dernière cellule remplie et à partir d'elle fait le copier/coller sur la cellule juste en dessous et cela 26 fois.
C'est ce que je suis entrain de faire, mon premier problème était les doublons et là j'ai ma réponse.
Donc encore une fois merci beaucoup pour votre aide!
Sincèrement,
Koalacid
Merci beaucoup pour ton aide, cela fonctionne à la perfection.
Pour la boucle: oui en effet il n'y a pas d'intérêt à la faire répéter plusieurs sur toute la même plage de cellule, il faut juste que je rajoute dans cette boucle une partie de code qui va rechercher la dernière cellule remplie et à partir d'elle fait le copier/coller sur la cellule juste en dessous et cela 26 fois.
C'est ce que je suis entrain de faire, mon premier problème était les doublons et là j'ai ma réponse.
Donc encore une fois merci beaucoup pour votre aide!
Sincèrement,
Koalacid
Koalacid
Messages postés
70
Date d'inscription
vendredi 5 septembre 2014
Statut
Membre
Dernière intervention
8 mars 2016
2
Modifié par Koalacid le 11/01/2016 à 11:15
Modifié par Koalacid le 11/01/2016 à 11:15
Re-bonjour,
J'ai un problème que j'imagine assez bête mais quand m^me trop compliqué pour que je trouve la solution tout seul.
Basé sur le code que JMY42009 m'a donné, voici le code de ma macro:
Le problème vient de cette ligne (surlignée en jaune par le debugueur) :
Ce que je voulais faire, c'est faire mon copier/coller en boucle à partir de la dernière cellule non-vide de la colonne. Du coup dans ma tête j'ai demandé à VBA d'aller sur la dernière ligne non-vide et de se décaler d'un cran pour copier la sélection. Apparemment j'ai tort mais je ne comprend pas pourquoi.
Ou alors, en réfléchissant un peu, je me demande si l'utilisation des deux
J'ai un problème que j'imagine assez bête mais quand m^me trop compliqué pour que je trouve la solution tout seul.
Basé sur le code que JMY42009 m'a donné, voici le code de ma macro:
Sub Doublons_essais_longeur_liste_infinie()
For i = 1 To 25
Sheets("blabla").Select
Set mondico = CreateObject("Scripting.Dictionary")
For Each c In Range("a2", [a65000].End(xlUp))
mondico(c.Value) = ""
Next c
Worksheets("blabla2").[B2].Resize(mondico.Count, 1) = Application.Transpose(mondico.keys)
Sheets("blabla2").Range("b2", [b65535].End(xlUp)).Select
Selection.Copy Sheets("blabla2").Cells(65535, 2).End(xlUp)(2)
Next i
Sheets("blabla2").Select
End Sub
Le problème vient de cette ligne (surlignée en jaune par le debugueur) :
Sheets("blabla2").Range("b2", [b65535].End(xlUp)).Select
Ce que je voulais faire, c'est faire mon copier/coller en boucle à partir de la dernière cellule non-vide de la colonne. Du coup dans ma tête j'ai demandé à VBA d'aller sur la dernière ligne non-vide et de se décaler d'un cran pour copier la sélection. Apparemment j'ai tort mais je ne comprend pas pourquoi.
Ou alors, en réfléchissant un peu, je me demande si l'utilisation des deux
End(xlUp)ne crée pas une sorte de boucle infinie que VBA ne peut gérer (dîtes-moi si je suis incompréhensible). Dans ce cas, comment modifier ce code et pourquoi?
J'ai testé et ça marche chez moi SI LA FEUILLE "blabla2" EST ACTIVE.
Si tu ne veux pas naviguer de feuille en feuille, tu peux répéter la ligne qui te copie le résultat sans doublon. ce qui te donne:
'créé la liste sans les doublons
'création d'un objet dictionary (mondico).
'En résumé, la boucle for each / next va regarder toutes les valeurs (c.value) des cellules
'de "a2" à "a/dernière ligne complétée". Dés qu'une nouvelle valeur est trouvée, celle-ci
'est ajoutée à mondico.
'Par analogie au dictionnaire classique, les mots ne sont présents qu'une seule fois.
'Voir la discription de Scripting.dictionary sur l'aide Microsoft: https://support.microsoft.com/fr-fr/kb/187234)
Sheets("blabla").Select
Set mondico = CreateObject("Scripting.Dictionary") ' création d'un objet dictionary
For Each c In Range("a2", [a65000].End(xlUp))
mondico(c.Value) = ""
Next c
'Copie 26 fois la liste
For i = 1 to 25
Sheets("blabla2").[b65535].End(xlUp).Resize(mondico.Count, 1) = Application.Transpose(mondico.keys)
Next i
Si tu ne veux pas naviguer de feuille en feuille, tu peux répéter la ligne qui te copie le résultat sans doublon. ce qui te donne:
'créé la liste sans les doublons
'création d'un objet dictionary (mondico).
'En résumé, la boucle for each / next va regarder toutes les valeurs (c.value) des cellules
'de "a2" à "a/dernière ligne complétée". Dés qu'une nouvelle valeur est trouvée, celle-ci
'est ajoutée à mondico.
'Par analogie au dictionnaire classique, les mots ne sont présents qu'une seule fois.
'Voir la discription de Scripting.dictionary sur l'aide Microsoft: https://support.microsoft.com/fr-fr/kb/187234)
Sheets("blabla").Select
Set mondico = CreateObject("Scripting.Dictionary") ' création d'un objet dictionary
For Each c In Range("a2", [a65000].End(xlUp))
mondico(c.Value) = ""
Next c
'Copie 26 fois la liste
For i = 1 to 25
Sheets("blabla2").[b65535].End(xlUp).Resize(mondico.Count, 1) = Application.Transpose(mondico.keys)
Next i
Koalacid
Messages postés
70
Date d'inscription
vendredi 5 septembre 2014
Statut
Membre
Dernière intervention
8 mars 2016
2
14 janv. 2016 à 11:22
14 janv. 2016 à 11:22
Hello, merci pour les explications.
Cependant, j'ai préfér´travaillé avec la méthode de Michel qui correspondait plus à ce que je souhaitait.
Sincèrement,
Koalacid
Cependant, j'ai préfér´travaillé avec la méthode de Michel qui correspondait plus à ce que je souhaitait.
Sincèrement,
Koalacid
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Koalacid
Messages postés
70
Date d'inscription
vendredi 5 septembre 2014
Statut
Membre
Dernière intervention
8 mars 2016
2
11 janv. 2016 à 13:20
11 janv. 2016 à 13:20
Hello Michel,
Ton code fonctionne à la perfection. Il est génial au défaut près que je n'y comprend rien. :)
Pourrais-tu me donner quelques explications sur les étapes et la syntaxe utilisée?
Je comprendrais parfaitement que tu refuses et je ne veux pas abuser de ton temps. Il s'agit surtout pour moi de comprendre le code parce que je sais que ce ne sera pas la dernière macro que j'aurais à faire.
Cordialement et un grand merci,
Koalacid
Ton code fonctionne à la perfection. Il est génial au défaut près que je n'y comprend rien. :)
Pourrais-tu me donner quelques explications sur les étapes et la syntaxe utilisée?
Je comprendrais parfaitement que tu refuses et je ne veux pas abuser de ton temps. Il s'agit surtout pour moi de comprendre le code parce que je sais que ce ne sera pas la dernière macro que j'aurais à faire.
Cordialement et un grand merci,
Koalacid
michel_m
Messages postés
16603
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
16 décembre 2023
3 310
11 janv. 2016 à 16:26
11 janv. 2016 à 16:26
qu'est ce que tu veux savoir ?
michel_m
Messages postés
16603
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
16 décembre 2023
3 310
>
michel_m
Messages postés
16603
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
16 décembre 2023
14 janv. 2016 à 09:12
14 janv. 2016 à 09:12
Pas de réponses ???
Koalacid
Messages postés
70
Date d'inscription
vendredi 5 septembre 2014
Statut
Membre
Dernière intervention
8 mars 2016
2
14 janv. 2016 à 11:20
14 janv. 2016 à 11:20
Hello, Désol´, je viens de voir seulement à l'instant que tu avais ajouté un commentaire.
Alors je t'avoue que j'ai qauisment compris tout ton code. Ca m'aura pris beaucoup de temps mais j'y suis suffisament arrivé pour pouvoir l'adapter aux différentes situations (parce qu'entre temps beaucoup de choses ont changé ;) ).
il me reste deux incompréhensions:
Sur cette partie, je ne comprend pas pourquoi le fait de copier la liste fait apparaître une cellule vide au-dessus de la première cellule de la liste. A savoir que ce n'est en aucun cas dérangeant puisque la cellule vide n'apparaît qu'une fois en tête de liste et ca ne dérange pas le processus, mais je veux juste savoir pourquoi.
Deuxième point: J'ai du rajouter une sélection de la feuille ou effectuer le clear content:
Parce que sinon elle effectuait le clear content dans la feuille d'où elle prenait les infos de la liste à "dédoublonner".
Enfin, mon fichier est devenu assez lent et lourd (1,9mb). Je pense que c'est à cause des formules et du nombre de données traitées (environ 60000 cellules de formules sur chacune des trois feuilles différentes plus une autre feuille avec 40000 cellules pleines). Je voulais savoir si le fait d'avoir une variable objet ne prenait pas aussi de la place et si, pour libérer un peu d'espace, je pouvais faire un clear de cette variable en fin de macro?
Sincèrement,
Koalacid
Alors je t'avoue que j'ai qauisment compris tout ton code. Ca m'aura pris beaucoup de temps mais j'y suis suffisament arrivé pour pouvoir l'adapter aux différentes situations (parce qu'entre temps beaucoup de choses ont changé ;) ).
il me reste deux incompréhensions:
Ligvid = .Columns("C").Find("", .Range("C3"), xlValues).Row
.Cells(Ligvid, "C").Resize(Nbre, 1) = T_out
Sur cette partie, je ne comprend pas pourquoi le fait de copier la liste fait apparaître une cellule vide au-dessus de la première cellule de la liste. A savoir que ce n'est en aucun cas dérangeant puisque la cellule vide n'apparaît qu'une fois en tête de liste et ca ne dérange pas le processus, mais je veux juste savoir pourquoi.
Deuxième point: J'ai du rajouter une sélection de la feuille ou effectuer le clear content:
'nettoyage
Range("C4:C" & 30000).ClearContents
Parce que sinon elle effectuait le clear content dans la feuille d'où elle prenait les infos de la liste à "dédoublonner".
Enfin, mon fichier est devenu assez lent et lourd (1,9mb). Je pense que c'est à cause des formules et du nombre de données traitées (environ 60000 cellules de formules sur chacune des trois feuilles différentes plus une autre feuille avec 40000 cellules pleines). Je voulais savoir si le fait d'avoir une variable objet ne prenait pas aussi de la place et si, pour libérer un peu d'espace, je pouvais faire un clear de cette variable en fin de macro?
Sincèrement,
Koalacid
michel_m
Messages postés
16603
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
16 décembre 2023
3 310
>
Koalacid
Messages postés
70
Date d'inscription
vendredi 5 septembre 2014
Statut
Membre
Dernière intervention
8 mars 2016
Modifié par michel_m le 14/01/2016 à 14:27
Modifié par michel_m le 14/01/2016 à 14:27
Bonjour
Sur des classeurs volumineux passer en VBA fait gagner au moins 20% de poids et passer en variables-tableaux la rapidité.
Mais cela demande une étude préalable rigoureuse pas forcément évidente; D'après ce que tu annonces 3*60000 pourrait laisser à évoquer une solution "Access" mais...
Et pour
la fonction "find" cherche la ligne de la 1° cellule vide dans la colonne C
l=cette cellule ( cells(ligvid,"C") agrandit à nbre sur une colonne permet d'accueillir les valeurs du bloc "T_out"
A chaque étape de la boucle la cellule vide se déplace (de mémoire 26 lignes) vers le bas
Sur des classeurs volumineux passer en VBA fait gagner au moins 20% de poids et passer en variables-tableaux la rapidité.
Mais cela demande une étude préalable rigoureuse pas forcément évidente; D'après ce que tu annonces 3*60000 pourrait laisser à évoquer une solution "Access" mais...
Et pour
Ligvid = .Columns("C").Find("", .Range("C3"), xlValues).Row
.Cells(Ligvid, "C").Resize(Nbre, 1) = T_out
la fonction "find" cherche la ligne de la 1° cellule vide dans la colonne C
l=cette cellule ( cells(ligvid,"C") agrandit à nbre sur une colonne permet d'accueillir les valeurs du bloc "T_out"
A chaque étape de la boucle la cellule vide se déplace (de mémoire 26 lignes) vers le bas
Koalacid
Messages postés
70
Date d'inscription
vendredi 5 septembre 2014
Statut
Membre
Dernière intervention
8 mars 2016
2
14 janv. 2016 à 14:19
14 janv. 2016 à 14:19
C'est bien la réponse que je craignais, parce qu'autant je peux avancer que je maîtrise EXCEL, autant VBA....hum tu connais la réponse.
Enfin malgré le fait qu'il faille passer par des ruptures de calcul de feuille (et lancer les calculs une fois le travail de la macro fini), je fais gagner une demi-journée de temps de travail donc en soit c'est une réussite.
Enfin malgré le fait qu'il faille passer par des ruptures de calcul de feuille (et lancer les calculs une fois le travail de la macro fini), je fais gagner une demi-journée de temps de travail donc en soit c'est une réussite.
Pierre1310
Messages postés
8564
Date d'inscription
lundi 21 décembre 2015
Statut
Membre
Dernière intervention
21 juillet 2020
649
8 janv. 2016 à 15:41
8 janv. 2016 à 15:41
Bonjour,
tape langage vba sur google et tu aura tout ...
tape langage vba sur google et tu aura tout ...