VBA- Macro comparative

Fermé
ludo35 - 29 févr. 2012 à 18:08
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 - 1 mars 2012 à 12:42
Bonjour,

Cela fait un moment que je cherche et j'avoue que je suis un peu perdu etant neophyte en VBA :(
J'ai une feuille excel, contenant 3 colonnes, une Nom article déclassée, une ID et une Nom article classée, je souhaiterais parcourir la premiere colonne, pour chaque cellule aller parcourir la 3eme colonne pour y trouver le même texte et pouvoir recuperer l'Id associé(colonne 2) afin de l'ecrire dans une 4eme colonne et ainsi pouvoir obtenir le bon ID face au bon Nom article, j'ai essayé avec le fonction RECHERCHEV, avec des macro mais la je m'y perd...

EX:

pomme 1 poire
abricot 2 marron
noix 3 fraise
pasteque 4 pomme

Je voudrais que le 4 par ex. soit afficher face au pomme de la colonne 1 et ainsi de suite.
J'espere avoir été assez concis.



Est qu'un ame charitable pourrais me donner un coup de main?

Un gros merci d'avance

Cordialement
A voir également:

6 réponses

michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 310
29 févr. 2012 à 18:21
Bonjour

Peut il y avoir des doublons dans une colonne (par Ex 2 fois pomme dans colonne A; m^me question pour colonne C) ?
combien de lignes comporte tes listes...?
0
Merci pour votre interet

En effet la colonne 1 possede des doublons, par contre la colonne 3 ne possede pas de doublons.
La colonne 1 possede 1300 lignes, pour 3600 pour la colonne 2 et 3

Pouvez vous m'aider, je ne pense pas que pour un connaisseur ce sois une grosse macro, malhuereusement j'arrive pas à m'en sortir :(

Merci par avance de votre réponse

Cordialement
0
michel_m Messages postés 16603 Date d'inscription lundi 12 septembre 2005 Statut Contributeur Dernière intervention 16 décembre 2023 3 310
Modifié par michel_m le 1/03/2012 à 08:24
Bonjour,

Suis absent toute la journée mais quelqu'un pourra t'aider ('je fais signe à qqn)

la solution pourrait passer par 2 variables -tableaux "in" et "out" et un objet "dictionary"
avec en clé le nom et en index l'id

Michel
0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 751
Modifié par pijaku le 1/03/2012 à 09:26
Bonjour,

Je passe par ici suite à l'invitation de michel (que je remercie pour la confiance accordée).

Y a t'il une ligne d'entête a ton tableau?
Tes données débutent ligne1? ligne 2? ligne 18?
Il n'y a aucune cellule vide colonnes B et C?

Prépare déjà une copie de ton classeur pour ne pas avoir à travailler sur les données originales et ainsi conserver une sauvegarde.

ps : sais tu intégrer et/ou adapter une macro à un classeur?

Cordialement,
Franck P
0

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

Posez votre question
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 751
Modifié par pijaku le 1/03/2012 à 11:11
Après, pour être pratico-pratique, comment souhaites tu voir restituer tes données?

Solution 1 (celle qu'il me semble que tu as prévu):
Colonne A : noms des articles déclassés
Colonne B : ID des articles classés
Colonne C : Noms des articles classés
Colonne D : ID des articles déclassés

Solution 2 :
Colonne A : noms des articles déclassés
Colonne B : ID des articles déclassés
Colonne C : Noms des articles classés
Colonne D : ID des articles classés

En attente de réponses à toutes ces questions.

Quoiqu'il en soit, je propose, ce midi, les deux solutions...
Cordialement,
Franck P
0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 751
1 mars 2012 à 12:40
Voici ma proposition, largement commentée.
J'ai laissé des choix à l'utilisateur, à savoir :
- choix 1 : conserver ou supprimer les doublons de la colonne A
- choix 2 : restitution des données comme suit :
Colonne A : noms des articles déclassés
Colonne B : ID des articles classés
Colonne C : Noms des articles classés
Colonne D : ID des articles déclassés
- choix 3 : restitution des données comme suit :
Colonne A : noms des articles déclassés
Colonne B : ID des articles déclassés
Colonne C : Noms des articles classés
Colonne D : ID des articles classés

En cadeau une petite démo
Pour lancer la procédure : ALT+F8 choisir "ProcedurePrincipale" et Exécuter.

Le code à intégrer DANS UNE COPIE DU CLASSEUR est :
Option Explicit

Sub ProcedurePrincipale()
'Déclaration des variables
Dim MonDico As Object
Dim TablA, TablBC, TablID, Cpt As Long
Dim Message As String, Msg As String, Repons As Integer

'initialisation du message de fin pour l'utilisateur
    'en cas de données contenues dans A mais pas dans C
    'qui n'auraient donc pas d'ID... Juste au cas ou...
Message = "Ces données ont été trouvées colonne A mais pas colonne C :"

'I-- remplissage des variables tableaux "d'entrée" :
    '1- TablA (colonne A)
    '2- TablBC (colonnes B & C)
    '3- TablID (les ID correspondants aux éléments de la colonne A)
    
'1    '- TablA = données contenues colonne A
TablA = Range("A2", Range("A" & Rows.Count).End(xlUp))
    '***************************************************************
    ' On propose à l'utilisateur de supprimer les doublons colonne A
    Repons = MsgBox("Voulez vous supprimer les doublons colonne A?", vbYesNo + vbCritical, "!!! Suppression définitive !!!")
    '-- Si l'utilisateur veux supprimer les doublons alors
    If Repons = vbYes Then
        'on lance la fonction appropriée (cf code ci-dessous)
        '-- APPEL DE LA FONCTION avec en paramètre notre TablA :
        SupprimeDoublonsColonneA TablA
        'on efface la variable tableau TablA qui contient les anciennes données colA
        Erase TablA
        'on le remplit à nouveau des nouvelles données contenues colonne A
        TablA = Range("A2", Range("A" & Rows.Count).End(xlUp))
    End If
    '***************************************************************
'2    '- TablBC = données contenues colonnes B & C
TablBC = Range("B2", Range("C" & Rows.Count).End(xlUp))

'3    '- TablID = futurs ID correspondants aux articles colonne A
        'TablID ne sera remplit qu'après le dictionnaire,
        'pour l'instant on le dimensionne à la bonne taille
ReDim TablID(UBound(TablA))

'II-- L'objet Dictionary
        'va servir à stocker les ID et les Noms
        'en faisant en sorte qu'ils se correspondent.
        'En effet, un élément de dictionary est construit comme ceci :
        'Dico clé,élément
        'pour en savoir plus :
        'http://boisgontierjacques.free.fr/pages_site/Dictionnaire.htm

'1- création de l'objet dictionary
Set MonDico = CreateObject("Scripting.Dictionary")
'le fait de boucler sur une variable tableau est + rapide
'que de boucler sur les cellules de la feuille
For Cpt = LBound(TablBC, 1) To UBound(TablBC, 1)

'2- remplissage du Dictionary :
    '- clés = n° ID (colonne B = TablBC(Cpt, 1))
    '- éléments = Noms (colonne C = TablBC(Cpt, 2))
    If Not MonDico.Exists(TablBC(Cpt, 2)) Then MonDico.Add TablBC(Cpt, 2), TablBC(Cpt, 1)
Next Cpt

'III-- Remplissage de la variable tableau TablID
    'TablID va contenir les ID correspondants aux éléments de notre TablA (colonne A)
For Cpt = LBound(TablA, 1) To UBound(TablA, 1)
    'Si l'élément TablA n'existe pas dans MonDico,
    'ça signifie que l'élément colonne A n'existe pas colonne C.
    If Not MonDico.Exists(TablA(Cpt, 1)) Then
        'Alors, on remplit le message à l'utilisateur avec :
            'Le contenu de cet élément : TablA(Cpt, 1)
            'la ligne ou il se trouve colonne A : Cpt + 1
        Message = Message & Chr(10) & "- " & TablA(Cpt, 1) & ", Ligne : " & Cpt + 1
    'Sinon, s'il existe bien colonne C
    Else
        'on remplit la variable tableau TablID des n° d'ID correspondants
        TablID(Cpt - 1) = MonDico(TablA(Cpt, 1))
    End If
Next

'IV-- Restitution des données
    'ici deux choix sont proposés à l'utilisateur :
        'Choix 1:
            'Colonne A : noms des articles déclassés
            'Colonne B : ID des articles classés
            'Colonne C : Noms des articles classés
            'Colonne D : ID des articles déclassés
        'Choix 2:
            'Colonne A : noms des articles déclassés
            'Colonne B : ID des articles déclassés
            'Colonne C : Noms des articles classés
            'Colonne D : ID des articles classés
'1- Choix 1 :
Msg = "Souhaitez vous obtenir :" & Chr(10) & _
            "- Colonne A : noms des articles déclassés" & Chr(10) & _
            "- Colonne B : ID des articles classés" & Chr(10) & _
            "- Colonne C : Noms des articles classés" & Chr(10) & _
            "- Colonne D : ID des articles déclassés"
Repons = MsgBox(Msg, vbYesNo + vbCritical, "Restitution des données")
If Repons = vbYes Then
    Range("D2").Resize(UBound(TablID), 1) = Application.Transpose(TablID)
    If Message <> "Ces données ont été trouvées colonne A mais pas colonne C :" Then MsgBox Message
    Exit Sub
End If

'2- Choix 2 :
Msg = "Souhaitez vous obtenir :" & Chr(10) & _
            "- Colonne A : noms des articles déclassés" & Chr(10) & _
            "- Colonne B : ID des articles déclassés" & Chr(10) & _
            "- Colonne C : Noms des articles classés" & Chr(10) & _
            "- Colonne D : ID des articles classés"
Repons = MsgBox(Msg, vbYesNo + vbCritical, "Restitution des données")
If Repons = vbYes Then
    '!!!!!! ICI SUPPRESSION DES DONNEES !!!!!!!!
        '==> d'où l'intérêt de travailler sur une copie du classeur
    Range("B2", Range("C" & Rows.Count).End(xlUp)).ClearContents
    Range("B2").Resize(UBound(TablID), 1) = Application.Transpose(TablID)
    Range("C2").Resize(MonDico.Count) = Application.Transpose(MonDico.keys)
    Range("D2").Resize(MonDico.Count) = Application.Transpose(MonDico.items)
    If Message <> "Ces données ont été trouvées colonne A mais pas colonne C :" Then MsgBox Message
End If
End Sub

'Fonction de suppression des doublons colonne A
    'cette fonction a pour paramètre une variable tableau
    'cette variable tableau contient les données de la colonne A selon l'appel
    'de cette fonction dans la procédure principale : SupprimeDoublonsColonneA TablA
Function SupprimeDoublonsColonneA(Tableau As Variant)
Dim DicoA As Object, i As Long

'création du dictionnaire
Set DicoA = CreateObject("Scripting.Dictionary")
For i = LBound(Tableau, 1) To UBound(Tableau, 1)
    'si le contenu de notre tableau n'existe pas dans le dictionnaire alors on l'ajoute
    If Not DicoA.Exists(Tableau(i, 1)) Then DicoA.Add Tableau(i, 1), Tableau(i, 1)
    's'il existe déjà, il n'est pas ajouté...
Next i
'Supprime les données de la colonne A
Range("A2", Range("A" & Rows.Count).End(xlUp)).ClearContents
'les remplace par les mêmes, sans les doublons, soit par les éléments de notre DicoA...
Range("A2").Resize(DicoA.Count) = Application.Transpose(DicoA.keys)
End Function


0
pijaku Messages postés 12263 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 4 janvier 2024 2 751
1 mars 2012 à 12:42
Pour Michel quand il repassera ici, le code sans les commentaires :
Sub ProcedurePrincipale()
Dim MonDico As Object
Dim TablA, TablBC, TablID, Cpt As Long
Dim Message As String, Msg As String, Repons As Integer


Message = "Ces données ont été trouvées colonne A mais pas colonne C :"
TablA = Range("A2", Range("A" & Rows.Count).End(xlUp))
    Repons = MsgBox("Voulez vous supprimer les doublons colonne A?", vbYesNo + vbCritical, "!!! Suppression définitive !!!")
    If Repons = vbYes Then
        SupprimeDoublonsColonneA TablA
        Erase TablA
        TablA = Range("A2", Range("A" & Rows.Count).End(xlUp))
    End If
TablBC = Range("B2", Range("C" & Rows.Count).End(xlUp))
ReDim TablID(UBound(TablA))
Set MonDico = CreateObject("Scripting.Dictionary")
For Cpt = LBound(TablBC, 1) To UBound(TablBC, 1)
    If Not MonDico.Exists(TablBC(Cpt, 2)) Then MonDico.Add TablBC(Cpt, 2), TablBC(Cpt, 1)
Next Cpt
For Cpt = LBound(TablA, 1) To UBound(TablA, 1)
    If Not MonDico.Exists(TablA(Cpt, 1)) Then
        Message = Message & Chr(10) & "- " & TablA(Cpt, 1) & ", Ligne : " & Cpt + 1
    Else
        TablID(Cpt - 1) = MonDico(TablA(Cpt, 1))
    End If
Next
Msg = "Souhaitez vous obtenir :" & Chr(10) & _
            "- Colonne A : noms des articles déclassés" & Chr(10) & _
            "- Colonne B : ID des articles classés" & Chr(10) & _
            "- Colonne C : Noms des articles classés" & Chr(10) & _
            "- Colonne D : ID des articles déclassés"
Repons = MsgBox(Msg, vbYesNo + vbCritical, "Restitution des données")
If Repons = vbYes Then
    Range("D2").Resize(UBound(TablID), 1) = Application.Transpose(TablID)
    If Message <> "Ces données ont été trouvées colonne A mais pas colonne C :" Then MsgBox Message
    Exit Sub
End If
Msg = "Souhaitez vous obtenir :" & Chr(10) & _
            "- Colonne A : noms des articles déclassés" & Chr(10) & _
            "- Colonne B : ID des articles déclassés" & Chr(10) & _
            "- Colonne C : Noms des articles classés" & Chr(10) & _
            "- Colonne D : ID des articles classés"
Repons = MsgBox(Msg, vbYesNo + vbCritical, "Restitution des données")
If Repons = vbYes Then
    Range("B2", Range("C" & Rows.Count).End(xlUp)).ClearContents
    Range("B2").Resize(UBound(TablID), 1) = Application.Transpose(TablID)
    Range("C2").Resize(MonDico.Count) = Application.Transpose(MonDico.keys)
    Range("D2").Resize(MonDico.Count) = Application.Transpose(MonDico.items)
    If Message <> "Ces données ont été trouvées colonne A mais pas colonne C :" Then MsgBox Message
End If
End Sub

Function SupprimeDoublonsColonneA(Tableau As Variant)
Dim DicoA As Object, i As Long

Set DicoA = CreateObject("Scripting.Dictionary")
For i = LBound(Tableau, 1) To UBound(Tableau, 1)
    If Not DicoA.Exists(Tableau(i, 1)) Then DicoA.Add Tableau(i, 1), Tableau(i, 1)
Next i
Range("A2", Range("A" & Rows.Count).End(xlUp)).ClearContents
Range("A2").Resize(DicoA.Count) = Application.Transpose(DicoA.keys)
End Function
0