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" 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).
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.
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
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.
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 ^^
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.
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.
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)
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)
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
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...
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...
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 ^^
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
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
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.
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.