Comparaison valeurs de deux tableaux et extraction valeurs manquantes
Bonjour !
J'ai un petit soucis concernant les formules excel, je pensais que c'était simple avec recherchev() mais ou match() mais ça ne me permet que de faire l'effet inverse.
En fait j'ai une base de données qui contient pour chaque entrée, une date de demande et un nom de client.
Et j'aimerais sortir une liste des clients qu'on a enregistré le mois dernier et dont il n'y a pas de ligne ce mois ci.
Je pensais donc faire deux tableaux avec deux filtres différents ( un avec filtre chronologique = mois dernier et l'autre avec filtre chronologique = ce mois )
Et puis faire la comparaison des deux colonnes avec recherchev ou MATCH mais je me rends compte que c'est l'effet inverse que je cherche. J'aimerais sortir les données qui ne sont pas communes ( les clients qui sont dans le tableau du mois dernier et non dans le tableau de ce mois ) Et puis après, utiliser l'outil "supprimer les doublons d'excel "
Est ce quelqu'un a une piste ? une formule ?
En vous remerciant d'avoir lu
Je mets en pièce jointe mon idée actuelle, même si elle pose des petits soucis car filtrer des tableaux, ça supprimer des lignes donc on peut pas avoir deux tableaux côte à côté mais c'est pas grave je pense.
merci pour l'essai !
En plus c'est du VBA c'est parfait car ça serait super si ça pouvait se faire assez facilement toutes les semaines ^^
Mais en fait ce que j'aimerais bien c'est que dans le tableau qui est crée, il n'y est que inscrit
" D "
Car c'est le seul client qui est inscrit dans le premier tableau " mois dernier " *
Mais qui n'est pas dans le deuxième tableau " mois actuel "
L'objectif c'est que ça sorte une petite liste de clients, sans dates, juste une liste de noms ^^
Merci beaucoup ça marche parfaitement !
Je vais utiliser cette solution, et je me demande, est ce que tu crois que ça serait possible avec des tableaux croisés dynamique ?
ça m'arrangerait encore plus car les tableaux se mettraient à jour automatiquement ( avec les filtres )
je veux dire que à la place d'avoir des tableaux avec des filtres, j'ai mis deux tableaux croisés dynamiques, est ce que tu crois que ce serait possible d'avoir le même résultat ?
juste en affichant donc une liste des clients qui sont dans le tableau du mois dernier et pas dans le tableau de ce mois ?
Si c'est possible ça serait plus que parfait ^^
J'ai fait les tableaux croisés dynamiques pour le test,
merci encore d'avoir lu !
Bonjour
Pour une version en TCD, je passe la main : il y a beaucoup plus compétent que moi en la matière, comme Jean-Eric, par exemple...
Bye !
ça marche !
Merci beaucoup pour la solution avec les tableaux !
SI c'est pas possible une solution avec les TCD, j'utiliserai celle là et elle est dèja très utile !
Au cas où je mets pas encore le sujet en résolu, mais je le mettrai à un moment
Bonjour
Pour une version en TCD, je passe la main : il y a beaucoup plus compétent que moi en la matière, comme Jean-Eric, par exemple...
Bye !
Juste au cas où, est ce que tu penses qu'une solution juste avec un tableau serait possible, ?
Par exemple avec un tableau
Client Date dossier
A 01/06/2019
B 02/06/2019
A 04/06/2019
C 07/06/2019
C 02/07/2019
D 08/07/2019
et avec un code VBA ça sort une liste des clients qui ont été enregistrés le mois dernier mais pas ce mois ci ?
Par exemple dans ce cas
"
A
B
"
Car ils ont pas été enregistrés ce mois ci
ou c'est pas possible, et je reste sur la solution des deux tableaux ^^
ça marche parfaitement !
merci beaucoup !
c'est vraiment parfait avec un seul tableau !
par contre j'ai essayé de l'adapter au fichier que j'utilise et j'ai un peu de mal, car idéalement, le bouton serait serait une feuille, le tableau serait sur une autre et la liste de clients serait encore sur une autre ( et le tableau contient 29 colonnes, les nom des client sont à la colonne 13 et les dates à la 17 ). Et le code que j'ai adapté ne me sort que un "1 "dans la liste des clients ^^
Est ce que tu pourrais me dire ce que j'ai oublié pour finaliser ^^ ?
Je mets en pièce jointe le fichier sur lequel je travaille :
Et le code qui marchait parfaitement que j'ai essayé d'adapter et que j'ai tout cassé
Option Explicit
Dim dico As Object, tablo, k, kP
Dim i&, j&, ln&
Sub LeMoisDernier()
Set dico = CreateObject("Scripting.Dictionary")
tablo = Sheets(2).Range("A2:AC" & Range("A" & Rows.Count).End(xlUp).Row)
For i = 2 To UBound(tablo, 1)
If tablo(i, 17) < DateSerial(Year(Date), Month(Date), 1) _
And tablo(i, 17) >= DateSerial(Year(Date), Month(Date) - 1, 1) Then
dico(tablo(i, 1)) = ""
Else
If dico.exists(tablo(i, 1)) Then
dico.Remove (tablo(i, 1))
End If
End If
Next i
Sheets(3).Range("C7").CurrentRegion.ClearContents
On Error GoTo fin
Sheets(3).Range("C7").Resize(dico.Count, 1) = Application.Transpose(dico.keys)
Sheets(3).Range("C7:C" & Application.Max(7, Sheets(3).Range("C" & Rows.Count).End(xlUp).Row)).Sort _
key1:=Sheets(3).Range("C7"), order1:=xlAscending, Header:=xlNo
fin:
End Sub
Merci beaucoup ! ça m'aide beaucoup pour mon stage et ça me donne très envie d'approfondir le VBA
ça marche parfaitement, j'ai plus qu'à faire 2 petites modifications car c'est pas la bonne colonne qui est choisie dans deux petites ligne je crois ^^
J'ai fait les deux petites modifications et du coup je crois que c'est tout bon !
Si tu me peux confirmer que j'ai pas oublié un truc dans la modification
- And tablo(i, 2) => Là pour le num de colonne , je mets le numéro de la colonne avec les dates donc And tablo(i, 17 ) ?
- dico(tablo(i, 1)) = "" => Là pour le le num de colonne, je mets le numéro de la colonne avec les clients donc dico(tablo(i, 13)) ?
- If dico.exists(tablo(i, 1)) Then
dico.Remove (tablo(i, 1))
=>
Là pour les deux numéros du colonne , à la place du 1 je mets 13 aussi car c'est le numéro de la colonne avec les noms des clients ?
Et après là ça marche très bien je crois ^^
Bonjour
Je crois que tu as tout compris. Bravo !!!
Bienvenue au club des amateurs de VBA !
Bye !
Merci beaucoup !
le VBA c'est la vie !
Au cas où tu puisses toujours voir ce message,
le sujet est résolu mais je ne comprends pas une ligne, est ce que tu pourrais m'expliquer ?
" fl.Range("C7:G" & Application.Max(7, fl.Range("C" & Rows.Count).End(xlUp).Row)).Sort _ "
Pourquoi est ce qu'on choisit jusqu'à la colonne G ?
Merci beaucoup ! C'est ce que je commençais à penser, je deviens vraiment un ptit apprenti.
J'ai essayé de faire encore plus de choses avec ce code, si je peux encore te demander une dernière aide sur ce code
J'ai essayé de demander à la boucle de faire une deuxième liste, qui se base sur les mêmes conditions ( si il y a une entrée dans le tableau pour le mois dernier mais pas ce mois ci ) mais cette fois ci, ça prendrait pas les données de la colonne 13 mais celle de la 14
Mais ça ne marche pas, le formatage marche pour la deuxième liste, mais ça prend les données de la colonne 13 même pour la deuxième liste....
Si je ne me trompe pas, ça vient du fait que j'ai utilisé deux fois la même variable, il faudrait que je déclare une nouvelle variable dico ou créer un nouvel objet "Scripting.Dictionary" ? Mais je ne sais pas comment faire
Voici ce que j'ai fait : j'ai essayé d'intégrer la création de la deuxième liste dans la boucle :
tablo = ft.Range("A2:AC" & ft.Range("A" & Rows.Count).End(xlUp).Row)
For i = 2 To UBound(tablo, 1)
If tablo(i, 17) < DateSerial(Year(Date), Month(Date), 1) _
And tablo(i, 17) >= DateSerial(Year(Date), Month(Date) - 1, 1) Then
dico(tablo(i, 13)) = ""
dico(tablo(i, 14)) = ""
Else
If dico.exists(tablo(i, 13)) Then
dico.Remove (tablo(i, 13))
End If
If dico.exists(tablo(i, 14)) Then
dico.Remove (tablo(i, 14))
End If
End If
Next i
Et j'ai copié / collé le code pour le formatage pour le faire pour la nouvelle liste
fl.Range("C7").CurrentRegion.Clear
On Error GoTo fin
fl.Range("C7").Resize(dico.Count, 1) = Application.Transpose(dico.keys)
fl.Range("C7:G" & Application.Max(7, fl.Range("C" & Rows.Count).End(xlUp).Row)).Sort _
key1:=fl.Range("C7"), order1:=xlAscending, Header:=xlNo
fl.Range("C7").CurrentRegion.Interior.Color = RGB(155, 194, 230)
fl.Activate
fl.Range("E7").CurrentRegion.Clear
On Error GoTo fin
fl.Range("E7").Resize(dico.Count, 1) = Application.Transpose(dico.keys)
fl.Range("E7:E" & Application.Max(7, fl.Range("E" & Rows.Count).End(xlUp).Row)).Sort _
key1:=fl.Range("E7"), order1:=xlAscending, Header:=xlNo
fl.Range("E7").CurrentRegion.Interior.Color = RGB(155, 194, 230)
fl.Activate
fin:
End Sub
Est ce que c'est bien ce que je pense ? il faut que je crée une autre variable pour la colonne 14 ?
Bonjour
Oui et plus précisément un deuxième dictionnaire.il faut que je crée une autre variable pour la colonne 14 ?
Bye !
Super !
Merci beaucoup !
Je vais me renseigner sur ces dictionnaires, et je vais tenter d'en créer un troisième juste pour essayer :p !
Alors comme j'ai dit j'ai essayé de créer un troisième dictionnaire pour tester si j'avais compris la structure du code
J'ai testé le code marche, mais au cas où, est ce que tu pourrais vérifier une partie du code car je ne suis pas sûr
dèja voilà le code avec le troisième dictionnaire qui prend les données de la quinzième colonne
Option Explicit
Dim fl As Worksheet, ft As Worksheet
Dim dico As Object, dico2 As Object, dico3 As Object, tablo, k, kP
Dim i&, j&, ln&
Sub LeMoisDernier()
Set dico = CreateObject("Scripting.Dictionary")
Set dico2 = CreateObject("Scripting.Dictionary")
Set dico3 = CreateObject("Scripting.Dictionary")
Set fl = Sheets("liste")
Set ft = Sheets("tableau ")
tablo = ft.Range("A2:AC" & ft.Range("A" & Rows.Count).End(xlUp).Row)
For i = 2 To UBound(tablo, 1)
If tablo(i, 17) < DateSerial(Year(Date), Month(Date), 1) _
And tablo(i, 17) >= DateSerial(Year(Date), Month(Date) - 1, 1) Then
dico(tablo(i, 13)) = ""
dico2(tablo(i, 14)) = ""
dico3(tablo(i, 15)) = ""
Else
If dico.exists(tablo(i, 13)) Then
dico.Remove (tablo(i, 13))
End If
If dico2.exists(tablo(i, 14)) Then
dico2.Remove (tablo(i, 14))
End If
If dico.exists(tablo(i, 15)) Then
dico.Remove (tablo(i, 15))
End If
End If
Next i
fl.Range("C7").CurrentRegion.Clear
On Error GoTo suite
fl.Range("C7").Resize(dico.Count, 1) = Application.Transpose(dico.keys)
fl.Range("C7:C" & Application.Max(7, fl.Range("C" & Rows.Count).End(xlUp).Row)).Sort _
key1:=fl.Range("C7"), order1:=xlAscending, Header:=xlNo
fl.Range("C7").CurrentRegion.Interior.Color = RGB(155, 194, 230)
fl.Activate
suite:
fl.Range("E7").CurrentRegion.Clear
On Error GoTo suite2
fl.Range("E7").Resize(dico2.Count, 1) = Application.Transpose(dico2.keys)
fl.Range("E7:E" & Application.Max(7, fl.Range("E" & Rows.Count).End(xlUp).Row)).Sort _
key1:=fl.Range("E7"), order1:=xlAscending, Header:=xlNo
fl.Range("E7").CurrentRegion.Interior.Color = RGB(155, 194, 230)
fl.Activate
suite2:
fl.Range("G7").CurrentRegion.Clear
On Error GoTo fin
fl.Range("G7").Resize(dico3.Count, 1) = Application.Transpose(dico3.keys)
fl.Range("G7:G" & Application.Max(7, fl.Range("G" & Rows.Count).End(xlUp).Row)).Sort _
key1:=fl.Range("G7"), order1:=xlAscending, Header:=xlNo
fl.Range("G7").CurrentRegion.Interior.Color = RGB(155, 194, 230)
fl.Activate
fin:
End Sub
Et je ne suis pas sûr de cette partie :
" On Error GoTo suite2 "
" suite2: "
Est ce que j'ai le droit de faire comme ça ?
( j'ai pris l'exemple du précédent code où il était inséré
On Error GoTo suite )
Merci beaucoup d'avoir autant suivi mon cas ^^