Macro suppression doublon Excel

Résolu
Terek Messages postés 4 Date d'inscription   Statut Membre Dernière intervention   -  
 AmineTLS31 -
Bonjour,

Alors je vous explique la situation. Je suis en stage dans une boîte d'organisation d'évenement médicale et aujourd'hui j'ai recu pour mission de supprimer les doublons (meme nom et prenom et adresse, on ne tient pas compte des autres informations) dans une magnifique liste de 5000 personnes.

Il y en a énormement et donc j'ai décider de me lancer dans une macro excel.

Voila mon code :
Sub Suppressiondouble()
'
' Suppressiondouble Macro
' Macro enregistrée le 09/01/2008 par Prod4
'
   Dim I As Long
    Dim Plage_nom As Range
    Dim Plage_prenom As Range
    Dim Plage_addresse As Range
    Set Plage_nom = Range("C2:C" & Range("C2").End(xlDown).Row)
    Set Plage_prenom = Range("D2:D" & Range("D2").End(xlDown).Row)
    Set Plage_adresse = Range("G2:G" & Range("G2").End(xlDown).Row)
    For I = Plage_nom.Cells.Count To 1 Step -1
        If Plage_nom.Cells(I).Value = Plage_nom.Cells(I - 1).Value And Plage_prenom.Cells(I).Value = Plage_prenom.Cells(I - 1).Value And Plage_adresse.Cells(I).Value = Plage_adresse.Cells(I - 1).Value Then
            Plage_nom.Cells(I).EntireRow.Delete
        End If
    Next

'
End Sub


Lorsque j'éxécute ma macro, j'ai le message d'erreur "La méthode Delete de la classe range a échoué". Je suis débutant en maccro, j'ai appris aujourd'hui en zieutant le forum comment ca marche et donc je ne sais pas comment régler ce probleme. Si j'enlève ma condition IF, tout mon tableau se supprime ce qui montre que le delete fonctionne non? Peut etre ai-je fais une érreur dans la condition de mon IF, aidez moi s'il vous plait.
Merci a bientot.
A voir également:

13 réponses

gbinforme Messages postés 14946 Date d'inscription   Statut Contributeur Dernière intervention   4 724
 
bonjour

Tu as une erreur de réservation : Dim Plage_addresse As Range =>un seul d utilisé ensuite.

Pour éviter cela, je te conseille de mettre : "Option Explicit" en début de feuille VBA.

Tu peux remplacer :
            Plage_nom.Cells(I).EntireRow.Delete
par
            Rows(I).Delete

Tu utilises "cells" sans mettre le paramètre colonne et cela peux peut-être poser problème et pour supprimer une ligne, pourquoi écrire plus que nécessaire ?

Autre petit souci, dans tes réservations de plage :
    Set Plage_prenom = Range("D2:D" & Range("D65536").End(xlUp).Row)
et non
    Set Plage_prenom = Range("D2:D" & Range("D2").End(xlDown).Row)

En effet si tu as une cellule vide, D10 par exemple, tu t'arrêtes en D9 si tu part du haut.

Sinon bravo pour la conception très compacte et très efficace de ton code car c'est rare de voir une telle qualité en débutant.
1
gbinforme Messages postés 14946 Date d'inscription   Statut Contributeur Dernière intervention   4 724
 
bonjour

Que tu n'apprécies pas les méthodes de management n'a rien à faire dans une discussion informatique.

Chacun dans l'entreprise se positionne à sa façon et ce ne sont pas forcément toujours ceux qui ne touchent à rien pour ne rien casser qui sont récompensés et c'est heureux : tous les managers ne sont pas obligatoirement bornés comme tu as l'air de le penser.

Pour gérer une liste de participants à un événement il n'est peut-être pas nécessaire d'installer un serveur raid avec un temps de réponse ultra performant et des sauvegardes en temps réel à l'autre bout de la planète au cas où les tours s'effrondrent.

Il faut savoir raison garder et ne pas tout mélanger.

En tout cas Terek a fait un très bon début et je pense qu'il est préférable de l'aider et non de profiter de l'occasion pour déverser tes déboires malheureux et vécus (même si je compatis à ton souci) .
1
phil232 Messages postés 607 Date d'inscription   Statut Membre Dernière intervention   178
 
EXCEL N'EST PAS UNE BASE DE DONNEES
0
gbinforme Messages postés 14946 Date d'inscription   Statut Contributeur Dernière intervention   4 724
 
bonjour

Qui as dit le contraire dans cette discussion : le demandeur stagiaire essaie de gérer correctement ce qu'on lui a fourni et il le fait très bien.

Pourquoi veux-tu le faire travailler sur une base de données alors qu'il gère une liste ?
0
phil232 Messages postés 607 Date d'inscription   Statut Membre Dernière intervention   178
 
parcequ'il va s'arracher le cheveux. une fois que tu commences (et tu réussis) c'est business qui va venir et demander "un peu plus" par ci "un peu plus par là". ça commence petit et 6 mois après tu est dans la merde parcequ'on a seulement hacké une soluce au lieu de trouver une vraie solution.
n'oublions pas puor le management il n'y a qu'une seule règle : le dernier qui a touché le programme est responsable s'il y a un bug
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Terek Messages postés 4 Date d'inscription   Statut Membre Dernière intervention  
 
Bonjour,

Merci pour ta réponse gbinforme tu m'aides énormement.

J'ai rajouter quelque lignes qui mettent en majuscules afin qu'il compare vraiment des données équivalente.
Les deux D à adresse était une faute de frappe stupide ^^ chaud a trouver.
J'ai fait un DUT informatique donc j'ai quelques notion de programmation (bien que ça ne soit pas une matière dans laquelle j'excelais) c'est d'ailleur pour ca que je continue pas dans l'info :P.

Ma mise en majuscule est un gros Paté Immonde mais je ne savais pas trop comment m'y prendre autrement.
En tout cas je te remercie grandement pour ton aide précieuse.

Voila mon code final si ca peut aider quelqu'un. Je pense qu'il est légèrement améliorable (surtout dans la partie que j'ai fais seul XD)

Option Explicit
Sub suppression()
    Dim I As Long
    Dim Plage_nom As Range
    Dim Plage_prenom As Range
    Dim Plage_adresse As Range
    Set Plage_nom = Range("C2:C" & Range("C2").End(xlDown).Row)
    Set Plage_prenom = Range("D2:D" & Range("D2").End(xlDown).Row)
    Set Plage_adresse = Range("G2:G" & Range("G2").End(xlDown).Row)
    For I = Plage_nom.Cells.Count To 1 Step -1
        Plage_nom.Cells(I).Value = UCase(Plage_nom.Cells(I).Value)
        Plage_nom.Cells(I - 1).Value = UCase(Plage_nom.Cells(I - 1).Value)
        Plage_prenom.Cells(I).Value = UCase(Plage_prenom.Cells(I).Value)
        Plage_prenom.Cells(I - 1).Value = UCase(Plage_prenom.Cells(I - 1).Value)
        Plage_adresse.Cells(I).Value = UCase(Plage_adresse.Cells(I).Value)
        Plage_adresse.Cells(I - 1).Value = UCase(Plage_adresse.Cells(I - 1).Value)
        If Plage_nom.Cells(I).Value = Plage_nom.Cells(I - 1).Value And Plage_prenom.Cells(I).
Value = Plage_prenom.Cells(I - 1).Value And Plage_adresse.Cells(I).Value = Plage_adresse.
Cells(I - 1).Value Then
            Rows(I).Delete
        End If
    Next
End Sub


Eu j'ai un petit problème. J'ai rajouter une coloration sans suppression de la ligne afin de vérifier quel ligne était supprimé.
Quand je lance la macro, c'est la ligne I-1 qui s'en va pour moi. Je m'explique

1 Bob
2 Hernest
3 Michel
4 Michel
5 Roger

Ici je voudrai que Michel (numero 4 soit supprimé) allant de bas en Haut,
Michel (numéro 4) = Cells(I) et donc Michel (numéro 3) serait donc égale a Cells(I-1) non ??
A moins que je n'ai pas compris :(.
0
phil232 Messages postés 607 Date d'inscription   Statut Membre Dernière intervention   178
 
"A moins que je n'ai pas compris :(."

t'as compris. le delete dans Excel supprime la ligne courante et ramène celles d'en-dessous vers le haut (I + 1 devient I). Excel n'est pas une bdd. c'est une feuille de calcul pas plus
0
Terek Messages postés 4 Date d'inscription   Statut Membre Dernière intervention  
 
"Ici je voudrai que Michel (numero 4 soit supprimé) allant de bas en Haut,
Michel (numéro 4) = Cells(I) et donc Michel (numéro 3) serait donc égale a Cells(I-1) non ?? "

Mon problème c'est que avec ma macro, ce n'est pas Michel (num 4) qui est supprimé mais c'est Michel (num 3). C'est ce que je ne comprend pas...
0
gbinforme Messages postés 14946 Date d'inscription   Statut Contributeur Dernière intervention   4 724
 
bonjour

le delete dans Excel supprime la ligne courante

Pas du tout, Excel supprime la ligne qu'on lui demande : Rows(I).Delete c'est-à-dire la ligne I.

Mais en fait, tes tests sont effectués sur ta plage qui commence en ligne 2 et donc il faut mettre pour être en cohérence
            Plage_nom.Rows(I).EntireRow.Delete

au temps pour moi qui ai trop simplifié car j'ai l'habitude du mode ligne.
0
Terek Messages postés 4 Date d'inscription   Statut Membre Dernière intervention  
 
Ok merci pour toutes vos réponses

Bon au final mon code qui marche ressemble a ca. Je testerai avec le Plage_nom.Rows(I).EntireRow.Delete voir si ca differe.

Option Explicit
Sub Mise_en_forme()
    Dim I As Long
    Dim Plage_nom As Range
    Dim Plage_prenom As Range
    Dim Plage_adresse As Range
    Dim Plage_TVF As Range
    Set Plage_nom = Range("C2:C" & Range("C2").End(xlDown).Row)
    Set Plage_prenom = Range("D2:D" & Range("D2").End(xlDown).Row)
    Set Plage_adresse = Range("G2:G" & Range("G2").End(xlDown).Row)
    Set Plage_TVF = Range("A2:A" & Range("A2").End(xlDown).Row)
    For I = Plage_nom.Cells.Count To 2 Step -1
        Plage_nom.Cells(I).Value = UCase(Plage_nom.Cells(I).Value)
        Plage_nom.Cells(I - 1).Value = UCase(Plage_nom.Cells(I - 1).Value)
        Plage_prenom.Cells(I).Value = UCase(Plage_prenom.Cells(I).Value)
        Plage_prenom.Cells(I - 1).Value = UCase(Plage_prenom.Cells(I - 1).Value)
        Plage_adresse.Cells(I).Value = UCase(Plage_adresse.Cells(I).Value)
        Plage_adresse.Cells(I - 1).Value = UCase(Plage_adresse.Cells(I - 1).Value)
        Plage_TVF.Cells(I).Value = UCase(Plage_TVF.Cells(I).Value)
        Plage_TVF.Cells(I - 1).Value = UCase(Plage_TVF.Cells(I - 1).Value)
        
        If Plage_nom.Cells(I).Value = Plage_nom.Cells(I - 1).Value And Plage_prenom.Cells(I).Value = Plage_prenom.Cells(I - 1).Value And Plage_adresse.Cells(I).Value = Plage_adresse.Cells(I - 1).Value Then
            Rows(I + 1).Delete
        End If
        'suppression si meme nom prenom adresse
        
        Rows(I).Interior.ColorIndex = 6
        'Ligne déjà traité JAUNE FONCé
        
        If Plage_nom.Cells(I).Value = Plage_nom.Cells(I - 1).Value And Plage_prenom.Cells(I).Value = Plage_prenom.Cells(I - 1).Value And Plage_adresse.Cells(I).Value <> Plage_adresse.Cells(I - 1).Value And Plage_TVF.Cells(I).Value <> Plage_TVF.Cells(I - 1).Value Then
            Rows(I + 1).Interior.ColorIndex = 40
            Rows(I).Interior.ColorIndex = 22
        End If
        'adresse diffère ROSE
                
        If Plage_nom.Cells(I).Value = Plage_nom.Cells(I - 1).Value And Plage_prenom.Cells(I).Value <> Plage_prenom.Cells(I - 1).Value And Plage_adresse.Cells(I).Value = Plage_adresse.Cells(I - 1).Value And Plage_TVF.Cells(I).Value <> Plage_TVF.Cells(I - 1).Value Then
            Rows(I + 1).Interior.ColorIndex = 20
            Rows(I).Interior.ColorIndex = 42
        End If
        'prénom diffère BLEU
        
        If (Plage_nom.Cells(I).Value <> Plage_nom.Cells(I - 1).Value Or Plage_TVF.Cells(I).Value <> Plage_TVF.Cells(I - 1).Value) And Plage_prenom.Cells(I).Value = Plage_prenom.Cells(I - 1).Value And Plage_adresse.Cells(I).Value = Plage_adresse.Cells(I - 1).Value Then
            Rows(I + 1).Interior.ColorIndex = 34
            Rows(I).Interior.ColorIndex = 36
        End If
        'Nom ou TVF Différent JAUNE
        
    Next
End Sub


Merci pour tout et à bientôt.
0
Kevin
 
Salut je veux juste te dire que dans exel il une fonction filtre avance et qu'il a une case a coché pour qu'il supprime les doublons lui meme
0
Terek > Kevin
 
Bonjour Kevin.

L'option filtre avancé n'était pas très pratique pour le fonctionnement que je voulais en faire.

De toute facon, j'ai quitté ce stage car à par travailler sur des tableaux excel je ne fesai rien d'autre. Pas que ca me déplaise vraiment mais pour un stage en communication publicitaire, allez voir le rapport...
0
aurelii
 
Salut !

J'ai quasiment la meme problématique que toi : je dois créer pour la premiere fois une macro permettant de faire un tri, une mise en page puis de supprimer les doublons. Pour la 1ère partie cela va sans probleme j'ai pu créer un bouton de commande adapté mais pr la suite je bloque depuis des heures !!!

A quoi correspond le I dans ta base de données?
0
Terek
 
Wow pas facile de se remettre la dedans plus d'un an après lol.

En fait I est un nombre qui désigne le numéro de la ligne. C'est un nombre qui varie entre Plage_nom.Cells.Count (le nombre de ligne totale de mon tableau) et 2 (la première ligne étant destiné à mes titre de colonnes).

Après si je me rappelle bien, je triai mes colonnes par ordre alpha des noms, ensuite des prénom (pour ceux qui ont le meme nom) puis les adresse (pour meme nom et meme prénom).
Ma macro :
- Met en Majuscule
- Si une personne avait meme nom, prénom et adresse, c'est que c'était la meme donc elle était supprimée.
- Si elle avait meme nom, prénom et pas meme adresse, c'était en général qu'elle avait changé et donc il me coloriait les 2 ligne et je vérifiait l'adresse.
- Si meme nom et meme adresse, mais prénom différent les lignes étaient aussi coloriées mais d'une autre couleur et je vérifiait qu'il n'y ai pas d'erreur.

Je ne fais du tout de macro excel donc je laisserai aux pro d'ici le soin de peut être mieux répondre à ton interrogation. En attendant j'espère t'avoir aider au mieux.
0
bastouf
 
Bonjour Terek,

Surement coincidence mai je suis dans une boite qui organise des evenements médical et j'ai un souci avec un macro de supression de doublon qui marche sur office 2003 SP2 mais pas sur office 2003 SP3 ni sur office 2007. J'aurais donc voulut savoir si il était possible de mettre à jours ce macro pour le faire fonctionner au moin sous 2003 SP3. A tu fais face à ce genre de problème?

Merci d'avance pour ton aide
0
AmineTLS31
 
Sinon y a cette Macro que je viens de faire plus simple - faut juste trier la colonne par ordre alphabétique avant de lancer la macro :

Sub doublons()

'Première cellule de la liste qui contient les doublons - Cellule A2 dans cet exemple

Sheets("feuil1").Cells(2, 1).Activate

Do
If ActiveCell.Value = ActiveCell.Offset(1, 0).Value Then
ActiveCell.EntireRow.Delete
Else
ActiveCell.Offset(1, 0).Activate
End If
Loop Until ActiveCell.Offset(1, 0).Value = ""

End Sub

Bon Courage
0