Macro: suppression de doublons et copier/coller à la suite
Résolu
Koalacid
Messages postés
70
Date d'inscription
Statut
Membre
Dernière intervention
-
Koalacid Messages postés 70 Date d'inscription Statut Membre Dernière intervention -
Koalacid Messages postés 70 Date d'inscription Statut Membre Dernière intervention -
Bonjour,
J'utilise Excel 2010 et je souhaite intégrer dans un fichier une macro permettant de:
_supprimer les doublons d'une liste de la feuille blabla1
_puis de sélectionner cette liste
_et la copier dans la feuille blabla2 à partir de la cellule C4
_puis de recopier à la suite en colonne toujours cette même liste (sans les doublons du coup)
_et cela un certain nombre défini de fois (26 pour être précis).
J'aurai aimé ne pas arriver les mains vides, mais les quelques exemples partiels de ce que je veux faire et trouvés sur internet me font apparaître le message d'erreur Sub or Function not defined quand je lance la macro.
En cherchant ce que ca voulait dire sur internet j'ai cru comprendre que c'était à cause d'une fonction mal définie ou mal écrite. C'est un peu trop vague pour mes compétences basiques en VBA.
Est-ce que quelqu'un peut m'aider à ce sujet? Et si oui, est-ce que je peux avoir une explication des différentes étapes pour apprendre à manier ce fameux langague VBA?
Voilà, je suis entièrement à votre disposition pour toutes questions et pour apprendre.
Je continue mes recherches entre temps.
Merci :)
Koalacid
J'utilise Excel 2010 et je souhaite intégrer dans un fichier une macro permettant de:
_supprimer les doublons d'une liste de la feuille blabla1
_puis de sélectionner cette liste
_et la copier dans la feuille blabla2 à partir de la cellule C4
_puis de recopier à la suite en colonne toujours cette même liste (sans les doublons du coup)
_et cela un certain nombre défini de fois (26 pour être précis).
J'aurai aimé ne pas arriver les mains vides, mais les quelques exemples partiels de ce que je veux faire et trouvés sur internet me font apparaître le message d'erreur Sub or Function not defined quand je lance la macro.
En cherchant ce que ca voulait dire sur internet j'ai cru comprendre que c'était à cause d'une fonction mal définie ou mal écrite. C'est un peu trop vague pour mes compétences basiques en VBA.
Est-ce que quelqu'un peut m'aider à ce sujet? Et si oui, est-ce que je peux avoir une explication des différentes étapes pour apprendre à manier ce fameux langague VBA?
Voilà, je suis entièrement à votre disposition pour toutes questions et pour apprendre.
Je continue mes recherches entre temps.
Merci :)
Koalacid
A voir également:
- Macro supprimer les doublons
- Supprimer rond bleu whatsapp - Guide
- Supprimer page word - Guide
- Supprimer les doublons excel - Guide
- Doublons photos - Guide
- Supprimer pub youtube - Accueil - Streaming
6 réponses
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
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
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
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
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
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
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
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
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.