Microsoft 365 Créer un dictionnaire sans doublon

Goufra

XLDnaute Occasionnel
Bonjour à tous,

je suis l’hérétique de service, J’ai créé un dictionnaire avec doublons !
Je souhaite à partir de ce dictionnaire créer un dictionnaire sans doublon

C’est pour le fun je sais le créer à partir d’une plage

Donc voici le code qui ne fonctionne pas


Sub nefonctionnepas() '
For Each c In DavecDoublons.Keys

DsansDoublon(c.Value) = ""

MsgBox c

Next c
End Sub

pièce jointe

C’est surtout pour faire marcher ma boîte à malices et éviter qu’elle ne se grippe ! Et je cherche à comprendre le fonctionnement d'un dictionnaire.
Avec mes sincères remerciements anticipés .
Goufra
 

Pièces jointes

  • 0000 Goufra.xlsm
    31.2 KB · Affichages: 20

mapomme

XLDnaute Barbatruc
Supporter XLD
Mais pour la 4eme question qui doit avoir les noms et prenoms en commun,
Pour cette question, nous voulons le nombre d'individu.
Un individu est identifié par son nom ET de son prénom.
La clef servant à repérer un individu de manière univoque sera donc une combinaison de son nom et de son prénom.
Dans la procédure du module1, on utilise pour clef la concaténation du nom, du séparateur "_" et du prénom.
Cela se traduit par : la clef = Nom & "_" & Prénom. Patrick Toulon aura pour clef "Toulon_Patrick" :D.

Voir le code commenté dans module1. La colonne des individus (sans doublons) est la colonne L.
 

Pièces jointes

  • fronck- dictionary- v2.xlsm
    214.8 KB · Affichages: 6
Dernière édition:

mapomme

XLDnaute Barbatruc
Supporter XLD
Re,

Un autre code qui cette fois donne aussi de l'importance à l'item associé à chaque clef.

Nous avons des individus repérés par leur nom qui passent des tests. Un individu peut passer plusieurs tests.
Chaque test est sanctionné par un résultat qui est un nombre.
Pour chaque individu, on veut savoir quel est résultat maximum qu'il a obtenu parmi tous les tests qu'il a passés.
Comme résultat du traitement, on veut la liste des individus avec en face la note maximum obtenue à leurs tests.

Le code est dans module1. Il est commenté.
 

Pièces jointes

  • fronck- dictionary- v3.xlsm
    182.9 KB · Affichages: 7
Dernière édition:

fronck

XLDnaute Junior
Merci pour les exemples mapomme,
Si je reprends l'exemple de mes deux listes indépendantes de noms:
- la 1ere une liste de tout le personnel.
- la 2éme pour les absents.
Je cherche à obtenir les présents avec ce code.
VB:
Sub absentsPresents()
Dim t, u, der&, dico, i&, j&, maClef As String, v
   With Sheets("liste")
      If .FilterMode Then .ShowAllData
      der = .Cells(Rows.Count, "a").End(xlUp).Row
      t = .Range("a1:a" & der)
      u = .Range("b1:b" & der)
      Set dico = CreateObject("scripting.dictionary")
      dico.CompareMode = TextCompare
      For i = 2 To UBound(t)
        For j = 2 To UBound(u)
           If t(i, 1) <> "" Then
              If Not dico.exists(t(j, 2)) Then
                 dico.Add t(i, 3)
               End If
            End If
        Next j
      Next i
      Application.ScreenUpdating = False
      .Range("J2:K" & Rows.Count).ClearContents
      .Range("C2") = dico.Count
      If dico.Count > 0 Then
         .Range("C2").Resize(dico.Count) = Application.Transpose(dico.Keys)
         .Range("C2").Resize(dico.Count).Sort key1:=.Range("J3"), order1:=xlAscending, MatchCase:=False, Header:=xlNo
      End If
   End With
End Sub
Cà ne passe plus :(
1681352105147.png
 

Pièces jointes

  • fronck- dictionary- v1.xlsm
    222.3 KB · Affichages: 7

patricktoulon

XLDnaute Barbatruc
Bonjour
tu m’étonne que ça ne marche pas et surtout que ca plante
ta variable tableau "u" ne fait qu'une colonne
u = .Range("b1:b" & der)

et toi tu teste la ligne j en colonne 2
If Not dico.exists(t(j, 2)) Then


et c'est pas du tout comme ça qu'il faut faire
si tes absents sont en colonne B pour ne garder que les présents , il suffit de tester avec match le nom de A sur b avant de le rentrer dans le dico
 

patricktoulon

XLDnaute Barbatruc
re
je pense que tu t'es compliqué la vie

VB:
Option Explicit

Sub presentsV1()
    Dim t, der&, dico, i&, absents, X

    With Sheets("liste")
        'der est la liste est le nombre de ligne de la base
        If .FilterMode Then .ShowAllData
        der = .Cells(Rows.Count, "a").End(xlUp).Row
        't est le tableau des valeurs sources
        t = .Range("a1:c" & der)
        absents = Application.Transpose(Application.Index(t, 0, 2))

        'on crée le dictionary  dico
        Set dico = CreateObject("scripting.dictionary")

        dico.CompareMode = TextCompare

        For i = 2 To UBound(t)
            With Application: X = .IfError(.Match(t(i, 1), absents, 0), 0): End With
            If X = 0 Then dico(t(i, 1)) = ""
        Next
        .Range("C2").Resize(dico.Count) = Application.Transpose(dico.Keys)
    End With
End Sub
demo.gif
 

Goufra

XLDnaute Occasionnel
Bonjour,
Le temps que je comprenne le code du fichier fronck- dictionary- v3, un certain temps.
Je souhaite remercier Mapomme pour ses explications détaillées.
Je les ai reprises. J'ai aéré la présentation pour quelles soient plus lisibles.. Format pdf joint
Bonne journée.
 

Pièces jointes

  • Dictionnary quelques explications pour comprendre son fonctionnement.pdf
    661.2 KB · Affichages: 9

mapomme

XLDnaute Barbatruc
Supporter XLD
Bonsoir @fronck ;), à tous :),
Si je reprends l'exemple de mes deux listes indépendantes de noms:
- la 1ere une liste de tout le personnel.
- la 2éme pour les absents.
Je cherche à obtenir les présents avec ce code.

Si on ne veut utiliser qu'un seul tableau et qu'un seul dictionary, on peut coder comme ceci :
VB:
Sub absentsPresents()
Dim t, der&, dico, i&
   Set dico = CreateObject("scripting.dictionary"): dico.CompareMode = TextCompare
   With Sheets("liste")
      If .FilterMode Then .ShowAllData
   
      der = .Cells(Rows.Count, "a").End(xlUp).Row: t = .Range("a1:a" & der +1 )
      For i = 2 To UBound(t)
         If t(i, 1) <> "" Then If Not dico.exists(t(i, 1)) Then dico.Add t(i, 1), ""
      Next i
   
      der = .Cells(Rows.Count, "b").End(xlUp).Row: t = .Range("b1:b" & der + 1)
      For i = 2 To UBound(t)
         If t(i, 1) <> "" Then If dico.exists(t(i, 1)) Then dico.Remove t(i, 1)
      Next i
   
      .Range("c2:c" & Rows.Count).ClearContents
      If dico.Count > 0 Then .Range("c2").Resize(dico.Count) = Application.Transpose(dico.Keys)
   End With
End Sub
 
Dernière édition:

mapomme

XLDnaute Barbatruc
Supporter XLD
Bonjour @fronck,
C'est pour faire quoi ce "" à la fin.
dico.Add sert à ajouter une clef et la valeur associée à cette clef.
La méthode Add utilise deux arguments : une clef et une valeur.
Ici la valeur nous importe peu alors on la fixe comme étant la chaine de caractère vide. On aurait aussi pu écrire : dico.Add clef,123 (la valeur aurait été 123 mais comme on ne l'utilise pas, l'important c'est juste qu'elle soit présente...)

Un extrait de l'aide de Microsoft :
1681448181118.png
 
Dernière édition:

Discussions similaires

Statistiques des forums

Discussions
314 628
Messages
2 111 325
Membres
111 102
dernier inscrit
driss touzi