Tri sur plusieurs colonnes d'un tableau simultanément

Bonjour,

Tout nouveau sur ce forum, je m'adresse à vous car après quelques essais, je n'arrive pas à trouver la réponse à ce que je cherche.

J'ai un tableau où chaque ligne présente plusieurs critères qui définissent un produit (donc un produit par ligne). Il va y avoir de nombreuses lignes et de nombreuses colonnes. Je joins un fichier ici très simplifié.

Le but est de rentrer les critères d'un produit un à un. A chaque fois que l'on entre un critère, qu'un tri se fasse uniquement sur les critères de la même colonne. Plus on rentre de critères, et plus le tri est restrictif

Le but est de se dire : s'il y a une valeur dans la cellule du critère 1 (C3) alors seules les cases non vides de la colonne sous la cellule C3 doivent apparaitre.

J'aimerai pouvoir faire cela simplement (pas sous VBA). Initialement j'ai créé un tableau de toutes mes données et j'ai tenté de faire un renvoi avec une formule de ce type :

FILTRE(tableau,(SI(C9<>"",tableau[Colonne2]<>"",""))*(SI(D9<>"",tableau[Colonne3]<>"",""))*(SI(E9<>"",tableau[Colonne4]<>"",""))),"Aucun résultat")

en mettant autant d'argument <*(SI(E9<>"",tableau[Colonne4]<>"","")> que de critère dans mon tableau

Mais il est logique que cela ne puisse pas répondre à la question. Aussi, je m'en remets à vous pour m'aider / m'aiguiller dans ma recherche

Par avance, merci beaucoup

Lolo

Salut Lolo,

Sans VBA, je ne sais pas comment faire : c'est toujours ça !
Si je comprends bien ta demande, la valeur en [C3:I3] n'a pas d'importance : pourquoi prends-tu dès lors le soin d'encoder des nombres aussi précis ?
Ici, de base, en cliquant sur [C3:I3], la macro écrit "1" ou "" selon que la cellule est vide ou non.

If Not Intersect(Target, Range("C3:I3")) Is Nothing Then _
    Target = IIf(Target = "", 1, ""): _
    Target.Offset(-1, 0).Select Dès lors, le tableau est filtréPrivate Sub Worksheet_Change(ByVal Target As Range)

Dès lors, le filtre est mis en place.

If Not Intersect(Target, Range("C3:I3")) Is Nothing Then
    ActiveSheet.AutoFilterMode = False
    With Range("B6:I6")
        .AutoFilter
        For x = 3 To 9
            If Cells(3, x) <> "" Then .AutoFilter Field:=x - 1, Criteria1:="<>", Operator:=xlAnd
        Next
    End With
End If

Un clic sur la cellule "SHOW" équivaut à ShowAllData pour annuler les filtres en place.

3lolo.xlsm (28.64 Ko)


A+

Tout d'abord merci pour ta réponse Curulis

pourquoi prends-tu dès lors le soin d'encoder des nombres aussi précis ?

Ta question est tout à fait légitime. Chaque colonne représente une substance et chaque ligne un produit. Un produit contient différentes substances à certaines teneurs / % (les valeurs dans les cases).

Ces valeurs sont importantes car normalement le tri devrait se faire sur la présence des valeurs de chaque critères dans les différentes lignes ET il faudrait que la valeur de la ligne soit pas très éloignée de celle rentrée dans le critère. En gros le résultat doit présenter les valeurs dans les mêmes colonnes que les critères rentrés et les valeurs des lignes doivent être proche de la valeur mise dans le critère (avec une incertitude donnée).

Le problème est que si je fais cela, je risque d'être trop restrictif et l'outil ne servira à rien (c'est une sorte de base de données en fait). Après on peut mettre une incertitude de 100% par défaut lorsqu'on ne veut pas être restrictif et la changer lorsqu'on veut l'être davantage...

Je pensais initialement le faire en 2 temps. D'abord, le tri se fait par la simple présence et une fois que le tri est fait, visuellement on regarde les % qui matchent le mieux avec les critères que l'on a défini.

C'est moins bien c'est sûr mais faire le tri avec les deux éléments me paraissait trop complexe (surtout en ajoutant une incertitude modifiable).

Pour le VBA, mon problème est que je n'ai jamais touché du coup, je ne saurai même pas modifier une macro existante... Sinon je ne suis pas contre bien entendu :)

Encore merci infiniment pour ton aide

Bien à toi

Lolo

Salut Lolo,

ainsi, sans doute...
La cellule "SHOW" (qui conserve le même usage de Reset) est remplacée par le pourcentage en plus et moins calculé sur la valeur que tu encodes en zone de critère.
Le filtre s'applique alors entre les bornes ainsi calculées.

Private Sub Worksheet_Change(ByVal Target As Range)
'
Dim dbMoins#, dbPlus#
'
Application.EnableEvents = False
'
If Not Intersect(Target, Range("C3:I3")) Is Nothing Then
    ActiveSheet.AutoFilterMode = False
    With Range("B5:I5")
        .AutoFilter
        For x = 3 To 9
            If Cells(3, x) <> "" Then _
                dbMoins = Cells(3, x) - (Cells(3, x) * [B3]): _
                dbPlus = Cells(3, x) + (Cells(3, x) * [B3]): _
                .AutoFilter Field:=x - 1, Criteria1:=">=" & dbMoins, Operator:=xlAnd, Criteria2:="<=" & dbPlus
        Next
    End With
End If
'
Application.EnableEvents = True
'
End Sub

À toi de jouer !

13lolo.xlsm (32.84 Ko)


A+

Je n'ai qu'un mot à dire : bravo !

Merci c'est exactement cela. Cela semble si facile.

Tu vas me faire gagner beaucoup de temps!

Encore merci pour l'aide apportée

Bonjour Curulis,

Cela va paraitre très bête mais je n'ai pas réussi à l'incorporer dans mon fichier initial. Pour tenter de comprendre, j'ai ajouter des colonnes, lignes etc sur ton fichier en changeant le code et tout va bien. Mais lorsque j'ai inséré une ligne en haut de ton fichier, j'ai modifié le code mais à ce moment, le tri ne fonctionne plus.

Comme je ne comprends pas du tout le code, j'imagine que c'est au niveau de cette partie :

If Cells(3, x) <> "" Then _

dbMoins = Cells(3, x) - (Cells(3, x) * [B3]): _

dbPlus = Cells(3, x) + (Cells(3, x) * [B3]): _

.AutoFilter Field:=x - 1, Criteria1:=">=" & dbMoins, Operator:=xlAnd, Criteria2:="<=" & dbPlus

A quoi cela correspond exactement ? Sinon, quelle partie du code je dois modifier lorsque le tableau grandit, que j'insère des lignes (etc...) afin de que je puisse modifier à ma guise le fichier ?

Désolé pour cette question très bête et merci par avance !

Lolo

Salut Lolo,

j'allais justement t'envoyer une correction, ayant remarqué une erreur due à mon ignorance en cette matière.
Les valeurs dbMoins et dbPlus, bornes du filtre doivent être converties en String.

Criteria1:=">=" & Str(dbMoins), Operator:=xlAnd, Criteria2:="<=" & Str(dbPlus)

Private Sub Worksheet_Change(ByVal Target As Range)
'
Dim dbMoins#, dbPlus#
'
Application.EnableEvents = False
'
If Not Intersect(Target, Range("C3:I3")) Is Nothing Then
    With Range("B5")
        .AutoFilter
        For x = 3 To 9
            If Cells(3, x) <> "" Then _
                dbMoins = Cells(3, x) - (Cells(3, x) * [B3]): _
                dbPlus = Cells(3, x) + (Cells(3, x) * [B3]): _
                .AutoFilter Field:=x - 1, Criteria1:=">=" & Str(dbMoins), Operator:=xlAnd, Criteria2:="<=" & Str(dbPlus)
        Next
    End With
End If
'
Application.EnableEvents = True
'
End Sub

- Cells(3, x) : le 3 correspond à la ligne sur laquelle se trouve ta zone d'encodage des critères ;
- For x = 3 To 9 : lecture des critères de la colonne 3 [C:C] à 9 [I:I] ;
- .AutoFilter Field:=x - 1 : Field = la colonne du tableau que tu souhaites filtrer donc, pour une boucle FOR...NEXT de 3 à 9, x-1= 3-1 = 2e colonne du tableau pour le critère 1;
- [B3] : cellule du pourcentage ;
- With Range("B5") : [B5] désigne obligatoirement la première cellule en haut à gauche de ton tableau à filtrer.

Avec ça, tu peux placer ton tableau et/ou ta zone de critères où bon te semble tant que ces variables sont bien ajustées !!


A+

Salut Curulis

Super, c'est nickel je n'avais pas fait attention à cette partie : "Cells(3, x)"

Tout fonctionne parfaitement vraiment merci beaucoup. Je l'ai donc implémenté facilement dans mon fichier :)

Encore merci infiniment !!!

Lolo

Rechercher des sujets similaires à "tri colonnes tableau simultanement"