Filtrer les données sur base de deux critères indépendants

Bonjour à tous,

Je dois réaliser un projet consistant à partir d'un tableau de données standard, provenant d'un système X et filtrer les données sur base de 2 critères. Je suis partis pour réaliser cela via des formules mais cela devient trop complexe et je m'en mêle les pinceaux. L'objectif c'est d'avoir une solution la plus simplifiée possible.

Voici mon cas.

Tous les mois, j'extrais d'un système un tableau de données. Ce tableau à toujours le même format, les colonnes ne changement pas. Les valeurs cependant, les lignes, peuvent varier selon les périodes.

Pour illustrer l'exemple ci-joint, j'ai des données par département. Il peut y avoir plusieurs données par département.

Je souhaiterais qu'une formule (ou une macro?) puisse filtrer la liste sur base d'un premier critère qui est la phase. Ce critère se traduit par le chiffre 1, 2, 3 ou 4 ou 1 est plus important que 2, 2 plus important que 3 et ainsi de suite. Sachant cela, le système filtre toute la liste en gardant la phase la plus importante. Ensuite, le système filtre une deuxième fois la "nouvelle" liste sur base d'un deuxième critère qui est la date en gardant la date la plus éloignée.

Au final, je me retrouve avec une seule ligne par département et cela reflète la phase la plus importante avec le délai le plus éloigné.

J'ai joint un fichier pour exemple.

Quelqu'un aurait une idée?

Merci d'avance

16exemple.xlsx (13.63 Ko)

Bonjour,

Sub FiltrerListe()
    Dim tbl(), dpt, itm, aa, i%, d As Object, ok As Boolean
    Set d = CreateObject("Scripting.Dictionary")
    aa = ActiveSheet.Range("A1").CurrentRegion.Value2
    For i = 2 To UBound(aa)
        dpt = aa(i, 1)
        If d.exists(dpt) Then
            itm = Split(d(dpt), ";")
            If aa(i, 3) < CInt(itm(1)) Then
                ok = True
            ElseIf aa(i, 4) < CLng(itm(2)) Then
                ok = True
            End If
            If ok Then
                itm = aa(i, 2) & ";" & aa(i, 3) & ";" & aa(i, 4)
                d(dpt) = itm: ok = False
            End If
        Else
            itm = aa(i, 2) & ";" & aa(i, 3) & ";" & aa(i, 4)
            d(dpt) = itm
        End If
    Next i
    ReDim tbl(d.Count, 3): i = 0
    For Each dpt In d.keys
        itm = Split(d(dpt), ";")
        i = i + 1: tbl(i, 0) = dpt: tbl(i, 1) = itm(0)
        tbl(i, 2) = CInt(itm(1)): tbl(i, 3) = CLng(itm(2))
    Next dpt
    itm = Split("Département Décision Phase Date")
    For i = 0 To 3
        tbl(0, i) = itm(i)
    Next i
    Application.ScreenUpdating = False
    With ActiveSheet.Range("J1").Resize(UBound(tbl, 1) + 1, 4)
        .Value = tbl
        With .Rows(1)
            .HorizontalAlignment = xlCenter: .Font.Italic = True
        End With
        .Columns(4).NumberFormat = "dd/mm/yyyy"
        .Columns.AutoFit
    End With
End Sub

Je place le résultat dans les colonnes J à M mais ils peuvent bien sûr être placés n'importe où , il suffit de modifier dans cette ligne :

    With ActiveSheet.Range("J1").Resize(UBound(tbl, 1) + 1, 4)

l'indication de la feuille et la plage identifiée par sa cellule supérieure gauche.

Nous aurons une petite différence sur deux lignes ! VBA ne se trompant pas sur le choix de la date la plus éloignée...

48pincho-exemple.xlsm (20.58 Ko)

Salut Mr Ferrand,

Grand merci pour ton aide. Ma macro fonctionne parfaitement à une exception près

Département Decision Phase Date

A New-York 1 30/06/2018

A Paris 2 31/05/2018

A Bruxelles 1 31/03/2018

Pour le dept A, la date la plus éloignée est bien le 30/06/2018 et non pas le 31/03.

De même pour les données avec dépt B, toi tu obtiens la date la plus proche et moi je recherche la date la plus éloignée.

Une idée comment modifier la macro?

Quand à la différence sur la dernière ligne, c'est une erreur de ma part!

Edit : serait-il possible de m'indiquer quelle partie du code dois-je modifier pour rajouter des colonnes de valeurs? Elles n'interviendront pas dans les conditions de filtrage, mais je devrais probablement rajouter 2 ou 3 colonnes en plus pour obtenir toutes les infos souhaitées.

Merci encore

Date la plus éloignée, je l'ai traduit par date la plus ancienne, donc le numéro de série le moins élevé.

Il faut donc être un peu précis et dire la plus éloignée de quoi quand tu emploie cette expression.

J'attends donc une réponse ne souffrant pas interprétation.

Nous avons donc le choix entre 3 hypothèses : la plus ancienne, qui est donc la plus éloignée du jour où la Terre cessera de tourner autour du Soleil...

la plus récente, qui est alors la plus éloignée du cataclysme ayant provoqué l'extinction des dinausores...

ou alors celle présentant l'écart le plus important par rapport à une date quelconque choisie arbitrairement, écart qui peut donc être négatif (date passée par rapport à la date pivot) ou positif (date future vue de la date de référence), date qu'il faut donc préciser.

et si cette date présente un caractère variable, aujourd'hui par exemple, l'écart variera aussi selon le moment de la mesure et le résultat pourra éventuellement être modifié....

Rajouter des colonnes de valeurs ! On demande toujours de fournir les conditions exactes de la question dès le départ, et cela a une raison, parce que, au cas particulier on n'aura que les colonnes qu'il est prévu de récupérer, et si on modifie ce qui est à récupérer il peut alors s'avérer judicieux de modifier la méthode, car là avec 4 colonnes dont 3 testées, on les récupère individuellement, mais s'il y en a plus il peut s'avérer à un moment plus intéressant de ne consigner qu'un indicateur de ligne pour procéder à la récupération ultérieurement par lignes entières...

Donc précise une bonne fois la configuration sur laquelle tu opères.

Hello MFerrand,

Je pensais que mon explication était assez claire et pas sujette à interprétation. Je vais donc rectifier le tir.

L'objectif est que le système identifie la date la plus éloignée dans le temps, par rapport à la date d'aujourd'hui. Cette notion "d'aujourd'hui" n'a que très peu d'importance, car cela peut se baser sur le passé, le résultat serait le même. Exemple, entre 30/06/2018 et 31/03/2018, la date la plus éloignée par rapport à aujourd'hui sera le 30/06/2018. De même si on prend comme point de départ le 31/12/2010 --> même résultat.

Concernant la configuration de récupération des valeurs dans le tableau, on va rester sur les mêmes données (pour éviter que vous m'engueuliez ).

Pourriez-vous m'indiquer quel changement dois-je opérer pour que la macro prenne la date la plus éloignée svp?

Question bonus, mais pas grave si pas de réponse : existe-t-il y moyen d'obtenir le résultat (le tableau synthétique que la macro produit) mais que les autres lignes, non retenues soient "groupées" avec le petit plus sur le côté et que si on le souhaite, on puisse développer la vue.

Encore un grand merci.

Hello, une petite remontée du topic avant qu'il ne tombe dans les méandres de l'oubli.

Que pourrais-je changer à la macro ci-dessous pour que ce soit la date la plus éloignée par rapport à aujourd'hui qui soit choisie?

Merci m'sieurs'dames.

Sub FiltrerListe()
    Dim tbl(), dpt, itm, aa, i%, d As Object, ok As Boolean
    Set d = CreateObject("Scripting.Dictionary")
    aa = ActiveSheet.Range("A1").CurrentRegion.Value2
    For i = 2 To UBound(aa)
        dpt = aa(i, 1)
        If d.exists(dpt) Then
            itm = Split(d(dpt), ";")
            If aa(i, 3) < CInt(itm(1)) Then
                ok = True
            ElseIf aa(i, 4) < CLng(itm(2)) Then
                ok = True
            End If
            If ok Then
                itm = aa(i, 2) & ";" & aa(i, 3) & ";" & aa(i, 4)
                d(dpt) = itm: ok = False
            End If
        Else
            itm = aa(i, 2) & ";" & aa(i, 3) & ";" & aa(i, 4)
            d(dpt) = itm
        End If
    Next i
    ReDim tbl(d.Count, 3): i = 0
    For Each dpt In d.keys
        itm = Split(d(dpt), ";")
        i = i + 1: tbl(i, 0) = dpt: tbl(i, 1) = itm(0)
        tbl(i, 2) = CInt(itm(1)): tbl(i, 3) = CLng(itm(2))
    Next dpt
    itm = Split("Département Décision Phase Date")
    For i = 0 To 3
        tbl(0, i) = itm(i)
    Next i
    Application.ScreenUpdating = False
    With ActiveSheet.Range("J1").Resize(UBound(tbl, 1) + 1, 4)
        .Value = tbl
        With .Rows(1)
            .HorizontalAlignment = xlCenter: .Font.Italic = True
        End With
        .Columns(4).NumberFormat = "dd/mm/yyyy"
        .Columns.AutoFit
    End With
End Sub

Personne pour un coup de main. Ce serait dommage de ne pas pouvoir utiliser la macro alors qu'elle est à 99% faite...

Bonjour,

Désolé, j'ai dû m'absenter du Forum depuis mi-février, je rattrape...

Réaménagement de la macro pour sélection (par département-phase la plus basse) de la date présentant l'écart le plus important avec la date du jour (où l'on filtre !) :

Sub FiltrerListe()
    Dim tbl(), dpt, itm, aa, ecd&, i%, d As Object, ok As Boolean
    Set d = CreateObject("Scripting.Dictionary")
    aa = ActiveSheet.Range("A1").CurrentRegion.Value2
    For i = 2 To UBound(aa)
        dpt = aa(i, 1)
        ecd = CLng(aa(i, 4)) - CLng(Date)
        If ecd < 0 Then ecd = -ecd
        If d.exists(dpt) Then
            itm = Split(d(dpt), ";")
            If aa(i, 3) < CInt(itm(2)) Then
                ok = True
            ElseIf aa(i, 3) = CInt(itm(2)) And ecd > CLng(itm(0)) Then
                ok = True
            End If
            If ok Then
                itm = ecd & ";" & aa(i, 2) & ";" & aa(i, 3) & ";" & aa(i, 4)
                d(dpt) = itm: ok = False
            End If
        Else
            itm = ecd & ";" & aa(i, 2) & ";" & aa(i, 3) & ";" & aa(i, 4)
            d(dpt) = itm
        End If
    Next i
    ReDim tbl(d.Count, 3): i = 0
    For Each dpt In d.keys
        itm = Split(d(dpt), ";")
        i = i + 1: tbl(i, 0) = dpt: tbl(i, 1) = itm(1)
        tbl(i, 2) = CInt(itm(2)): tbl(i, 3) = CLng(itm(3))
    Next dpt
    itm = Split("Département Décision Phase Date")
    For i = 0 To 3
        tbl(0, i) = itm(i)
    Next i
    Application.ScreenUpdating = False
    With ActiveSheet.Range("J1").Resize(UBound(tbl, 1) + 1, 4)
        .Value = tbl
        With .Rows(1)
            .HorizontalAlignment = xlCenter: .Font.Italic = True
        End With
        .Columns(4).NumberFormat = "dd/mm/yyyy"
        .Columns.AutoFit
    End With
End Sub

Pour les colonnes éventuellement à rajouter, indiquer les libellés d'en-tête ainsi que le type de données de chaque colonne...

Pour la question Bonus, pas compris ce que tu veux obtenir, il faudrait l'illustrer...

Cordialement.

36pincho-exemple.xlsm (23.45 Ko)
Rechercher des sujets similaires à "filtrer donnees base deux criteres independants"