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
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


A voir également:

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 306
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)
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
1
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
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
0
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
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
0
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
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:

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?
0
Bonjour,
J'améne ma voiture chez le garagiste (rien à voir, mais bof) et je regarde
@+
0
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
0
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
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
0

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
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
0
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 306
11 janv. 2016 à 16:26
qu'est ce que tu veux savoir ?
0
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 306 > 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
Pas de réponses ???
0
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
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:

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
0
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 306 > 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
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
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
0
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
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.
0
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
Bonjour,

tape langage vba sur google et tu aura tout ...
-5