IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Comparer 2 colonnes ADODB vs Dictionnaire [XL-2007]


Sujet :

Macros et VBA Excel

  1. #41
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Points : 12 068
    Points
    12 068
    Billets dans le blog
    8
    Par défaut re
    Bonjour mercatog

    Je viens de préciser à oliv pour quoi je ne fais pas une 2 ème boucle.

    La condition de l'un dans l'autre et l'autre dans l'un peut parfaitement être dans la même. On bouclerait sur une variable jusqu'à "fin" à la place de ubound(mondico), car fin et le nombre d'item dans les 2 tablos et 2 dicos et de lignes prises en compte dans les sheets.

    Et pour les tableaux plus cours au cas ou un sheet aurait moins de données.
    Si tu regardes bien j'utilise la même variable "fin" pour les deux dico et tablo
    même s'il y a des vides.

    Cela peut certainement générer une erreur sur mon dernier code, je viens de rectifier ce point.

  2. #42
    Expert éminent
    Avatar de Oliv-
    Homme Profil pro
    solution provider
    Inscrit en
    Mars 2006
    Messages
    4 087
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : solution provider

    Informations forums :
    Inscription : Mars 2006
    Messages : 4 087
    Points : 7 168
    Points
    7 168
    Billets dans le blog
    20
    Par défaut
    Je viens de préciser à oliv pour quoi je ne fais pas une 2 ème boucle.
    sauf que j'ai rien compris et que ton code ne fonctionne pas vraiment avec des doublons

    essaye avec ce générateur de données !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    Sub création_sources_V2()
     
        Worksheets("Feuil1").Cells.Delete
        Worksheets("Feuil2").Cells.Delete
        Dim maSource1(20000)
        Dim i
        maSource1(0) = "siren"
        For i = 1 To 20000
            If Right(CStr(i), 2) = "10" Then
                'création doublon
                maSource1(i) = CStr(100000000 + i - 10)
            Else
                maSource1(i) = CStr(100000000 + i)
            End If
        Next i
        Worksheets("Feuil1").Range("A1").Resize(UBound(maSource1) + 1) = Application.Transpose(maSource1)
     
        Dim maSource2(4000)
        maSource2(0) = "siren"
        For i = 5 To 20000 Step 5
            If Right(CStr(i), 1) = "0" Then
     
                maSource2(i / 5) = CStr(100000000 + i)
            'création doublon
            ElseIf Right(CStr(i), 2) = "20" Then
                maSource2(i / 5) = CStr(100000000 - i)
            Else
                maSource2(i / 5) = CStr(200000000 + i)
            End If
        Next i
        Worksheets("Feuil2").Range("A1").Resize(UBound(maSource2) + 1) = Application.Transpose(maSource2)
     
     
    End Sub
    il se peut par exemple qu'il n'y ai aucun commun.

  3. #43
    Expert éminent sénior Avatar de mercatog
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    9 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations forums :
    Inscription : Juillet 2008
    Messages : 9 435
    Points : 31 877
    Points
    31 877
    Par défaut
    Pour toi et ton code, il n'aurait pas de ko dans Tablos2

  4. #44
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Points : 12 068
    Points
    12 068
    Billets dans le blog
    8
    Par défaut re
    re

    Voilà maintenant il peut y avoir une liste plus courte que l'autre.
    Les tests dico1 dans dico2 et l'inverse sont bien dans la même boucle.
    Le résultat se trouve bien sur les deux pages et chez moi il n'y a pas d'erreur.
    Dans la colonne b de la feuille tu as ko ou ok et la ligne de son jumeau dans l'autre feuille et vice versa(feuil1 et feuil2)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
     
    Sub DictionnaireV3()
        T = Timer
        Dim k1, k2, i1, i2, n, i, fin, tablos1, tablos2
        Set mondico = Nothing
        Set mondico2 = Nothing
        Set mondico = CreateObject("Scripting.Dictionary")
        Set mondico2 = CreateObject("Scripting.Dictionary")
        If Sheets(1).Range("a" & Rows.Count).End(xlUp).Row > Sheets(2).Range("a" & Rows.Count).End(xlUp).Row Then
            fin = Sheets(1).Range("a" & Rows.Count).End(xlUp).Row
        Else
            fin = Sheets(2).Range("a" & Rows.Count).End(xlUp).Row
        End If
        tablos1 = Range(Sheets(1).Range("A1"), Sheets(1).Cells(fin, 2))
        tablos2 = Range(Sheets(2).Range("A1"), Sheets(2).Cells(fin, 2))
        'on a pris le plus grand nombre de lignes utilisé pour les feuilles 1 et 2
        For i = 1 To fin
            'au cas ou il y aurait des cellules vides ce qui était hors de question dans tes posts précédents tu l'avais même précisé dans un exemple précédent
            If tablos1(i, 1) = "" Then tablos1(i, 1) = "vide" & i
            If tablos2(i, 1) = "" Then tablos2(i, 1) = "vide" & i + 1    'au cas ou les deux sheets aient la même ligne vide
            mondico.Add tablos1(i, 1), i                     'avec les clés en colonne A, les valeurs en colonne B
            mondico2.Add tablos2(i, 1), i                  'avec les clés en colonne A, les valeurs en colonne B
            'quoi que là on aurait pu même le faire avant avec le filtre spécial et natif avant de faire les tableaux pour les cellules vides.
        Next
        k1 = mondico.keys
        i1 = mondico.items
        k2 = mondico2.keys
        i2 = mondico2.items
     
        For n = 0 To fin - 1
            'comparaison dans dico2
            If mondico2.exists(k1(n)) Then
                tablos1(mondico.Item(k1(n)), 2) = "ok en lig : " & mondico2.Item(k1(n))
            Else
                tablos1(mondico.Item(k1(n)), 2) = "ko"
            End If
     
            'comparaison dans dico1
            If mondico.exists(k2(n)) Then
                tablos2(mondico2.Item(k2(n)), 2) = "ok en lig : " & mondico.Item(k2(n))
            Else
                tablos2(mondico2.Item(k2(n)), 2) = "ko"
            End If
     
            'MsgBox "les lignes communes sont " & vbCrLf & "pour la feuill1 c'est la ligne :" & mondico.Item(k1(n)) & vbCrLf & "pour la feuill2 c'est la ligne :" & mondico2.Item(k1(n))
        Next
        Sheets(1).Range("A1:b" & fin) = tablos1
        Sheets(2).Range("A1:b" & fin) = tablos2
     
        MsgBox Timer - T
    End Sub
    et pour finir si les (vide X )ne te plaisent pas tu peux les supprimer avec un filtre spécial natif d'Excel.
    Et je le répète: chez moi je n'ai pas d'erreur. J'aime pas le jaune de toute façon.
    alors ???

  5. #45
    Expert éminent
    Avatar de Oliv-
    Homme Profil pro
    solution provider
    Inscrit en
    Mars 2006
    Messages
    4 087
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : solution provider

    Informations forums :
    Inscription : Mars 2006
    Messages : 4 087
    Points : 7 168
    Points
    7 168
    Billets dans le blog
    20
    Par défaut
    Toujours pareil ça plante avec les doublons !!
    Quel jeu de données utilises tu ?

  6. #46
    Expert éminent
    Avatar de Oliv-
    Homme Profil pro
    solution provider
    Inscrit en
    Mars 2006
    Messages
    4 087
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : solution provider

    Informations forums :
    Inscription : Mars 2006
    Messages : 4 087
    Points : 7 168
    Points
    7 168
    Billets dans le blog
    20
    Par défaut
    Citation Envoyé par mercatog Voir le message
    Pour toi et ton code, il n'aurait pas de ko dans Tablos2
    Désolé je n'ai pas compris le sens de ta réponse!

  7. #47
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Points : 12 068
    Points
    12 068
    Billets dans le blog
    8
    Par défaut re
    J'utilise une boucle avec rnd pour genérer des nombres aléatoires.

    Avec un comparateur (variable string au cas ou il serait déjà passé)
    je n'ai donc pas de doublons au départ

    cela dit pourquoi tu n'utilises pas (remove duplicate) avant de faire tes tableaux.

    Pour le nombre de lignes différentes on s'en fout car j'ai ajouté comme tu peux le voir un espion 'vide & i" qui remplace les cellules vides j'usqu'à hauteur du même nombre de lignes que le plus grand (feuille1 ou 2).

    Il faudrait que tu fasses un remove duplicate avant de faire tes tableaux bien entendu.

    Tu veux que je t'envoie un exemplaire de mon classeur?

  8. #48
    Expert éminent sénior Avatar de mercatog
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    9 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations forums :
    Inscription : Juillet 2008
    Messages : 9 435
    Points : 31 877
    Points
    31 877
    Par défaut
    Citation Envoyé par Oliv- Voir le message
    Désolé je n'ai pas compris le sens de ta réponse!
    C'était adressé à PatrickToulon par rapport à son code #41.
    Entre temps, tu as posté ton dernier code.

  9. #49
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Points : 12 068
    Points
    12 068
    Billets dans le blog
    8
    Par défaut re
    Et quoi que
    On pourrait même supprimer les espions qui ne nous servent plus dans la même boucle avant de transposer les tablos1 et tablos2.

    Tu vois ce que je veux dire.

    En tout cas ça aura le mérite de m'avoir fait travailler sur des composants que je ne connaissais pas du tout.

  10. #50
    Expert éminent
    Avatar de Oliv-
    Homme Profil pro
    solution provider
    Inscrit en
    Mars 2006
    Messages
    4 087
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : solution provider

    Informations forums :
    Inscription : Mars 2006
    Messages : 4 087
    Points : 7 168
    Points
    7 168
    Billets dans le blog
    20
    Par défaut
    Patrick,
    C'est bien ce que je pensais et c'était pour cela que j'avais fait un fichier protocole afin de travailler sur la même chose, bien que celui-ci ne générait pas de doublon , méa culpa.

    Je pense l'avoir dit dans un des posts, les 2 colonnes SIREN et EXISTE sont une partie de 2 tableaux plus importants, la nature de ces tableaux fait que les doublons sont possibles et qu'il ne faut pas forcément les supprimer.

    Il faut aussi donc retrouver les lignes dans le même ordre.

    Je viens de constater un problème
    s'agissant de SIREN le code peut commencer par un ou plusieurs "0"
    exemple "005520176" (construit sur l'ago de Luhn comme les cartes bleue etc..)

    Ou la cellule avoir un format texte ou nombre

    Quand je fais le test
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    If Not mondicoCommun.Exists(tablos2(i, 1))
    "100000001" <>100000001
    string <> double

    Quelqu'un voit une solution pour que "100000001" =100000001 ? ou forcer le type de données dans tablos2 et tablos1 à string ?

    Le fait de poser clairement le problème permet souvent de trouver la réponse.
    en tout cas en voici une

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    '---------------------------------------------------------------------------------------
    ' Procedure : DictionnaireV4
    ' Author    : Oliv-
    ' Date      : 26/11/2012
    ' Purpose   : tester l'existence réciproque entre 2 colonnes
    '---------------------------------------------------------------------------------------
    '
    Sub DictionnaireV4()
        Dim T, truc, temp, i
        Dim mondico As Object
        Dim mondicoCommun As Object
        T = Timer
        Set mondico = CreateObject("Scripting.Dictionary")
        Set mondicoCommun = CreateObject("Scripting.Dictionary")
     
        Set s1 = Worksheets("Feuil1")
        Set S2 = Worksheets("Feuil2")
     
        If S2.UsedRange.Rows.Count < s1.UsedRange.Rows.Count Then
            Set SR = s1
            Set s1 = S2
            Set S2 = SR
            Set SR = Nothing
        End If
     
        Dim tablos1 As Variant
        Dim tablos2 As Variant
     
        tablos1 = Range(s1.Range("A1"), s1.Cells(Rows.Count, 1).End(xlUp).Offset(0, 1))
        tablos2 = Range(S2.Range("A1"), S2.Cells(Rows.Count, 1).End(xlUp).Offset(0, 1))
    mondico.CompareMode = vbTextCompare
    mondicoCommun.CompareMode = vbTextCompare
     
        For i = 1 To UBound(tablos1, 1)
            If Not mondico.Exists(CStr(tablos1(i, 1))) Then mondico.Add CStr(tablos1(i, 1)), CStr(tablos1(i, 1))
        Next i
     
        For i = 1 To UBound(tablos2, 1)
            If mondico.Exists(CStr(tablos2(i, 1))) Then
                If Not mondicoCommun.Exists(CStr(tablos2(i, 1))) Then mondicoCommun.Add CStr(tablos2(i, 1)), CStr(tablos2(i, 1))
                tablos2(i, 2) = "OK"
            Else
                tablos2(i, 2) = "ko"
            End If
        Next i
     
        For i = 1 To UBound(tablos1, 1)
            If mondicoCommun.Exists(CStr(tablos1(i, 1))) Then
                tablos1(i, 2) = "OK"
            Else
                tablos1(i, 2) = "ko"
            End If
        Next i
     
    Debug.Print Timer - T
    Debug.Print mondico.Count
    Debug.Print mondicoCommun.Count
     
        Application.ScreenUpdating = False
        s1.Range("A1:b" & UBound(tablos1)).NumberFormat = "@"
        s1.Range("A1:b" & UBound(tablos1)) = tablos1
     
        S2.Range("A1:b" & UBound(tablos2)).NumberFormat = "@"
        S2.Range("A1:b" & UBound(tablos2)) = tablos2
        Application.ScreenUpdating = True
    Debug.Print "DictionnaireV4 :"; Timer - T
        MsgBox "DictionnaireV4 :" & vbCr & Timer - T
     
    End Sub

  11. #51
    Expert éminent sénior Avatar de mercatog
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    9 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations forums :
    Inscription : Juillet 2008
    Messages : 9 435
    Points : 31 877
    Points
    31 877
    Par défaut
    J'allais la proposer (forcer dans mondico le type string)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    mondicoCommun.Add CStr(truc.Value), CStr(truc.Value)
    '....
    If Not mondicoCommun.Exists(CStr(tablos2(i, 1))) Then

  12. #52
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Points : 12 068
    Points
    12 068
    Billets dans le blog
    8
    Par défaut
    ok
    Même si ton tablo siren et presence ne sont qu'une partie, ton test .le dico se base sur la colonne siren .

    C'est dans cette colonne qui faut supprimer les doublons je ne vois pas trop à quoi ils pourraient te servir (dans la meme colonne )

    Ou alors tu ne prend pas la bonne colonne comme référence auquel cas tu a une lettre à changer dans le code ou le chiffre 1 ou 2 dans tablo(x,y).

    Même si au départ tes tablos font 60 colonnes au dico tu ne te sers que de tablo(X,1) et tablo(X,2)' les 2 premieres colonnes (dans la boucle for n)

    En fait tu traites les items de ton tablo (ligne et colonnes ) comme des cellules.
    C'est là ou je voulais en venir depuis le début.

    wouawhh ton code marche très bien !!!

    Pour le même résultat

    ton code VS mon code sans les doublons bien sûr
    le tiens
    ---------------------------
    Microsoft Excel
    ---------------------------
    DictionnaireV4 :
    0,265625
    ---------------------------
    OK
    ---------------------------
    le mien
    ---------------------------
    Microsoft Excel
    ---------------------------
    0,215873
    ---------------------------
    OK
    ---------------------------
    Tiens voilà c'est là que je suis un peu ennuyé par ton code, bien qu'il fonctionne, on dira pas le contraire.

    Tu as ces 2 boucles:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    For i = 1 To UBound(tablos2, 1)
            If mondico.Exists(CStr(tablos2(i, 1))) Then
                If Not mondicoCommun.Exists(CStr(tablos2(i, 1))) Then mondicoCommun.Add CStr(tablos2(i, 1)), CStr(tablos2(i, 1))
                tablos2(i, 2) = "OK"
            Else
                tablos2(i, 2) = "ko"
            End If
        Next i
     
        For i = 1 To UBound(tablos1, 1)
            If mondicoCommun.Exists(CStr(tablos1(i, 1))) Then
                tablos1(i, 2) = "OK"
            Else
                tablos1(i, 2) = "ko"
            End If
        Next i
    N'y a t'il pas quelque chose qui te dérange ???
    Dis moi que tu le vois enfin !!!!!

    regarde ce qui est en vert

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
     'toujour en prenant le tablo le plus grand bien surle 1 ou le 2 tu dois le determiner avant
        For i = 1 To UBound(tablos2, 1) 'ici tu texte le tablo2
            If mondico.Exists(CStr(tablos2(i, 1))) Then 'ici tu texte si il existe dans le dico1 donc a partir de la on sais que l'element est present sur les deux
                If Not mondicoCommun.Exists(CStr(tablos2(i, 1))) Then mondicoCommun.Add CStr(tablos2(i, 1)), CStr(tablos2(i, 1))
                tablos2(i, 2) = "OK"
            'alors pourquoi tu met pas par exemple ici
            'tablos1(itemdico2/cle du dico1, 2) = "OK" ' par ce que c'est certainement le cas
            Else
                'et pour le cas ou c'est non
                'tablos1(itemdico2/cle du dico1, 2) = "ko"
                tablos2(i, 2) = "ko"
            End If
        Next i
    '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    '                         A JETER
     
    '    For i = 1 To UBound(tablos1, 1)
    '        If mondicoCommun.Exists(CStr(tablos1(i, 1))) Then
    '            tablos1(i, 2) = "OK"
     '       Else
    '            tablos1(i, 2) = "ko"
     '       End If
     '   Next i
    '"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
    re
    Sinon du temps des cavernes il y avait.......

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
    Sub essaie_drole_et_marrant()
    Dim fin, phrase1, phrase2, i, e
    T = Timer
    If Sheets(1).Range("a" & Rows.Count).End(xlUp).Row > Sheets(2).Range("a" & Rows.Count).End(xlUp).Row Then
            fin = Sheets(1).Range("a" & Rows.Count).End(xlUp).Row
        Else
            fin = Sheets(2).Range("a" & Rows.Count).End(xlUp).Row
        End If
        tablos1 = Range(Sheets(1).Range("A1"), Sheets(1).Cells(fin, 2))
        tablos2 = Range(Sheets(2).Range("A1"), Sheets(2).Cells(fin, 2))
        'on a pris le plus grand nombre de lignes utilisé pour les feuilles 1 et 2
        For i = 1 To fin
        phrase1 = phrase1 & "*" & tablos1(i, 1) & "/"
        phrase2 = phrase2 & "*" & tablos2(i, 1) & "/"
    Next
    For e = 1 To fin
    If InStr(phrase1, tablos2(e, 1)) > 0 Then
    tablos2(e, 2) = "OK"
    Else
    tablos2(e, 2) = "ko"
    End If
    If InStr(phrase2, tablos1(e, 1)) > 0 Then
    tablos1(e, 2) = "OK"
    Else
    tablos1(e, 2) = "ko"
    End If
    Next
    Sheets(1).Range("A1:b" & fin) = tablos1
    Sheets(2).Range("A1:b" & fin) = tablos2
    MsgBox Timer - T
    End Sub
    c'est juste pour rire tu le comprend bien



    au plaisir

  13. #53
    Expert éminent
    Avatar de Oliv-
    Homme Profil pro
    solution provider
    Inscrit en
    Mars 2006
    Messages
    4 087
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : solution provider

    Informations forums :
    Inscription : Mars 2006
    Messages : 4 087
    Points : 7 168
    Points
    7 168
    Billets dans le blog
    20
    Par défaut
    Citation Envoyé par patricktoulon Voir le message
    ok
    Même si ton tablo siren et presence ne sont qu'une partie, ton test .le dico se base sur la colonne siren .
    Oui effectivement, mais ce n'est qu'une partie des traitements...

    Citation Envoyé par patricktoulon Voir le message
    C'est dans cette colonne qui faut supprimer les doublons je ne vois pas trop à quoi ils pourraient te servir (dans la meme colonne )

    Ou alors tu ne prend pas la bonne colonne comme référence auquel cas tu a une lettre à changer dans le code ou le chiffre 1 ou 2 dans tablo(x,y).
    C'est quand même moi qui pose le problème ! si je dis que les doublons font partie de l'équation c'est comme cela ! Si tu remplaces le ballon ovale par un ballon rond et que tu joues au pied c'est plus du rugby mais du foot !!

    A la base le sujet portait quand même sur l'utilisation de ADODB !!

    En fait, Patrick tu as de bonnes idées mais tu es un boulimique de production de code, un addict du forum ,tes codes manques de rigueur, et ne sont pas vérifiés, (ça m'arrive aussi !).
    On perd du temps ! il faut savoir s’arrêter sur une solution satisfaisante !
    regarde tototiti2008 nous a donné d'excellentes solutions qui donnaient d'ailleurs le meilleur temps!
    Point positif j'ai pu corriger 2 pb aujourdhui sur ce code.

    Ne m'en veux pas, j'accepte aussi les critiques ! bonne soirée

  14. #54
    Membre éprouvé
    Avatar de Montor
    Homme Profil pro
    Autre
    Inscrit en
    Avril 2008
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Avril 2008
    Messages : 879
    Points : 963
    Points
    963
    Par défaut
    Dommage pour ceux qui ne connaissent pas Collection
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    Sub Tester()
        Dim s1, s2, s As String
        Dim C1 As New Collection
        Dim C2 As New Collection
    Dim L As Long
        Dim T, truc, temp, i
        T = Timer
     
        Set s1 = Worksheets("Feuil1")
        Set s2 = Worksheets("Feuil2")
        Dim R1 As Range
    Dim R2 As Range
     
        Dim tablos1
        Dim tablos2
        tablos1 = Range(s1.Range("A1"), s1.Cells(Rows.Count, 1).End(xlUp).Offset(0, 1))
        tablos2 = Range(s2.Range("A1"), s2.Cells(Rows.Count, 1).End(xlUp).Offset(0, 1))
     
        For i = 1 To UBound(tablos1, 1)
             On Error Resume Next
             C1.Add 1, CStr(UCase(tablos1(i, 1)))
        Next
     
        For i = 1 To UBound(tablos2, 1)
            L = 0
            s = UCase(tablos2(i, 1))
            On Error Resume Next
            L = C1(s$)
            If L <> 0 Then
                On Error Resume Next
                C2.Add 1, s$
                tablos2(i, 2) = True
            Else
                tablos2(i, 2) = ""
            End If
        Next
     
        For i = 1 To UBound(tablos1, 1)
            L = 0
            On Error Resume Next
            L = C2(CStr(UCase(tablos1(i, 1))))
            If L <> 0 Then
                tablos1(i, 2) = True
            Else
                tablos1(i, 2) = ""
            End If
        Next
     
    Debug.Print Timer - T
     
     
        Application.ScreenUpdating = False
        s1.Range("A1:b" & UBound(tablos1)).NumberFormat = "@"
        s1.Range("A1:b" & UBound(tablos1)) = tablos1
     
        s2.Range("A1:b" & UBound(tablos2)).NumberFormat = "@"
        s2.Range("A1:b" & UBound(tablos2)) = tablos2
        Application.ScreenUpdating = True
    Debug.Print "DictionnaireV4 :"; Timer - T
        MsgBox "DictionnaireV4 :" & vbCr & Timer - T
     
    End Sub

  15. #55
    Expert éminent
    Avatar de Oliv-
    Homme Profil pro
    solution provider
    Inscrit en
    Mars 2006
    Messages
    4 087
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : solution provider

    Informations forums :
    Inscription : Mars 2006
    Messages : 4 087
    Points : 7 168
    Points
    7 168
    Billets dans le blog
    20
    Par défaut
    Merci Montor , pour ce code qui remplie apparemment bien la mission.
    Pour ma part j'avais écarté les collections réputées peu performantes(ici 26% plus long) / dictionnaires ou aux tableaux
    .

  16. #56
    Membre éprouvé
    Avatar de Montor
    Homme Profil pro
    Autre
    Inscrit en
    Avril 2008
    Messages
    879
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Avril 2008
    Messages : 879
    Points : 963
    Points
    963
    Par défaut
    Citation Envoyé par Oliv- Voir le message
    Merci Montor , pour ce code qui remplie apparemment bien la mission.
    Pour ma part j'avais écarté les collections réputées peu performantes(ici 26% plus long) / dictionnaires ou aux tableaux
    .
    c'est vrai que les dictionnaire sont dédié pour le stockage des mot mais les collections ont aussi la propriétés key que l'on peut utiliser pour accéder rapidement a des données associées en plus c'est un objet natif

    26% de moins ... tout mes testes me peuvent le contraire .

  17. #57
    Expert éminent
    Avatar de Oliv-
    Homme Profil pro
    solution provider
    Inscrit en
    Mars 2006
    Messages
    4 087
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : solution provider

    Informations forums :
    Inscription : Mars 2006
    Messages : 4 087
    Points : 7 168
    Points
    7 168
    Billets dans le blog
    20
    Par défaut
    Montor, j'ai fait un test sur les données créées avec création_sources_V2 () que tu trouveras plus haut.

    cela me donne
    collection : 0,734375
    DictionnaireV4 : 0,59375
    sans doute qu'avec un autre jeu de données ca peut changer !

  18. #58
    Expert éminent sénior Avatar de mercatog
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    9 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations forums :
    Inscription : Juillet 2008
    Messages : 9 435
    Points : 31 877
    Points
    31 877
    Par défaut
    @Oliv-

    Je proposerai une autre variante utilisant seulement les variables tableaux (à tester)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    Sub SoloTablo()
    Dim N1 As Long, N2 As Long, N As Long, i As Long
    Dim S1 As Worksheet, S2 As Worksheet
    Dim Tb As Variant, Tmp As Variant
    Dim T As Single
     
    T = Timer
    Application.ScreenUpdating = False
     
    Set S1 = Worksheets("Feuil1")
    N1 = S1.Cells(S1.Rows.Count, 1).End(xlUp).Row
     
    Set S2 = Worksheets("Feuil2")
    N2 = S2.Cells(S2.Rows.Count, 1).End(xlUp).Row
     
    N = N1 + N2 - 2
    Tb = S1.Range("A2:D" & N + 2).Value
     
    For i = 1 To N1 - 1
        Tb(i, 3) = 1
        Tb(i, 4) = i
    Next i
     
    Tmp = S2.Range("A2:B" & N2 + 1).Value
    For i = N1 To N + 1
        Tb(i, 1) = Tmp(i - N1 + 1, 1)
        Tb(i, 3) = 2
        Tb(i, 4) = i
    Next i
     
    Tri Tb, 1, N, 1
    Remplissage Tb
    Tri Tb, 1, N, 4
     
    S1.Range("A2:B" & N1).Value = Tb
    Set S1 = Nothing
     
    For i = N1 To N + 1
        Tmp(i - N1 + 1, 2) = Tb(i, 2)
    Next i
     
    S2.Range("A2:B" & N2) = Tmp
    Set S2 = Nothing
     
    MsgBox Timer - T
    End Sub
     
     
    Private Sub Tri(ByRef A As Variant, ByVal Gauche As Long, ByVal Droite As Long, ByVal ColTri As Byte)
    Dim Tmp As Variant, Ref As Variant
    Dim G As Long, D As Long
    Dim i As Byte
     
    Ref = A((Gauche + Droite) \ 2, ColTri)
    G = Gauche
    D = Droite
    Do
        Do While A(G, ColTri) < Ref
            G = G + 1
        Loop
        Do While A(D, ColTri) > Ref
            D = D - 1
        Loop
        If G <= D Then
            For i = LBound(A, 2) To UBound(A, 2)
                Tmp = A(G, i)
                A(G, i) = A(D, i)
                A(D, i) = Tmp
            Next i
            G = G + 1
            D = D - 1
        End If
    Loop While G <= D
    If G < Droite Then Tri A, G, Droite, ColTri
    If D > Gauche Then Tri A, Gauche, D, ColTri
    End Sub
     
    Private Sub Remplissage(ByRef B As Variant)
    Dim i As Long, j As Long, k As Long, P As Long
    Dim Existe As Boolean
     
    P = UBound(B, 1)
    i = 1
    Do
        j = i
        Do While B(i, 1) = B(i + 1, 1)
            If Not Existe Then
                If B(i, 3) <> B(i + 1, 3) Then Existe = True
            End If
            i = i + 1
        Loop
     
        If Existe Then
            Existe = False
            For k = j To i
                B(k, 2) = "OK"
            Next k
        Else
            For k = j To i
                B(k, 2) = "ko"
            Next k
        End If
        i = i + 1
    Loop Until i = P
    End Sub

  19. #59
    Membre expérimenté
    Avatar de tototiti2008
    Homme Profil pro
    Formateur/développeur
    Inscrit en
    Octobre 2008
    Messages
    747
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Formateur/développeur

    Informations forums :
    Inscription : Octobre 2008
    Messages : 747
    Points : 1 332
    Points
    1 332
    Par défaut
    Bonjour à tous,

    Félicitations à Montor et à Mercatog pour leurs propositions qui me semblent toutes les deux plus rapides que les dictionnaires, me reste plus qu'à éplucher tout ça
    En effet, les Collections tournent le plus vite chez moi, et comme Oliv j'avais entendu que c'était plus lent que le dictionnaires, reste plus qu'à bien comprendre les codes

    Edit : Oups, j'avais pas testé la version 4 d'Oliv, qui finalement remporte la palme, donc félicitations Oliv
    très intéressant comment le mode de comparaison accélère (divise par 8 chez moi) le temps d'exécution du code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mondico.CompareMode = vbTextCompare
    avec quelques Cstr bien placés

    Re,

    Bon, ben ma version en ajoutant le mode de comparaison

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    Sub DictionnaireV4_1()
        Dim T As Double, i As Long, j As Long
        Dim mondico As Object
        Dim tablos1 As Variant
        Dim tablos2 As Variant
        Dim TabloLigne
        T = Timer
        Set mondico = CreateObject("Scripting.Dictionary")
        mondico.CompareMode = vbTextCompare
     
        If Worksheets("Feuil2").UsedRange.Rows.Count < Worksheets("Feuil1").UsedRange.Rows.Count Then
            Set s2 = Worksheets("Feuil1")
            Set s1 = Worksheets("Feuil2")
        Else
            Set s1 = Worksheets("Feuil1")
            Set s2 = Worksheets("Feuil2")
        End If
        s1.Columns("B:B").ClearContents
        s2.Columns("B:B").ClearContents
     
     
        tablos1 = Range(s1.Range("A1"), s1.Cells(Rows.Count, 1).End(xlUp).Offset(0, 1)).Value
        tablos2 = Range(s2.Range("A1"), s2.Cells(Rows.Count, 1).End(xlUp).Offset(0, 1)).Value
     
        For i = 1 To UBound(tablos1, 1)
            If mondico.Exists(tablos1(i, 1)) Then
                mondico(CStr(tablos1(i, 1))) = mondico(tablos1(i, 1)) & "," & i
            Else
                mondico(CStr(tablos1(i, 1))) = CStr(i)
            End If
        Next i
     
        For i = 1 To UBound(tablos2, 1)
            If mondico.Exists(CStr(tablos2(i, 1))) Then
                tablos2(i, 2) = "OK"
                TabloLigne = Split(mondico.Item(tablos2(i, 1)), ",")
                For j = LBound(TabloLigne) To UBound(TabloLigne)
                    tablos1(CLng(TabloLigne(j)), 2) = "OK"
                Next j
            Else
                tablos2(i, 2) = "ko"
            End If
        Next i
     
        For i = 1 To UBound(tablos1, 1)
            If tablos1(i, 2) = "" Then
                tablos1(i, 2) = "ko"
            End If
        Next i
     
    Debug.Print Timer - T
    Debug.Print mondico.Count
        Application.ScreenUpdating = False
        s1.Range("A1:b" & UBound(tablos1)) = tablos1
     
        s2.Range("A1:b" & UBound(tablos2)) = tablos2
        Application.ScreenUpdating = True
    Debug.Print Timer - T
        MsgBox Timer - T
    End Sub

  20. #60
    Expert éminent
    Avatar de Oliv-
    Homme Profil pro
    solution provider
    Inscrit en
    Mars 2006
    Messages
    4 087
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : solution provider

    Informations forums :
    Inscription : Mars 2006
    Messages : 4 087
    Points : 7 168
    Points
    7 168
    Billets dans le blog
    20
    Par défaut
    Merci à tous,
    j'ai fait une compilation des codes, avec un lancement de toutes les macros(ou presque) pour avoir un benchmark.

    Le benchmark se fait sur le jeu de données sans doublon:

    Please enjoy !
    Fichiers attachés Fichiers attachés

+ Répondre à la discussion
Cette discussion est résolue.
Page 3 sur 4 PremièrePremière 1234 DernièreDernière

Discussions similaires

  1. Comparer deux colonnes
    Par gandalfthegrey dans le forum Excel
    Réponses: 6
    Dernier message: 30/01/2008, 11h57
  2. Comparer deux colonnes d'une même table
    Par snoopy69 dans le forum Requêtes et SQL.
    Réponses: 5
    Dernier message: 08/01/2008, 10h05
  3. Comparer deux colonnes adjacentes une à une sur mon tableau?
    Par drthodt dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 06/12/2007, 10h11
  4. Réponses: 3
    Dernier message: 22/10/2006, 23h15
  5. comparer deux colonnes sur Excel
    Par delamarque dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 21/12/2005, 10h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo