Résolu Masquer des colonnes en fonction des valeurs d'une plage avec menu déroulant

citizenbaban

XLDnaute Junior
Bonjour à tous,

Petit problème avec une macro d'affichage/masquage de colonnes. J'ai cherché sur le forum et un peu sur le net mais j'ai surtout trouvé des solutions qui ne s'appliquent que pour une cellule et pas une plage de cellule.
Voici l'idée :

En colonne A, de A3 à A150 des cellules à menu déroulant "Test1; Test2; Tets3".
En fonction de la valeur retenue en A : afficher les colonnes "B:D" si Test 1, "E:G" si Test2 et "H:J" si Test 3, et si cellule A vide : "B:J" masqué.

Ca, j'arrive à le faire avec ce code :


VB:
Private Sub Worksheet_Change(ByVal Target As Range)
    
    Dim h, iSct As Range
    Set iSct = Intersect(Target, Range("A2:A150"))
    If iSct Is Nothing Then Exit Sub
        
    Application.EnableEvents = True
    For Each h In iSct.Cells
            If IsEmpty(h) Then
            Columns("B:J").Hidden = True
            
            ElseIf h.Value = "Test1" Then
            Columns("B:D").Hidden = False
                
            ElseIf h.Value = "Test2" Then
            Columns("E:G").Hidden = False
            
            ElseIf h.Value = "Test3" Then
            Columns("H:J").Hidden = False
            
        End If

        Next
      
End Sub

Le truc c'est que si je supprime un Test sur une ligne, ça ne prend pas en compte les valeurs des cellules au dessus/en dessous, idem si un Test3 est remplacé par un Test2 par exemple.

Est-ce que vous auriez une idée pour "interconnecter" les valeurs en A ? (sachant que le A150 est pris pour être large, le nombre de saisies en A sera variable).

Merci à tous,

Citizen
 

Iznogood1

XLDnaute Impliqué
Bonjour,

je ne comprends pas la logique.
En fonction de la valeur retenue en A : afficher les colonnes "B : D" si Test 1, "E:G" si Test2 et "H:J" si Test 3, et si cellule A vide : "B:J" masqué.
Quelles colonnes doivent être affichées s'il y a "Test1" en A3 et "Test2" en A4 ?
(On ne peut pas afficher / masquer des colonnes différentes pour chaque ligne)
 

Staple1600

XLDnaute Barbatruc
Bonjour le fil

citizenbaban
Si tu testes ce code en lieu et place du tien, tu en penses quoi?
VB:
Private Sub Worksheet_Change(ByVal Target As Range)
Columns("B:J").Hidden = True
If IsEmpty(Target) Then Exit Sub
Range(Choose(Right(Target, 1) * 1, "B:D", "E:G", "H:J")).Columns.Hidden = False
End Sub
EDITION
Bonjour Iznogood1
 

citizenbaban

XLDnaute Junior
Bonjour le fil

citizenbaban
Si tu testes ce code en lieu et place du tien, tu en penses quoi?
VB:
Private Sub Worksheet_Change(ByVal Target As Range)
Columns("B:J").Hidden = True
If IsEmpty(Target) Then Exit Sub
Range(Choose(Right(Target, 1) * 1, "B:D", "E:G", "H:J")).Columns.Hidden = False
End Sub
EDITION
Bonjour Iznogood1
Bonjour Staple1600, Iznogood,
J'ai une incompatiblité de type, erreur d'execution 13 sur la ligne
Range(Choose(Right(Target, 1) * 1, "B:D", "E:G", "H:J")).Columns.Hidden = False

Le Test1/Test2/Test3 sont génériques, j'ai mis ça car je n'ai pas encore l'intitulé exact de tous les termes qui seront dans la liste déroulante, mais ils ne suivront pas une incrémentation.
 

Staple1600

XLDnaute Barbatruc
Re

J'ai suivi ton exemple
Testes avec dans la liste déroulante les valeurs Test1,Test2,Test3
et tu n'auras pas d'erreur.

Quand tu nous donneras les intitulés exacts, j'adapterai mon code. ;)
Pour le moment, nous sommes en période de test, donc je teste selon les éléments du message 1 ;)
(et mon test est OK sur mon PC, sinon je n'aurai pas posté mon code...)
 

citizenbaban

XLDnaute Junior
Bonjour,

je ne comprends pas la logique.


Quelles colonnes doivent être affichées s'il y a "Test1" en A3 et "Test2" en A4 ?
(On ne peut pas afficher / masquer des colonnes différentes pour chaque ligne)
En fait je voudrais :
-si rien entre A3:A150 : colonnes B ) J masquées
- si 1 valeur ou + par test : afficher les colonnes correspondantes

Et du coup en écrivant ça je crois que je viens de trouver une piste lol. Il me suffirait juste de définir la plage A3:A150 et de mettre en critère :
- si nombre de Test 1>0 alors masquer colonnes B à D
- si nombre de Test 2>0 alors masquer colonnes E à G
etc

Non ?
 

citizenbaban

XLDnaute Junior
Re

J'ai suivi ton exemple
Testes avec dans la liste déroulante les valeurs Test1,Test2,Test3
et tu n'auras pas d'erreur.

Quand tu nous donneras les intitulés exacts, j'adapterai mon code. ;)
Pour le moment, nous sommes en période de test, donc je teste selon les éléments du message 1 ;)
(et mon test est OK sur mon PC, sinon je n'aurai pas posté mon code...)
Exact, j'avais fait le boulet.
donc ça marche ligne par ligne effectivement mais ça ne tient pas compte des valeurs avant/après :
si je met Test1 en A2, il affiche bien les colonnes B à D mais si je mets Test 2 en A3, ces cette condition qui s'applique donc ça masque B à D pour afficher E à F, or j'aimerai que les conditions se cumulent en quelque sorte.

Je peux essayer de vous faire un fichier pour expliquer un peu mieux mais il faut que je l'anonymise avant :(
 

Staple1600

XLDnaute Barbatruc
Re

Je suis dans le même questionnemnt qu'Iznogood1 quant à la logique de la chose.
Mon code se base sur le Target
Donc si on change de cellule, c'est logique que le masquage/démasquage change à chaque fois, non?

NB:
Je peux essayer de vous faire un fichier pour expliquer un peu mieux mais il faut que je l'anonymise avant :(
Si ce petit fichier eut été là dès le départ, nous ne serions pas arrivé au message#8 ;)
 

citizenbaban

XLDnaute Junior
Re

Je suis dans le même questionnemnt qu'Iznogood1 quant à la logique de la chose.
Mon code se base sur le Target
Donc si on change de cellule, c'est logique que le masquage/démasquage change à chaque fois, non?

NB:
Oui c'est logique :)

En fait c'est un fichier qui doit servir au traitement de résultats de beaucoup d'espèces de bactéries. En A seront notées les familles (Staphylocoques, entérobactéries ceux là je pense que vous les connaissez ^^ mais il y en a des dizaines d'autres) et les colonnes serviront à réaliser les traitements de résultats par famille. Donc là actuellement j'ai un tableau qui va jusqu'en CW. Ingérable si il est ouvert "en l'état".

L'idée était donc d'avoir toutes les espèces de bactéries en colonne B qui seront rentrées manuellement, et leur famille choisie par menu déroulant en colonne A (pas possible de l'automatiser ça) donc je peux me retrouver avec 15 Staphylocoques, 34 entérobactéries, et 3 autres familles par exemple.
L'idée c'est de n'afficher automatiquement que les colonnes "utiles" et de masquer celles des familles qui n'apparaissent pas car ça ne dépassera jamais 5 ou 6 familles donc lisible sur un écran d'ordi ou sur une impression A3.

Ce n'est peut etre pas très clair lol, je vais essayer d'anonymiser un fichier pour le début d'après-midi :)
 

citizenbaban

XLDnaute Junior
Voici le fichier draft, grandement épuré. Je n'ai mis que 5 "blocs famille" dans le tableau pour ne pas le charger inutilement :) (5 blocs de 3 colonnes de couleurs différentes juste avant la colonne "remarque").

Bon appétit
 

Fichiers joints

Staple1600

XLDnaute Barbatruc
Re

Un peu trop épuré à mon goût...
L'est où la liste déroulante en colonne A (avec les valeurs idoines au lieu de Test1,Test2 et Test3?
 

Staple1600

XLDnaute Barbatruc
Re

Chez moi aucune lise déroulante en A4:A150
(mise en place avec Données/Validation)
Bizarrre ou alors elle a disparue lors du downgrading du *.xlsm en *.xls

Du coup, je viens de nommer liste la plage A3:A22
et j'ai recréé la liste déroulante (avecAutoriser: Liste et Source=liste)
 

Staple1600

XLDnaute Barbatruc
Re

En attendant de tes nouvelles, je suis parti sur cette piste
Tu en penses quoi?
(C'est juste pour un test, pour la logique du truc)
VB:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim x
x = Application.Match(Target, [liste], 0)
If Application.CountIf([colA], Target) > 1 Then
Select Case x
Case 1, 3, 5, 7
MsgBox "titi"
Case 2, 4, 6, 7, 8
MsgBox "toto"
Case Is > 13
MsgBox "tutu"
End Select
End If
End Sub
liste et colA correspondent à des plages nommées
et selon la valeur renvoyée par Application.Match dans le Select Case, on lance telle ou telle action
(symbolisée ici pour le test par des MsgBox)
 

citizenbaban

XLDnaute Junior
Re

Chez moi aucune lise déroulante en A4:A150
(mise en place avec Données/Validation)
Bizarrre ou alors elle a disparue lors du downgrading du *.xlsm en *.xls

Du coup, je viens de nommer liste la plage A3:A22
et j'ai recréé la liste déroulante (avecAutoriser: Liste et Source=liste)
Ha oui bizarre en effet, je la retrouvais bien en ouvrant le fichier ici.
Je regarde de suite :)

Tu peux m'expliquer ton code stp? je n'ai jamais utilisé les case
 
Dernière édition:

Staple1600

XLDnaute Barbatruc
Re

Mon code n'est qu'une ébauche de piste
Copie le dans ton fichier exemple, et testes-le
(Evidemment, avant nomme les plages de cellules avec les noms qu'utilise le code VBA
colA ='Résultats bruts'!$A$4:$A$148
liste =donnée!$A$3:$A$22

Tu vois alors ce qui se passe selon la valeur que tu affiches en colonne A avec la liste déroulante.
 

citizenbaban

XLDnaute Junior
Re

Mon code n'est qu'une ébauche de piste
Copie le dans ton fichier exemple, et testes-le
(Evidemment, avant nomme les plages de cellules avec les noms qu'utilise le code VBA
colA ='Résultats bruts'!$A$4:$A$148
liste =donnée!$A$3:$A$22

Tu vois alors ce qui se passe selon la valeur que tu affiches en colonne A avec la liste déroulante.
Oui c'est ce que j'ai fait mais des fois ça marche, des fois ça ne marche pas et je n'arrive pas à ressortir une tendance.
Par exemple en A28, les cas 1, 3, 5 et 7 marchent mais c'est tout. En A27 c'est 1,2,3,5 et 7.
En A25 le >13 ne marche que pour les valeurs 18 et 20 de la liste o_O
 

Staple1600

XLDnaute Barbatruc
Re

Le principe est simple pourtant (et encore un fois ce n'est qu'une ébauche, un exemple donc forcément incomplet)
Donc explication, liste correspond à la plage de cellules donnée!$A$3:$A$22
Donc A3 apparait en 1ere position dans cette plage et A22 en 20ième
Maintenant si sur la feuille Résultats bruts, on choisit une valeur avec la liste déroulante
Cette partie du code VBA
x = Application.Match(Target, [liste], 0)
renvoie la position de la valeur dans la plage nommée liste
Par exemple, si on choisit Enterococcus spp alors x vaut 2
et grâce au Select Case
on voit que pour la valeur 2, on affichera toto avec le MsgBox

Donc à toi de paramétrer les Case1,2,n etc selon que ce tu veux masquer/afficher

VB:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim x
Columns("B:AB").Hidden = True
If Application.CountIf([colA], Target) > 0 Then
x = Application.Match(Target, [liste], 0)
Select Case x
Case 1, 3, 5, 7 'ici à toi de mettre les "bons numéros"
Columns("J:L").Hidden = False
Case 2, 4, 6, 7, 8
MsgBox "toto" 'à modifier comme le premier Case
Case Is > 13
MsgBox "tutu" 'etc..
End Select
End If
End Sub
Est-ce que tu vois mieux la logique du truc?

Encore une fois c'est juste une piste à creuser ou pas.
A toi de tester et peaufiner le truc et nous redire. ;)
 

citizenbaban

XLDnaute Junior
Re

Le principe est simple pourtant (et encore un fois ce n'est qu'une ébauche, un exemple donc forcément incomplet)
Donc explication, liste correspond à la plage de cellules donnée!$A$3:$A$22
Donc A3 apparait en 1ere position dans cette plage et A22 en 20ième
Maintenant si sur la feuille Résultats bruts, on choisit une valeur avec la liste déroulante
Cette partie du code VBA
x = Application.Match(Target, [liste], 0)
renvoie la position de la valeur dans la plage nommée liste
Par exemple, si on choisit Enterococcus spp alors x vaut 2
et grâce au Select Case
on voit que pour la valeur 2, on affichera toto avec le MsgBox

Donc à toi de paramétrer les Case1,2,n etc selon que ce tu veux masquer/afficher

VB:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim x
Columns("B:AB").Hidden = True
If Application.CountIf([colA], Target) > 0 Then
x = Application.Match(Target, [liste], 0)
Select Case x
Case 1, 3, 5, 7 'ici à toi de mettre les "bons numéros"
Columns("J:L").Hidden = False
Case 2, 4, 6, 7, 8
MsgBox "toto" 'à modifier comme le premier Case
Case Is > 13
MsgBox "tutu" 'etc..
End Select
End If
End Sub
Est-ce que tu vois mieux la logique du truc?

Encore une fois c'est juste une piste à creuser ou pas.
A toi de tester et peaufiner le truc et nous redire. ;)
Oui j'avais compris le code, ce que je ne comprends pas c'est pourquoi le Case 2,4,6,8 marche une fois par ci par là alors que le Case 1,3,5,7 lui marche bien ^^.
Et de même pour le le Case >13 qui ne marche que pour les valeurs 18 et 20 et pas pour les 14, 15, 16, 17 et 19.
Il marche bien chez toi le code ?

Je vais l'adapter, peut être que ça tournera mieux avec une seule valeur par Case même si je n m'explique pas pourquoi le code avec chiffres et titi/toto/tutu ne marche pas.


Bon ça semble marcher avec une valeur par Case :) :

VB:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim x
Columns("M:AB").Hidden = True
If Application.CountIf([colA], Target) > 0 Then
x = Application.Match(Target, [liste], 0)
Select Case x
Case 1
Columns("M:O").Hidden = False
Case 2
Columns("P:R").Hidden = False
Case 3
Columns("S:U").Hidden = False
Case 4
Columns("V:X").Hidden = False
Case 5
Columns("Y:AA").Hidden = False

End Select
End If
End Sub
La question est maintenant : si j'ai le Case 1 en A4 et le Case 2 en A5 par exemple, j'aimerai que les colonnes M à O ET P à R s'affichent et ainsi de suite. Actuellement elles sont remplacées...
Est-ce qu'il est possible d'appliquer les Case non pas sur une cellule isolée mais sur la plage Cal A ?
façon : Si(nb.val("Case1";colA)>0;affiche les colonnes;masque les colonnes) et si....Case2....et si...Case3.... etc

Bon j'ai mal de tête, je vais lâcher prise pour aujourd'hui ^^
 
Dernière édition:

Staple1600

XLDnaute Barbatruc
Re

Regardes le dernier code que j'ai posté et le précédent
Tu verras qu'il y a une ligne de code qui n'est pas à la même place
Cela explique ceci ;)
Et devrait donc éclairer ta lanterne.

PS
Un Case par valeur, dans ce cas ?!?
cela perd tout l'intéret du Select Case

Ici, l'idée étant de regrouper par Case les bactéries de même famille.
 

Haut Bas