Quelques problemes sur une macro avec des dictionnaires

Bonjour !

Je doit faire une macro excel qui compare des valeurs par 2 de 2 feuilles differents pour mettre a jour des données ou en ajouter. J'ai pensé a associer les paires de données pour en avoir qu'une seul, les mettre dans des dictionnaires (1 par feille) pour ensuite comparer les valeurs dans ces dictionnaires.

Cependant je rencontre qq problemes. merci d'avance a ceux qui prendront le temps de check cette cata ahah

Sub Mettre a jour dossier()
    Dim feuilleForm As Worksheet
    Dim feuilleBD As Worksheet
    Dim Critere1 As Variant
    Dim Critere2 As Variant
    Dim plageRecherche As Range
    Dim cellule As Range
    Dim ligneTrouvee As Range
    Dim derniereligne As Long
    Dim derniereligneForm As Long
    Dim dictionnaire As Object
    Dim dictionnaire2 As Object
    Dim feuille As Worksheet
    Dim i As Long
    Dim y As Long
    Dim CellD As Variant
    Dim CellG As Variant
    Dim o As Variant
    Dim Num1 As Variant
    Dim Num2 As Variant
    Dim Correspondance As Variant

    Set feuilleForm = ThisWorkbook.Sheets("Form")
    Set feuilleBD = ThisWorkbook.Sheets("BD")
    Set dictionnaire = CreateObject("Scripting.Dictionary")
    Set dictionnaire2 = CreateObject("Scripting.Dictionary")

    'Récupere tout les paires de valeur de la feuille BD

    derniereligne = feuilleBD.Cells(feuilleBD.Rows.Count, "D").End(xlUp).Row
    For i = 2 To derniereligne
        CellD = feuilleBD.Cells(i, "D").Value
        CellG = feuilleBD.Cells(i, "G").Value
        dictionnaire.Add CellD & CellG
    Next i

    'Récupere tout les paires de valeur de la feuille BD
    derniereligneForm = feuilleForm.Cells(feuilleBD.Rows.Count, "D").End(xlUp).Row
    For y = 9 To derniereligne
        Critere1 = feuilleForm.Cells(y, "D").Value
        Critere2 = feuilleForm.Cells(y, "C").Value
        dictionnaire.Add Critere1 & Critere2
    Next i

    'Chercher une correspondane pour chaque valeur du dictionnaire 1 dans le dictionnaire 2.
    'Si correspondance trouvé ---> fonction IF
    'Si aucune correspondance trouvée ---> fonction "ajouter une ligne"
    For Each Value1 In dictionnaire.keys

    o = 2
        Correspondance = InStrRev(dictionnaire2, Value1)
        If Correspondance = 0 Then
                            derniereligne = Cells(Rows.Count, 1).End(xlUp).Row
                            Rows(derniereligne + 1).Insert Shift:=xlDown
        Else
        For Each Value2 In dictinnaire2.keys
            'COMMENT DIFFENCIER LES VALEURS PRESENTES DANS LES 2 DICTIONNAIRES ? Value1 et Value2
            If Value1 = Value2 Then
            Set ligneTrouvee = cellule.EntireRow
            If feuilleBD.Range("H" & o).Value <> ligneTrouvee.Cells(11) Then
                ligneTrouvee.Cells(11).Value = feuilleBD.Range("H" & o).Value
                ligneTrouvee.Cells(11).Interior.Color = RGB(255, 200, 255)
            End If
            End If
        Next Value2
        'Augmenter la valuer de o pour que la ligne ou les info sont modifiées change
        o = o + 1
     Next Value1

End Sub

Il y a plus de Dim que ce qui est utilisé car les actions a effectuer sont plus longue mais elles marchent indépendament donc je les ai enlevé pour ecourter la lecture.

Louma

bonjour,

dans quelle feuille dois-tu ajouter ou modifier les données ? feuilleBD ou feuilleform ? le plus simple est de mettre un fichier exemple représentatif, (anonymisé si nécessaire)

Bonjour,

En plus du fichier veuillez indiquer également le nombre de ligne réel des feuilles...

A+

Oui ! voici le fichier et la macro que j'essaye de faire marche mtn (spoil ca marche quand meme pas, meme si j'ai l'impression d'approcher du but)

Je doit mettre a jour les données dans la feuille Form a partir de celles présentes dans la feuille BD

Sub Mettreajourdossier()

    Dim feuilleForm As Worksheet
    Dim feuilleBD As Worksheet
    Dim Critere1 As Variant
    Dim Critere2 As Variant
    Dim plageRecherche As Range
    Dim cellule As Range
    Dim ligneTrouvee As Variant
    Dim derniereligne As Long
    Dim derniereligneBD As Long
    Dim derniereligneForm As Long
    Dim dictionnaire1 As Object
    Dim dictionnaire2 As Object
    Dim feuille As Worksheet
    Dim i As Long
    Dim y As Long
    Dim CellD As Variant
    Dim CellG As Variant
    Dim o As Variant
    Dim Num1 As Variant
    Dim Num2 As Variant
    Dim Correspondance As Variant
    Dim key As Variant

    Set feuilleForm = ThisWorkbook.Sheets("Form")
    Set feuilleBD = ThisWorkbook.Sheets("BD")
    Set dictionnaire1 = CreateObject("Scripting.Dictionary")
    Set dictionnaire2 = CreateObject("Scripting.Dictionary")

    'Récupere tout les paires de valeur de la feuille BD

    derniereligneBD = feuilleBD.Cells(feuilleBD.Rows.Count, "D").End(xlUp).Row
    For i = 2 To derniereligne
        CellD = feuilleBD.Cells(i, "D").Value
        CellG = feuilleBD.Cells(i, "G").Value
        dictionnaire1.Add CellD & CellG
    Next i

    'Récupere tout les paires de valeur de la feuille BD
    derniereligneForm = feuilleForm.Cells(feuilleForm.Rows.Count, "D").End(xlUp).Row
    For y = 9 To derniereligne
        Critere1 = feuilleForm.Cells(y, "D").Value
        Critere2 = feuilleForm.Cells(y, "C").Value
        dictionnaire2.Add Critere1 & Critere2
    Next y

    'Modifier o pour qu'il corresponde a la ligne trouvé de key dic2 n'existant pas dans key dic1
    o = 2
    p = 2
    ligneTrouvee = 9

    'Cherche une correspondane pour chaque key dictionnaire 1 dans key dictionnaire 2 pour mettre a jour le solde et collorer si il a été modifié
    For Each key In dictionnaire1.key
        If dictionnaire2.Exists(key) Then
        If dictionnaire1(key) = dictionnaire2(key) Then
        If feuilleBD.Range("H" & p).Value <> ligneTrouvee.Cells(11) Then
                ligneTrouvee.Cells(11).Value = feuilleBD.Range("H" & p).Value
                ligneTrouvee.Cells(11).Interior.Color = RGB(255, 200, 255)
        ligneTrouvee = ligneTrouvee + 1
        p = p + 1
        End If
        End If
        End If
        Next key

        'Cherche les valeur de key dic2 qui n'existe pas dans key dic 1 pour ajouter la ligne correspondante
    For Each key In dictionnaire2.Keys
        If Not dictionnaire1.Exists(key) Then
        derniereligne = Cells(Rows.Count, 1).End(xlUp).Row
                    Rows(derniereligne + 1).Insert Shift:=xlDown

                    'Trouve un moyen pour que o ne monte pas d'une ligne pas une ligne mais prenne la ligne ou key dic2 n'as pas été trouvé dans key dic2
                    Cells(derniereligne + 1, 2).Value = feuilleBD.Range("B" & o).Value
                    Cells(derniereligne + 1, 3).Value = feuilleBD.Range("G" & o).Value
                    Cells(derniereligne + 1, 4).Value = feuilleBD.Range("D" & o).Value
                    Cells(derniereligne + 1, 5).Value = feuilleBD.Range("E" & o)
                    If Range("D" & o).Value = "" Then
                    Cells(derniereligne + 1, 6).Value = "?"
                    ElseIf Range("D" & o).Value >= 600000 Then
                    Cells(derniereligne + 1, 6).Value = "R"
                    ElseIf Range("D" & o).Value < 600000 Then
                    Cells(derniereligne + 1, 6).Value = "B"
                    End If
                    Cells(derniereligne + 1, 7).Value = feuilleBD.Range("F" & o)
                    'La ligne collone 8 utilise une plage non présente dans le fichier test. La rajouter a la fin (simple
                    Cells(derniereligne + 1, 9).Value = feuilleBD.Range("H" & o).Value
                    Cells(derniereligne + 1, 10).Value = feuilleBD.Range("C" & o).Value
                    Cells(derniereligne + 1, 11).Value = feuilleBD.Range("H" & o).Value
                    Cells(derniereligne + 1, 12).Value = "?"

                    o = o + 1
        End If

    Next key

End Sub

Bonjour Loumatrix,

A tester :

Sub MettreAJourDossier()
    '... Vos déclarations de variables ici ...

    ' Récupère toutes les paires de valeur de la feuille BD
    ' ...

    ' Récupère toutes les paires de valeur de la feuille Form
    ' ...

    ' Met à jour o, p et ligneTrouvee pour correspondre à la clé trouvée de dic2 n'existant pas dans dic1
    o = 2
    p = 2
    ligneTrouvee = 9

    ' Cherche une correspondance pour chaque clé du dictionnaire1 dans le dictionnaire2 pour mettre à jour le solde et colorer si elle a été modifiée
    For Each key In dictionnaire1.Keys
        If dictionnaire2.Exists(key) Then
            If dictionnaire1(key) = dictionnaire2(key) Then
                If feuilleBD.Cells(p, "H").Value <> feuilleForm.Cells(ligneTrouvee, 11).Value Then ' Correction ici
                    feuilleForm.Cells(ligneTrouvee, 11).Value = feuilleBD.Cells(p, "H").Value
                    feuilleForm.Cells(ligneTrouvee, 11).Interior.Color = RGB(255, 200, 255)
                End If
                ligneTrouvee = ligneTrouvee + 1
                p = p + 1
            End If
        End If
    Next key

    ' Cherche les clés de dic2 qui n'existent pas dans dic1 pour ajouter la ligne correspondante
    For Each key In dictionnaire2.Keys
        If Not dictionnaire1.Exists(key) Then
            derniereligne = feuilleBD.Cells(Rows.Count, 1).End(xlUp).Row
            feuilleBD.Rows(derniereligne + 1).Insert Shift:=xlDown
            ' ... Votre code pour remplir les cellules ici ...
            o = o + 1
        End If
    Next key
End Sub

merci, j'ai testé, mais malheureusement ca ne fonctionne toujours pas.

Apres avoir testé de mettre des msg box apres la création des dictionnaires, ceux la sont en realité vide, donc ils ne prennent pas en compte les valeur :(

bonjour,

le but est-il bien d'avoir dans la feuille form toutes les lignes de la feuille BD ? j'ai un doute.

voici ce que j'ai compris du code.

recherche dans la BD toutes les lignes de form et le mettre à jour la colonne H de form avec la valeur de la colonne H de feuille si valeur différente ?

puis on parcourt BD et on ajoute toutes les lignes qui se ne se trouve pas dans form.

pour moi cela revient à prendre BD tel quel en modifiant l'ordre des colonnes.

Le but est d'y ajouter les lignes qui n'y sont pas présente, et de mettre a jour celles qui y sont deja en changeant le "Montant"

re-bonjour,

donc

pour moi cela revient à prendre toutes les infos de BD telles quelles en modifiant l'ordre des colonnes.

Rebonjour

Le soucis est de verifier si la ligne existant deja, pour collorer le nouveau montant afin de voir qu'il a été modifié.

apres j'me casse probablement la tete pour pas grand chose :x

Re bonjour,

Je pense que votre code actuel ne mette pas correctement à jour le "Montant" et n'ajoute pas correctement les nouvelles lignes à la feuille "Form" à voir.
Un code que vous pourrez tester :

Sub Mettreajourdossier()

    Dim feuilleForm As Worksheet
    Dim feuilleBD As Worksheet
    Dim Critere1 As Variant
    Dim Critere2 As Variant
    Dim derniereligneBD As Long
    Dim derniereligneForm As Long
    Dim dictionnaire1 As Object
    Dim i As Long
    Dim y As Long
    Dim CellD As Variant
    Dim CellG As Variant
    Dim o As Variant
    Dim key As Variant

    Set feuilleForm = ThisWorkbook.Sheets("Form")
    Set feuilleBD = ThisWorkbook.Sheets("BD")
    Set dictionnaire1 = CreateObject("Scripting.Dictionary")

    'Récupere toutes les paires de valeur de la feuille BD
    derniereligneBD = feuilleBD.Cells(feuilleBD.Rows.Count, "D").End(xlUp).Row
    For i = 2 To derniereligneBD
        CellD = feuilleBD.Cells(i, "D").Value
        CellG = feuilleBD.Cells(i, "G").Value
        dictionnaire1.Add CellD & CellG, i
    Next i

    'Cherche correspondance pour chaque paire dans la feuille Form
    derniereligneForm = feuilleForm.Cells(feuilleForm.Rows.Count, "D").End(xlUp).Row
    For y = 9 To derniereligneForm
        Critere1 = feuilleForm.Cells(y, "D").Value
        Critere2 = feuilleForm.Cells(y, "C").Value
        key = Critere1 & Critere2

        If dictionnaire1.Exists(key) Then
            'Si correspondance trouvée, mettre à jour le montant
            feuilleForm.Cells(y, "H").Value = feuilleBD.Cells(dictionnaire1(key), "H").Value
            feuilleForm.Cells(y, "H").Interior.Color = RGB(255, 200, 255)
            dictionnaire1.Remove key
        End If
    Next y

    'Ajoute les lignes restantes de la feuille BD à la feuille Form
    For Each key In dictionnaire1.Keys
        o = dictionnaire1(key)
        derniereligneForm = feuilleForm.Cells(feuilleForm.Rows.Count, "D").End(xlUp).Row + 1
        feuilleForm.Range("D" & derniereligneForm & ":G" & derniereligneForm).Value = _
            feuilleBD.Range("D" & o & ":G" & o).Value
    Next key

End Sub

merci bcp pour ces corrections, j'y ai jété un coup d'oeil mais j'ai l'impression que comme H2S04 me l'as fait comprendre je me suis embourbé dans un code bcp trop compliqué pour quelque chose de simple.

J'ai repensé un moyen plus simple d'atteindre mon objctif et je reviens vers vous quand il fonctionne

bonjour,

voici une proposition de modification de ton code

Sub Mettreajourdossier()
    Dim feuilleForm As Worksheet
    Dim feuilleBD As Worksheet
    Dim Critere1 As Variant
    Dim Critere2 As Variant
    Dim plageRecherche As Range
    Dim cellule As Range
    Dim ligneTrouvee As Range
    Dim derniereligne As Long
    Dim derniereligneForm As Long
    Dim dictionnaire As Object
    Dim dictionnaire2 As Object
    Dim feuille As Worksheet
    Dim i As Long
    Dim y As Long
    Dim CellD As Variant
    Dim CellG As Variant
    Dim o As Variant
    Dim Num1 As Variant
    Dim Num2 As Variant
    Dim Correspondance As Variant

    Set feuilleForm = ThisWorkbook.Sheets("Form")
    Set feuilleBD = ThisWorkbook.Sheets("BD")
    Set dictionnaire = CreateObject("Scripting.Dictionary")

    derniereligneForm = feuilleForm.Cells(Rows.Count, 1).End(xlUp).Row
    derniereligne = feuilleBD.Cells(Rows.Count, 1).End(xlUp).Row
    Set dictionnaire = CreateObject("Scripting.Dictionary")
    ' creer un dictionnaire avec les lignes présentes dans form
    For i = 9 To derniereligneForm
        CellD = feuilleForm.Cells(i, "D").Value
        CellC = feuilleForm.Cells(i, "C").Value
        dictionnaire.Add CellD & CellC, i 'attention pas de gestion de l'erreur en cas de doublon
    Next i

    For i = 2 To derniereligne 'parcourt toute la BD
        Critere1 = feuilleBD.Cells(i, "D")
        Critere2 = feuilleBD.Cells(i, "G")
        If dictionnaire.exists(Critere1 & Critere2) Then 'ligne de BD présente dans form
            o = dictionnaire(Critere1 & Critere2) 'oui, o est le numéro de ligne dans Form
            If feuilleForm.Cells(o, 11) <> feuilleBD.Range("H" & i) Then 'montant différent
                feuilleForm.Cells(o, 11) = feuilleBD.Range("H" & i) 'on modifie la colonne K de la form avec l'info de la BD en colonne H
                feuilleForm.Cells(o, 11).Interior.Color = RGB(255, 200, 255)
            Else 'même montant
                feuilleForm.Cells(o, 11).Interior.Color = RGB(255, 255, 255)
            End If
        Else 'ligne de BD absente de form on ajoute les données dans form
            derniereligneForm = derniereligneForm + 1
            feuilleForm.Rows(derniereligneForm).Insert
            feuilleForm(derniereligneForm - 1, 1).Copy feuilleForm.Cells(derniereligneForm, 1)
            feuilleForm.Cells(derniereligneForm, 2).Value = feuilleBD.Range("B" & i).Value
            feuilleForm.Cells(derniereligneForm, 3).Value = feuilleBD.Range("G" & i).Value
            feuilleForm.Cells(derniereligneForm, 4).Value = feuilleBD.Range("D" & i).Value
            feuilleForm.Cells(derniereligneForm, 5).Value = feuilleBD.Range("E" & i)
            If feuilleBD.Range("D" & i).Value = "" Then
                feuilleForm.Cells(derniereligneForm, 6).Value = "?"
            ElseIf feuilleBD.Range("D" & i).Value >= 600000 Then
                feuilleForm.Cells(derniereligneForm, 6).Value = "R"
            ElseIf feuilleBD.Range("D" & i).Value < 600000 Then
                feuilleForm.Cells(derniereligneForm, 6).Value = "B"
            End If
            feuilleForm.Cells(derniereligneForm, 7).Value = feuilleBD.Range("F" & i)
            feuilleForm.Cells(derniereligneForm, 9).Value = feuilleBD.Range("H" & i).Value
            feuilleForm.Cells(derniereligneForm, 10).Value = feuilleBD.Range("C" & i).Value
            feuilleForm.Cells(derniereligneForm, 11).Value = feuilleBD.Range("H" & i).Value
            feuilleForm.Cells(o, 11).Interior.Color = RGB(255, 255, 255)
            feuilleForm.Cells(derniereligneForm, 12).Value = "?"
        End If
    Next i

End Sub

A priori ce que vous m'avez envoyé marche, merci beaucoup et bravo. Je vais etudier ca pour comprendre ou j'ai fait mal les choses

A priori bcp de problemes ont été reglés mais il en subsiste 2.

1 : le calcul de la collone 6 avec les condition ne fonctionne pas (je pense pouvoir m'en charger tout seul)

2 : lorsque l'on utilise 2 fois la macro, elle recréé les nouvelles lignes comme si elles ne les reconnaissaient pas.

ex: depart : mon fichier a 2 lignes. J'en rajoute une dans la BD et lance la macro ---> la macro créé une troisieme ligne

2eme utilisation : la macro recréé la 3eme ligne a nouveau, comme si elle ne l'avait pas ajouter dans son dictionnaire

C'est tout bon ! j'ai corrigé les 2 problemes.

Encore merci a tous :D

Rechercher des sujets similaires à "problemes macro dictionnaires"