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
 

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.
 

citizenbaban

XLDnaute Junior
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.
Bonjour Staple1600,

Là j'avoue que je suis perdu :(
 

Staple1600

XLDnaute Barbatruc
Bonsoir le fil,

Alors pour de te deperdre
1er version
Dim x
x = Application.Match(Target, [liste], 0)
If Application.CountIf([colA], Target) > 1 Then
puis dans la dernière version, un changement apparait
Dim x
If Application.CountIf([colA], Target) > 1 Then
x = Application.Match(Target, [liste], 0)
 

citizenbaban

XLDnaute Junior
Bonsoir le fil,

Alors pour de te deperdre
1er version
Dim x
x = Application.Match(Target, [liste], 0)
If Application.CountIf([colA], Target) > 1 Then
puis dans la dernière version, un changement apparait
Dim x
If Application.CountIf([colA], Target) > 1 Then
x = Application.Match(Target, [liste], 0)
Hello,

J'avais bien vu la différence entre les 2 mais je ne suis pas vraiment plus avancé sur le fonctionnement lol.
J'ai trouvé une alternative un peu moins académique mais ça fonctionne alors ce n'est pas grave :)
 

Staple1600

XLDnaute Barbatruc
Re,

citizenbaban
Que tu ais trouvé une alternative fonctionnelle , c'est bien ;)
Que tu ne la postes pas ici, pour rester dans l'esprit du forum (le partage des connaissances), c'est moins bien ;)

PS:message écrit sans la moindre animosité, mais je le concède, avec juste un soupçon d'ironie amicale.
Donc inutile que les esprits s'échauffent, la canicule s'en charge déjà ;)

Mais c'est pas grave, cela corrrespond bien aux moeurs des temps actuels...
 
Dernière édition:

citizenbaban

XLDnaute Junior
Re,

citizenbaban
Que tu ais trouvé une alternative fonctionnelle , c'est bien ;)
Que tu ne la postes pas ici, pour rester dans l'esprit du forum (le partage des connaissances), c'est moins bien ;)

PS:message écrit sans la moindre animosité, mais je le concède, avec juste un soupçon d'ironie amicale.
Donc inutile que les esprits s'échauffent, la canicule s'en charge déjà ;)

Mais c'est pas grave, cela corrrespond bien aux moeurs des temps actuels...
Hello,

L'alternative que j'ai trouvée est assez éloignée de l'idée initiale, ça aurait plus pollué le post qu'autre chose mais je peux tout de même le poster.
J'ai simplement ajouté une formule nb.si(A4:A150;"La_Famille")


VB:
Private Sub Worksheet_Change(ByVal Nb_De_Fam As Range)

Dim Entero As Range
Dim Pseudo As Range
Dim Staph As Range
   
Set Nb_De_Fam = Sheets("Résultats bruts").Range("B2")
Set Entero = Sheets("Résultats bruts").Range("E157")
Set Pseudo = Sheets("Résultats bruts").Range("F157")
Set Staph = Sheets("Résultats bruts").Range("G157")


      Sheets("Résultats bruts").Columns("P:AA").EntireColumn.Hidden = True
      Sheets("Calcul du mode").Columns("T:AM").EntireColumn.Hidden = True
      Sheets("Calcul d'EA").Columns("N:U").EntireColumn.Hidden = True
      Sheets("Calcul d'EA").Range("V:BX").EntireColumn.Hidden = True

'-----------------PAR DEFAUT---------------

'Si présence tableau vide
    If Nb_De_Fam.Value < 1 Then
    Exit Sub
    End If

'------------SI 5 Fam-------------
    If Nb_De_Fam.Value = 5 Then
    Call Cinq_Fam
    End If



ETC

Avec plusieurs conditions qui en découlent

Sub Cinq_Fam()

    If Nb_De_Fam.Value = 5 And Entero.Value > 0 And Pseudo.Value > 0 And Staph.Value > 0 Then
      Sheets("Résultats bruts").Columns("P:AA").EntireColumn.Hidden = False
      Sheets("Calcul du mode").Columns("T:AM").EntireColumn.Hidden = False
      Sheets("Calcul d'EA").Columns("N:U").EntireColumn.Hidden = False
      Sheets("Calcul d'EA").Range("V:BX").EntireColumn.Hidden = False

    ElseIf Nb_De_Fam.Value = 5 And Entero.Value > 0 And Pseudo.Value > 0 And Staph.Value = 0 Then
    '[etc pour toutes les conditions]

End If
End Sub


Etc, avec 160 conditions en tout. Donc pas super clean, voir même carrément moche lol mais ça tourne quand même rapidement donc ça ira.
J'étudierai ton code à tête reposée pendant les vacances ^^
 
Dernière édition:

Staple1600

XLDnaute Barbatruc
Bonjour le fil,

Quitte à poster, autant poster l'entièreté du code, non?
Histoire de pouvoir tester
(et qui sait peut-être qu'un membre du forum pourrait te proposer un "allégement" de code)

NB: En théorie (et à l'usage) l'initiateur d'un fil ne pollue jamais son fil avec ses interventions puisque c'est le sien à la base ;)
 

citizenbaban

XLDnaute Junior
Bonjour le fil,

Quitte à poster, autant poster l'entièreté du code, non?
Histoire de pouvoir tester
(et qui sait peut-être qu'un membre du forum pourrait te proposer un "allégement" de code)

NB: En théorie (et à l'usage) l'initiateur d'un fil ne pollue jamais son fil avec ses interventions puisque c'est le sien à la base ;)
Le code fait 1100 lignes et ce ne sont que des conditions. Je veux bien le mettre mais je pense que ce ne sera pas très pertinent lol
 

Staple1600

XLDnaute Barbatruc
Re

Je parlais uniquement du code qui est censé faire ceci
"Masquer des colonnes en fonction des valeurs d'une plage avec menu déroulant"
Et j'ai du mal à croire que ce code pour cette simple action fasse 1100 lignes

NB: Je parlais de cette procédure nommée Cinq_Fam que tu as postée tronquée.
 

citizenbaban

XLDnaute Junior
Re

Je parlais uniquement du code qui est censé faire ceci
"Masquer des colonnes en fonction des valeurs d'une plage avec menu déroulant"
Et j'ai du mal à croire que ce code pour cette simple action fasse 1100 lignes

NB: Je parlais de cette procédure nommée Cinq_Fam que tu as postée tronquée.
Bonjour,
J'ai complété le bout de code qui manquait (et étant donné que j'ai 240 conditions différentes, si, le code est long), mais pas pour le code "Masquer des colonnes en fonction des valeurs d'une plage avec menu déroulant" vu que j'ai dis que j'avais changé d'approche entre temps pour ne faire référence qu'à une seule cellule et non plus un menu déroulant, faute de temps pour comprendre la macro.

Citizen
 

Discussions similaires

Statistiques des forums

Discussions
312 103
Messages
2 085 312
Membres
102 860
dernier inscrit
fredo67