Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

Une fonction (VBA) qui repère s'il y a un ou des doublons

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

Magic_Doctor

XLDnaute Barbatruc
Supporter XLD
Bonsoir,

Je suis à la recherche d'une fonction qui, comme il est stipulé dans le titre du fil, recherche, dans une plage de cellule, s'il y a ou pas un ou des doublons. Supposons que nous nommions cette fonctions "Doublons" :
VB:
Sub Function Doublons (plage As Range) As Boolean

	blablabla

End Function
La fonction renvoyant uniquement "True" ou "False" suivant qu'il y ait ou pas un ou des doublons.

Merci pour toute aide.
 
Re : Une fonction (VBA) qui repère s'il y a un ou des doublons

Bonjour Magic_Doctor.


Peut-être ceci ?​
VB:
Function Doublons(plage As Range) As Boolean
'Nécessite l'ajout de la bibliothèque Microsoft Scripting Runtime au projet.
Dim Cel As Range, Dic As New Dictionary
    On Error GoTo E
    For Each Cel In plage.Cells: Dic.Add CStr(Cel.Value), True: Next
Exit Function
E:  Doublons = True
End Function



ROGER2327
#6767


Jeudi 12 Phalle 140 (Sainte Andouille, amphibologue - fête Suprême Quarte)
5 Fructidor An CCXXI, 0,2743h - saumon
2013-W34-4T00:39:30Z
 
Re : Une fonction (VBA) qui repère s'il y a un ou des doublons

Bonjour Magic_Doctor,

Un essai dans le fichier joint.

La fonction peut s'écrire:=Doublons(Plage1 [;Plage2;...;Plage n ] [;MinMajDiff = VRAI ou FAUX])
.
  • =doublons(A1:A6;A9:A11;C3:C8) recherche si doublon(s) (ne distingue pas les majuscules des minuscules)
  • =doublons(A1:A6;A9:A11;C3:C8;FAUX) recherche si doublon(s) (ne distingue pas les majuscules des minuscules)
  • =doublons(A1:A6;A9:A11;C3:C8;VRAI) recherche si doublon(s) (distingue les majuscules des minuscules)

Si le dernier paramètre est VRAI: on distingue les majuscules des minuscules ( A est différent de a)

Si le dernier paramètre est FAUX ou non indiqué: on ne distingue pas les majuscules des minuscules ( A est égal à a)

En fait l'écriture minimale est : Doublons(plage1) qui recherche les doublons sur une plage unique en faisant fi de la casse et des cellules vides.

Dans tous les cas, on ne prend pas en compte les cellules vides.

VB:
Public Function Doublons(ParamArray Plages()) As Boolean
Dim dico As New Scripting.Dictionary, xplage, xrg As Range
Dim Nmax As Long, MinMajDiff As Boolean, i As Long, S As String

If VarType(Plages(UBound(Plages))) = vbBoolean Then
  Nmax = UBound(Plages) - 1
  MinMajDiff = Plages(UBound(Plages))
Else
  Nmax = UBound(Plages)
  MinMajDiff = False
End If
  
For i = LBound(Plages) To Nmax
  For Each xrg In Plages(i)
    S = CStr(xrg)
    If Not MinMajDiff Then S = LCase(S)
    If Not S = "" Then
      If dico.Exists(S) Then
        Doublons = True
        Exit Function
      Else
        dico(S) = ""
      End If
    End If
  Next xrg
Next i

End Function

Edit : tout comme ROGER2327 que je salue 🙂 , il faut une référence à Microsoft Scripting Runtime pour utiliser les structures Dictionary.
 

Pièces jointes

Dernière édition:
Re : Une fonction (VBA) qui repère s'il y a un ou des doublons

Suite...
Bonjour mapomme.


Avec le paramétrage que vous décrivez, je propose :​
VB:
Function Doublons2(ParamArray Plages()) As Boolean 'Ignore les cellules vides.
'Nécessite l'ajout de la bibliothèque Microsoft Scripting Runtime au projet.
Dim i&, Mm As Boolean, Tf As Boolean, Cel As Range, Dic As New Dictionary
    Tf = VarType(Plages(UBound(Plages))) = vbBoolean
    If Tf Then Mm = Plages(UBound(Plages))
    For i = LBound(Plages) To UBound(Plages) + Tf
        On Error GoTo E
        If Mm Then
            For Each Cel In Plages(i).Cells
                If Not IsEmpty(Cel.Value) Then Dic.Add CStr(Cel.Value), True
            Next
        Else
            For Each Cel In Plages(i).Cells
                If Not IsEmpty(Cel.Value) Then Dic.Add UCase(CStr(Cel.Value)), True
            Next
        End If
    Next
Exit Function
E:  Doublons2 = True
End Function


ROGER2327
#6768


Jeudi 12 Phalle 140 (Sainte Andouille, amphibologue - fête Suprême Quarte)
5 Fructidor An CCXXI, 0,9264h - saumon
2013-W34-4T02:13:24Z
 
Dernière édition:
Re : Une fonction (VBA) qui repère s'il y a un ou des doublons

Suite...


Peut-être un poil plus rapide :​
VB:
Function Doublons3(ParamArray Plages()) As Boolean 'Ignore les cellules vides.
'Nécessite l'ajout de la bibliothèque Microsoft Scripting Runtime au projet.
Dim i&, Mm As Boolean, Tf As Boolean, Cel As Range, Dic As New Dictionary
    Tf = VarType(Plages(UBound(Plages))) = vbBoolean
    If Tf Then Mm = Plages(UBound(Plages))
    On Error GoTo E
    If Mm Then
        For i = LBound(Plages) To UBound(Plages) + Tf: For Each Cel In Plages(i).Cells
            If Not IsEmpty(Cel.Value) Then Dic.Add CStr(Cel.Value), True
        Next Cel, i
    Else
        For i = LBound(Plages) To UBound(Plages) + Tf: For Each Cel In Plages(i).Cells
            If Not IsEmpty(Cel.Value) Then Dic.Add UCase(CStr(Cel.Value)), True
        Next Cel, i
    End If
Exit Function
E:  Doublons3 = True
End Function



ROGER2327
#6769


Jeudi 12 Phalle 140 (Sainte Andouille, amphibologue - fête Suprême Quarte)
5 Fructidor An CCXXI, 1,0307h - saumon
2013-W34-4T02:28:25Z
 
Re : Une fonction (VBA) qui repère s'il y a un ou des doublons

Bonsoir à tous, et tout d’abord merci à Roger & mapomme.

Sujet intéressant non tant par la demande mais par les réponses.
Dans mon application j’utilise souvent le « Dictionary » sans problèmes jusqu’à présent.
J’essaie la fonction de ROGER2327 :
VB:
Function Doublons(plage As Range) As Boolean
'Vérifie si dans une plage il y a ou pas un ou des doublons
'ROGER2327
Dim Cel As Range, Dic As New Dictionary
On Error GoTo E
For Each Cel In plage.Cells: Dic.Add CStr(Cel.Value), True: Next
Exit Function
E:  Doublons = True
End Function
Ça plante (Traduction : “Erreur de compilation : le type défini par l’usager n’a pas été défini“).
mapomme précise bien qu’il faut une référence à Microsoft Scripting Runtime pour utiliser les structures Dictionary. J’avoue, au passage, que les concepteurs de ce programme nous les cassent un peu dans certains paramétrages préalables pour que tout marche correctement. Je n’ai toujours pas compris pourquoi ils ne l’étaient pas d’emblée et que l’on n’en parle plus !
Bref, je ne me pose pas de question et modifie un chouïa la fonction de Roger :
VB:
Function Doublons(plage As Range) As Boolean
'Vérifie si dans une plage il y a ou pas un ou des doublons
'ROGER2327
Dim Cel As Range, Dic As Object
Set dico = CreateObject("Scripting.Dictionary")
On Error GoTo E
For Each Cel In plage.Cells: Dic.Add CStr(Cel.Value), True: Next
Exit Function
E:  Doublons = True
End Function
Et là ça marche !
Avant même de poser cette question sur ce fil, je me demandais si la présence de cellules vierges n’interfèreraient pas dans la recherche de doublons. Aussi, j’ai rédigé une petite fonction pour que la recherche ne se fasse que dans le segment du tableau où il y a des cellules qui contiennent quelque chose :
VB:
Function PlagePleine(plage As Range) As String
'Renvoie l'adresse de la plage non vide d'un tableau
'Magic_Doctor
Dim nbtotallgn As Integer, nblgnvides As Integer
nbtotallgn = plage.Rows.Count
nblgnvides = WorksheetFunction.CountBlank(plage)
PlagePleine = plage.Rows(1).Resize(nbtotallgn - nblgnvides).Address
End Function
Je précise, au passage, que dans mon application toutes les cellules non vides du tableau sont contiguës quoi qu’il arrive (si on effaçait le contenu de l’une des cellules, automatiquement l’ensemble des autres cellules au-dessous serait déplacé d’une ligne vers le haut).

Pour finalement combiner les 2 fonctions dans cet exemple de macro :
VB:
Sub Tralala()
'La recherche se fait dans la 1ère colonne d'une plage nommée "ListeItems1"
[S9] = Doublons(Range(PlagePleine([ListeItems1].Columns(1)))) 'vérifie (cellule "S9") la présence ou pas de doublon(s) uniquement dans les cellules non vides du tableau "LiteItems1"
End Sub
En tout cas, merci pour votre aide.

PS : comment fait donc Roger pour mettre autant de couleurs dans ses exemples de routines ? C’est bô !
 
Dernière édition:
Re : Une fonction (VBA) qui repère s'il y a un ou des doublons

Rebonsoir Roger, nos posts se sont croisés…

Par rapport à votre 1ère solution, que j’ai un peu modifiée, quel serait l’avantage de votre dernière solution ?
 
Re : Une fonction (VBA) qui repère s'il y a un ou des doublons

Re...


(...)
PS : comment fait donc Roger pour mettre autant de couleurs dans ses exemples de routines ? C’est bô !
Balisage :

[CODE=vb]
----'Le code...
[/CODE]



C'est trop beau. Grave !​


ROGER2327
#6771


Jeudi 12 Phalle 140 (Sainte Andouille, amphibologue - fête Suprême Quarte)
5 Fructidor An CCXXI, 5,5114h - saumon
2013-W34-4T13:13:39Z
 
Re : Une fonction (VBA) qui repère s'il y a un ou des doublons

Oun essai para la rigolada.
VB:
Function Doublons(plage As Range) As Boolean
'Vérifie si dans une plage il y a ou pas un ou des doublons
'ROGER2327
Dim Cel As Range, Dic As Object
Set dico = CreateObject("Scripting.Dictionary")
On Error GoTo E
For Each Cel In plage.Cells: Dic.Add CStr(Cel.Value), True: Next
Exit Function
E:  Doublons = True
End Function
C'est vrai que c'est + trop bô !

Muchas gracias Roger, estoy chocho!
 
Dernière édition:
Re : Une fonction (VBA) qui repère s'il y a un ou des doublons

Re...


Rebonsoir Roger, nos posts se sont croisés…

Par rapport à votre 1ère solution, que j’ai un peu modifiée, quel serait l’avantage de votre dernière solution ?
Dans la dernière solution, la valeur de Mm est moins souvent testée.
Quant à votre modification, elle est astucieuse. Personnellement, je me méfie un peu de la notion de blank vue par le Bill's Band. Mais j'ai probablement tort...

Ceci dit, voici une version plus courte de mes propositions précédentes :​
VB:
Function Doublons(ParamArray Plages()) As Boolean 'Ignore les cellules vides.
'Nécessite l'ajout de la bibliothèque Microsoft Scripting Runtime au projet.
Dim i&, Cel As Range, Dic As New Dictionary
    i = UBound(Plages)
    If VarType(Plages(i)) = 11 Then Dic.CompareMode = -Not Plages(i): i = i - 1 Else Dic.CompareMode = 1
    On Error GoTo E
    For i = 0 To i: For Each Cel In Plages(i).Cells
        If Not IsEmpty(Cel.Value) Then Dic.Add CStr(Cel.Value), True
    Next Cel, i
Exit Function
E:  Doublons = True
End Function
Si on est certain, comme vous, de n'avoir pas de cellule vide dans les plages à contrôler :​
VB:
Function Doublons(ParamArray Plages()) As Boolean 'N'ignore pas les cellules vides.
'Nécessite l'ajout de la bibliothèque Microsoft Scripting Runtime au projet.
Dim i&, Cel As Range, Dic As New Dictionary
    i = UBound(Plages)
    If VarType(Plages(i)) = 11 Then Dic.CompareMode = -Not Plages(i): i = i - 1 Else Dic.CompareMode = 1
    On Error GoTo E
    For i = 0 To i: For Each Cel In Plages(i).Cells: Dic.Add CStr(Cel.Value), True: Next Cel, i
Exit Function
E:  Doublons = True
End Function


Bonne nuit.


ROGER2327
#6772


Jeudi 12 Phalle 140 (Sainte Andouille, amphibologue - fête Suprême Quarte)
5 Fructidor An CCXXI, 7,5389h - saumon
2013-W34-4T18:05:36Z
 
Dernière édition:
Re : Une fonction (VBA) qui repère s'il y a un ou des doublons

Bonsoir ROGER2327,

Pas pu répondre avant.
Merci pour ces modifications intéressantes. Mais ayant encore des progrès à accomplir (largo es el camino...), j'avoue que certaines sentences me déconcertent, comme : Dic.CompareMode = -Not
Comme précédemment, j'ai fait la petite modification suivante :
VB:
Function Doublons(ParamArray Plages()) As Boolean
'Vérifie si dans une plage il y a ou pas un ou des doublons (ignore les cellules vides)
'ROGER2327
    Dim i&, Cel As Range, dico As Object
    Set dico = CreateObject("Scripting.Dictionary")
        i = UBound(Plages)
        If VarType(Plages(i)) = 11 Then dico.CompareMode = -Not Plages(i): i = i - 1 Else dico.CompareMode = 1
        On Error GoTo E
        For i = 0 To i: For Each Cel In Plages(i).Cells
            If Not IsEmpty(Cel.Value) Then dico.Add CStr(Cel.Value), True
        Next Cel, i
    Exit Function
E:  Doublons = True
End Function
Bien que la fonction que j'avais rédigée soit maintenant superflue, j'en ai quand même profité pour la simplifier :
VB:
Function PlagePleine(plage As Range) As String
'Renvoie l'adresse de la plage non vide d'un tableau dont les lignes pleines sont toujours contiguës
'Magic_Doctor
    Dim nblgnfull As Integer
    nblgnfull = WorksheetFunction.CountA(plage) 'décompte du nombre de lignes pleines de la plage "plage"
    PlagePleine = plage.Rows(1).Resize(nblgnfull).Address
End Function
Buenas noches
 
Re : Une fonction (VBA) qui repère s'il y a un ou des doublons

Bonjour Magic_Doctor, mapomme, Roger,

Je n'avais pas vu ce fil mais pourquoi pas cette formule très classique :

Code:
=SIGNE(LIGNES(Plage)*COLONNES(Plage)-SOMMEPROD(1/NB.SI(Plage;Plage)))
avec la cellule au format personnalisé "Oui";;"Non"

Cette fonction VBA ne fait que retranscrire la formule précédente :

Code:
Function Doublons(plage As Range) As Byte
Dim a$
a = plage.Address
Doublons = Evaluate("SIGN(ROWS(" & a & ")*COLUMNS(" & a & ")-SUMPRODUCT(1/COUNTIF(" & a & "," & a & ")))")
End Function
Fichier joint.

A+
 

Pièces jointes

Re : Une fonction (VBA) qui repère s'il y a un ou des doublons

Re,

La fonction VBA est plus simple dans ce fichier (2) :

Code:
Function Doublons(P As Range) As Byte
Doublons = Sgn(P.Count - Evaluate("SUMPRODUCT(1/COUNTIF(" & P.Address & "," & P.Address & "))"))
End Function
A+
 

Pièces jointes

Re : Une fonction (VBA) qui repère s'il y a un ou des doublons

Bonjour à tous, bonjour Magic_Doctor.


En fait, l'instruction complète est :​
VB:
dico.CompareMode = -Not Plages(i)
Dans le contexte, la valeur de Plages(i) est un booléen. On a alors :


[table="width: 500, class: grid, align: center"]
[tr]
[td]
Plages(i)
[/td]
[td]
Not Plages(i)
[/td]
[td]
-Not Plages(i)
[/td]
[td]
dico.CompareMode
[/td]
[/tr]
[tr]
[td]
False​
[/td]
[td]
True​
[/td]
[td]
1​
[/td]
[td]
vbTextCompare​
[/td]
[/tr]
[tr]
[td]
True​
[/td]
[td]
False​
[/td]
[td]
0​
[/td]
[td]
vbBinaryCompare​
[/td]
[/tr]
[/table]


Ce qui fixe le mode de comparaison des chaînes de caractères pour ne pas distinguer, ou distinguer, les minuscules des majuscules.​


Bonne journée.


ROGER2327
#6785


Jeudi 19 Phalle 140 (Prélote, capucin - fête Suprême Quarte)
12 Fructidor An CCXXI, 3,7011h - fenouil
2013-W35-4T08:52:57Z
 
Re : Une fonction (VBA) qui repère s'il y a un ou des doublons

Re,

En fait c'était bien plus simple... Il suffisait de compter les NB.SI(Plage;Plage)>1...

Fichier (3) avec des blancs, des nombres et des textes :

Code:
=SIGNE(SOMMEPROD((Plage<>"")*(NB.SI(Plage;Plage)>1)))
Code:
Function Doublons(plage As Range) As Byte
Dim a$
a = plage.Address
Doublons = Sgn(Evaluate("SUMPRODUCT((" & a & "<>"""")*(COUNTIF(" & a & "," & a & ")>1))"))
End Function
A+
 

Pièces jointes

Dernière édition:
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…