XL 2016 VBA-Comparaison données

ynx69

XLDnaute Junior
Bonjour à tous,

Je travaille actuellement sur un petit outil permettant de faire des comparaisons entre une liste entrée par l'utilisateur et une liste existante.

Dans un classeur comportant n feuilles, je souhaite que l'utilisateur entre une liste de code sur la première feuille (admettons que celle-ci s'appelle "Liste". Par la suite je souhaiterais avoir une macro qui va comparer chacune des valeurs entrées par l'utilisateur en parcourant toutes les colonnes de la ligne 3 sur toutes les autres feuilles de mon classeur. Si les 6 premiers caractères de la liste de codes corresponds aux 6 premiers caractères des valeurs présentes sur les feuilles.
- Si il y'a correspondance, alors on conserve les colonnes.
- Si pas de correspondance, on supprime les colonnes.

Concrètement si n codes sont présent dans toutes les feuilles , il ne restera donc à la fin que n colonnes.

J'aimerais à la fin qu'une msgbox apparaissent en indiquant à l'utilisateur la liste de codes qu'il n'a pas pu retrouver.

petite précision : Il peut y avoir un nombre indéfini de codes entrées par l'utilisateur, un nombre indéfini de colonnes en ligne 3 et un nombre indéfini de feuilles.

Merci bcp pour votre aide
 

Pièces jointes

  • Comparaison v1.0.xlsx
    12 KB · Affichages: 24

vgendron

XLDnaute Barbatruc
Bonjour

J'ai pas saisi le besoin..
peux tu nous dire quelles colonnes de quelles feuilles doivent etre gardées.et à quelle condition?
en attendant. en PJ, une formule pour te dire si le code est présent dans les feuilles
 

Pièces jointes

  • Comparaison v1.0.xlsx
    12.6 KB · Affichages: 25

ynx69

XLDnaute Junior
Hello Vgendron

Merci pour ton aide. Je vais tâcher d'expliquer un peu mieux désolé.
Dans un premier temps, j'aimerais passé par une macro.

Mon besoin est le suivant :

Sur le fichier que je t'ai fourni. La première feuille correspond à une liste de code que va entrer l'utilisateur. Il peut y avoir 1 comme 100 codes ( ou plus ). Cette feuille n°1 pour que ce soit plus clair on l'appellera "liste".

Les autres feuilles de mon classeur sont le résultat d'une macro ( elle n'est pas présente dans ce fichier ). La macro va générer un nombre indéfini de feuilles qui possèdent elle même un nombre indéfinies de colonne ).

Ce que je souhaite c'est à partir d'une macro actionnée par un bouton et de la liste de l'utilisateur, que tout ce qui ne correspond pas aux données de la feuille liste soit supprimé dans les autres feuilles. Les codes qui n'auront pas été trouvés par la macro apparaîtront dans une msgbox.
La condition comme je l'ai dis plus haut c'est si les 6 premiers caractères correspondent.

En reprenant l'exemple du fichier excel on aurait donc :

- L'utilisateur entre sa liste
- Il clique sur un bouton / La macro se lance
- le résultat : Une msgbox qui lui indique qu'il n'a pas trouvé les codes ( par exemple Z1,Z2 ect .. ), et si on parcoure les feuilles autre que "liste", il ne resterait que 4 colonnes (abcdef02, CEEEEEEE, F et Z ). Le reste des colonnes aura été supprimé.
 

vgendron

XLDnaute Barbatruc
hmm.. pas encore tout à fait clair cette histoire de 6 caractères.. mais ca devrait se clarifier au fur et à mesure.

toutes tes feuilles (hors liste) créées par une autre macro... sont elles toutes identiques??
c a d.. Ont elles toutes les memes codes dans la ligne 3 ?

est ce que un code de la liste peut etre trouvé dans une feuille et pas dans une autre?
 

ynx69

XLDnaute Junior
Hello Vgendron.

C'est vrai que moi j'ai une idée claire mais c'est compliqué à expliquer.. lol


Alors , oui la macro génère tout le temps le même type de feuille. Tous les codes sont placés en ligne 3. Et pour être plus précis les codes commencent en C et non pas B mais ca c'est pas grave je peux facilement le modifier sur la macro, ce n'est qu'une question d'indice.

Les codes sont différents les uns des autres mais possèdent tous 8 caractères. Les deux derniers sont en fait des indices. Donc globalement le plus important pour moi sont les 6 premiers caractères. Les indices ont peu d'importances.


Ensuite Oui, on peut trouver un code dans une feuille et ne pas le retrouver dans l'autre..
 

vgendron

XLDnaute Barbatruc
Bon..
il y a quand meme un souci entre ce que tu dis (les codes contiennent tous 8 caractères (6 de code + 2 d'indice) et ce que je vois dans le fichier fourni..
E, F, Z, Z1...Z19 ca fait que 1 ou 3 caractères....??

un début de réponse en PJ
==> pour l'instant, je ne m'occupe pas du nombre de caractères..
pour chaque feuille.. si le code n'est pas dans la liste, il est supprimé

pour la zone nommée "Liste_Codes", ouvrir le gestionnaire de noms
 

Pièces jointes

  • Comparaison v1.0.xlsm
    23.1 KB · Affichages: 25

ynx69

XLDnaute Junior
Hello Vgendron,

C'est exactement ce que je recherche et ca fonctionne super bien !


Comment puis-je faire pour indiquer à mon utilisateur les codes qu'il n'est pas parvenu à trouver dans une msgbox ? Comment prendre en compte les 6 premiers caractères ?

En tout les cas je te remercie pour ton aide !

J'ai modifié les codes en leur attribuant 8 caractères.
 

Pièces jointes

  • Comparaison v1.0 (1).xlsm
    23.8 KB · Affichages: 19

vgendron

XLDnaute Barbatruc
Hello
regarde ce code... toujours pas clair pour moi quelles colonnes doivent etre supprimées...
si seulement 6 caractères sont utiles.. pourquoi en saisir 8 ??

VB:
Sub sup()
Application.ScreenUpdating = False
Dim TabCode() As Variant
With Sheets("Liste")
    TabCode = .Range("Liste_Codes").Value 'on place tous les codes saisis de la feuille Liste dans un tablo
    For i = LBound(TabCode, 1) To UBound(TabCode, 1)
        TabCode(i, 1) = Left(TabCode(i, 1), 6) 'on ne garde que les 6 premiers caractères
    Next i
End With

For Each ws In Sheets 'on parcourt toutes les feuilles du classeur
    With ws 'avec la feuille
        If ws.Name <> "Liste" Then 'si on est pas dans la feuille liste
            fin = .Cells(3, .Columns.Count).End(xlToLeft).Column 'on récupère la dernière colonne remplie sur la ligne 3
            For i = fin To 3 Step -1 'pour chaque élément de la ligne 3 (en partant de la droite)
                Code = .Cells(3, i) 'on récupère le code
                For j = LBound(TabCode, 1) To UBound(TabCode, 1) 'on cherche le code dans le tablo
                    If Code Like TabCode(j, 1) & "*" Then 'si les 6 premiers caractères du code sont comme dans la liste
                        .Columns(i).Delete 'on supprime la colonne 'on supprime la colonne
                        Exit For 'on sort de la boucle pour passer au code suivant
                    End If
                Next j
            Next i
        End If
    End With
Next ws
Application.ScreenUpdating = True
End Sub

Note: avec le fichier proposé.. toutes les feuilles sont vidées..
 

ynx69

XLDnaute Junior
Hello Vgendron

Les 6 premiers caractère correspondent au code d'un produit. Les deux derniers caractères sont l'indice de la version.

exemple :
ABCDEF02
ABCDEF03

Dans ce cas là le dernier produit correspond au code ABCDEF03.

Et comme je souhaite voir tous les produits portant ce code alors que je me focus sur les 6 premiers caractères.

Pour revenir à ton point concernant les feuilles qui sont vidées : Si les 6 premiers caractères d'un des code présent dans la feuille liste correspondent aux 6 premiers caractère d'une cellule présent sur la ligne 3 d'une des feuilles alors on conserve la colonne.

Un peu plus clair pour toi ? desolé si j'ai mal défini mon besoin
 

vgendron

XLDnaute Barbatruc
bah non, toujours pas clair
Dans ce cas là le dernier produit correspond au code ABCDEF03.
le code c'est ABCDEF... ou ABCDEF03???

tu ne dis toujours pas avec exemple concret QUELLES colonnes doivent etre supprimées !
regarde dans la PJ
dans la feuille "Liste"
colonne B: les codes tapés manuellement ==> code + indice
colonne C: C'est LE CODE (=6 premiers caractères)

en ligne 3 (ligne jaune), c'est juste recopié les "codesIndices" qu'on peut retrouver dans les différentes feuilles
en zone Verte: formule pour voir si les CODES (de la colonne C) se retrouvent dans les CODES de la zone jaune
si trouvé==> on supprime les "CODES +indices" de la zone jaune
si pas trouvé==> on garde, et c'est ceux la qu'on doit indiqué à l'utilisateur (suffirait qu'il aille regarder les feuilles..)
 

Pièces jointes

  • Comparaison v1.0 (1).xlsm
    24.4 KB · Affichages: 15

ynx69

XLDnaute Junior
Bon je vais refaire une explication la plus complète possible.

J'ai un classeur avec une feuille "liste" suivi de n feuilles avec n colonnes en ligne 3.

Dans ma feuille liste, je dispose d'une zone ou je vais venir placé manuellement des codes à 8 caractères. Les n feuilles qui suivent disposent elles aussi, en ligne 3 et sur chaque cellule, d'un code à 8 chiffres.

Je cherche à trouver une correspondance entre ces codes. Or, il ne s'agit pas de retrouver la correspondance sur les 8 caractères mais sur les 6 premiers. Les deux derniers caractères étant des indices sur la version d'un produit.

En placant donc mes codes à 8 caractères sur ma feuille liste et par l'intermédiaire d'une macro, je cherche à faire la chose suivante :

- L'utilisateur place des codes à 8 caractère dans la feuille liste
- Les n feuilles suivantes sont toutes remplies de codes à 8 caractères que je souhaite donc comparer
- On se focalise uniquement sur les 6 premiers caractères.
- En appuyant sur un bouton, la macro parcours les n feuilles , en ligne 3 et compare les 6 premiers caractères de chaque cellule avec les 6 premiers caractères de chaque cellule de la "liste".
- S'il y a correspondance entre les 6 premiers termes d'un code "liste" et d'un code présent sur les n feuilles, alors on conserve la colonne correspondante. Il ne restera donc que les codes qui auront été trouvé sur les n feuilles. Si des codes ne sont pas trouvés, alors les feuilles n seront vierges.


Maintenant en reprenant l'exemple que je poste ici :

Dans la feuille liste j'ai les codes suivants :

ABCDEF01
ABCDEF02
ABCDEF04
GHIJKL20
ACDLMP04
ESSAYONS


et dans les feuilles qui suivent j'ai :

ABCDEF07
ABCDEF06
GHIJKL01
ACDLMP87
ZZZZZZ55
ESSAII25
GG
DD

En reprenant donc mon explication , après execution de la macro on doit retrouver sur nos n feuilles :

ABCDEF07
ABCDEF06
GHIJKL01
ACDLMP87

et seront donc supprimés :
ZZZZZZ55
ESSAII25
GG
DD

Une msg box apparait :
1 codes n'ont pas été trouvés. ( il s'agit du code ESSAYONS )
n codes ont été supprimés. (nombres de codes supprimés par feuilles )

Pour ce qui est des codes , je conçois que tu ne comprennent pas pourquoi ont écris 8 caractères au lieu de 6 mais ils sont issus d'une extraction qui nous fourni les codes avec 8 caractères.

Merci pour ton aide
 

Pièces jointes

  • Comparaison v3.0.xlsx
    12.9 KB · Affichages: 21

vgendron

XLDnaute Barbatruc
voila qui est un peu plus clair

VB:
Sub sup()
Application.ScreenUpdating = False
Dim TabCode() As Variant
Set dico = CreateObject("Scripting.dictionary")
With Sheets("Liste")
    TabCode = .Range("Liste_Codes").Value 'on place tous les codes saisis de la feuille Liste dans un tablo
    For i = LBound(TabCode, 1) To UBound(TabCode, 1)
        TabCode(i, 1) = Left(TabCode(i, 1), 6) 'on ne garde que les 6 premiers caractères
    Next i
End With

For Each ws In Sheets 'on parcourt toutes les feuilles du classeur
    With ws 'avec la feuille
        If ws.Name <> "Liste" Then 'si on est pas dans la feuille liste
            fin = .Cells(3, .Columns.Count).End(xlToLeft).Column 'on récupère la dernière colonne remplie sur la ligne 3
            For i = fin To 3 Step -1 'pour chaque élément de la ligne 3 (en partant de la droite)
                code = .Cells(3, i) 'on récupère le code
                Trouvé = False
                For j = LBound(TabCode, 1) To UBound(TabCode, 1) 'on cherche le code dans le tablo
                    If code Like TabCode(j, 1) & "*" Then 'si les 6 premiers caractères du code sont comme dans la liste
                        Trouvé = True
                        Exit For 'on sort de la boucle pour passer au code suivant
                    End If
                Next j
                If Trouvé = False Then 'si pas trouvé
                    If Not dico.exists(code) Then 'si on ne l'avait pas déjà identifié
                        dico.Add code, ws.Name 'on l'ajoute au dictionnaire
                    End If
                    .Columns(i).Delete 'on supprime la colonne 'on supprime la colonne
                End If
            Next i
        End If
    End With
Next ws
With Sheets("Liste")
    .Range("A2").Resize(dico.Count) = Application.Transpose(dico.keys) ' on colle les codes non trouvés en colonne A de la feuille Liste
    '.Range("E15").Resize(dico.Count) = Application.Transpose(dico.items)
    a = dico.keys
    For i = LBound(a) To UBound(a) 'on créé une chaine de caractère qui contient tous les codes non trouvés
        ListePasTrouvé = ListePasTrouvé & "-" & a(i)
    Next i
End With
MsgBox "les codes suivants n'ont pas été trouvés: " & Chr(10) & ListePasTrouvé

Application.ScreenUpdating = True
End Sub
 

ynx69

XLDnaute Junior
Hello Vgendron, merci bcp pour ton aide vraiment ! :)

Par contre j'ai une petite erreur en exécutant la macro a partir du dernier fichier que je t'ai transmis.
J'ai une erreur incompatibilité de type ici :

With Sheets("Liste")
.Range("A2").Resize(dico.Count) = Application.Transpose(dico.keys) ' on colle les codes non trouvés en colonne A de la feuille Liste
'.Range("E15").Resize(dico.Count) = Application.Transpose(dico.items)
a = dico.keys
For i = LBound(a) To UBound(a) 'on créé une chaine de caractère qui contient tous les codes non trouvés
ListePasTrouvé = ListePasTrouvé & "-" & a(i)
Next i
End With
MsgBox "les codes suivants n'ont pas été trouvés: " & Chr(10) & ListePasTrouvé

Application.ScreenUpdating = True
End Sub
 

Discussions similaires

Statistiques des forums

Discussions
312 165
Messages
2 085 881
Membres
103 009
dernier inscrit
dede972