Affichage de sheets avec checkbox
Bonsoir.
J'ai quelques difficultés avec les userforms et les événements.
Je souhaite réaliser quelque chose de simple sur le principe.
Créer un userform qui affiche des sheets "fixes" et des sheets que j'aimerais créer dynamiquement avec le nom de toutes les sheets du classeur avec une case à cocher pour laisser à l'opérateur le choix de les afficher ou les masquer.
Comme le nb de caractères max pour le nom d'une sheet est 31 caractères, j'ai déterminé la position des checkbox dynamiques en vertical et en horizontal (3 colonnes de 13 checkbox).
Là où ça se gâte, c'est la gestion de l'événement des check box.
Si la checkbox est cochée, j'affiche la sheet.
À l'inverse, si la checkbox n'est pas cochée, la sheet doit être masquée.
Mon code fonctionne pour l'affichage des checkbox.
Option Explicit
Public MonClasseur As Workbook
Private Sub CheckBox1_Click()
Set MonClasseur = Application.ActiveWorkbook
'CheckBox1.Value = True
'MonClasseur.Worksheets("Page de garde").Visible = True
If CheckBox1.Value = True Then
MonClasseur.Worksheets("Page de garde").Visible = True
Else: MonClasseur.Worksheets("Page de garde").Visible = xlSheetHidden
End If
End Sub
Private Sub CheckBox2_Click()
Set MonClasseur = Application.ActiveWorkbook
If CheckBox2.Value = True Then
MonClasseur.Worksheets("Renseignements généraux").Visible = True
Else: MonClasseur.Worksheets("Renseignements généraux").Visible = xlSheetHidden
End If
End Sub
Private Sub CheckBox3_Click()
Set MonClasseur = Application.ActiveWorkbook
If CheckBox3.Value = True Then
MonClasseur.Worksheets("Documents de référence").Visible = True
Else: MonClasseur.Worksheets("Documents de référence").Visible = xlSheetHidden
End If
End Sub
Je ne comprends pas comment "dire" à toutes les checkbox du userform d'afficher l'état "en cours" des sheets déjà masquées ou affichées.
J'ai bien essayé de rajouter, juste après le set, une "initialisation" du style:
CheckBox1.Value = True
MonClasseur.Worksheets("Page de garde").Visible = True
Histoire de bien caler les choses dès l'apparition de la combobox (qui encapsule toutes les checkbox):
J'aurai ainsi, dès que l'opérateur clique sur le bouton qui lance le userform, toutes les sheets affichées et les checkbox "cochées".
Même si ce n'est pas terrible.
Je souhaite juste qu'après lancement du userform, les checkbox affichent l'état réel des sheets masquées ou affichées.
Auriez-vous des idées sur le comment et/ou le pourquoi du comment ?
Merci d'avance.
Bonjour,
Je ne suis pas un expert mais as-tu essayé de faire simplement :
Private Sub CheckBox1_Click()
If checkbox1.Value = True Then
Sheets("Page de garde").Visible = True
Else
Sheets("Page de garde").Visible = xlVeryHidden
End If
End Sub
et pour avoir avoir les checkbox cochés à l'ouverture de l'userform faire l'inverse :
Sub Userform_initialize()
If Sheets("Page de garde").Visible = True Then
checkbox1.Value = True
Else
checkbox1.Value = False
End If
End Sub
Bonjour pipout64 et Seb77,
pour cette exemple j'ai supposé que les feuilles "menu" et "Feuil1" devait restées toujours visible, tous les autre peuvent être masquées ou vivible
Private Sub CommandButton1_Click()
' listeFixe = "menu" "Feuil1"
For i = 0 To Me.ListBox1.ListCount - 1
If Me.ListBox1.Selected(i) Then
t = Me.ListBox1.List(i)
Select Case t
Case "menu", "Feuil1" ' listeFixe
Case Else
With ThisWorkbook.Worksheets(t)
If .Visible Then
.Visible = False
Else
.Visible = True
End If
End With
End Select
End If
Next
End Sub
Private Sub UserForm_Initialize()
Dim liste()
For Each sh In Worksheets
ReDim Preserve liste(n)
liste(n) = sh.Name
n = n + 1
Next sh
With Me.ListBox1
.Clear
.ColumnCount = 1
.BoundColumn = 1
.ColumnWidths = "40"
.ListStyle = fmListStyleOption
.MultiSelect = fmMultiSelectMulti
End With
Me.ListBox1.List() = liste
End Sub
autre possibilité ne montrer que les feuilles du classeur qui peuvent être affichées ou masquées
Private Sub CommandButton1_Click()
For i = 0 To Me.ListBox1.ListCount - 1
If Me.ListBox1.Selected(i) Then
t = Me.ListBox1.List(i)
With ThisWorkbook.Worksheets(t)
If .Visible Then
.Visible = False
Else
.Visible = True
End If
End With
End If
Next
End Sub
Private Sub UserForm_Initialize()
Dim liste(), sh
For Each sh In ThisWorkbook.Worksheets
Select Case sh.Name
Case "menu", "Feuil1" ' sheets fixes
Case Else
ReDim Preserve liste(n)
liste(n) = sh.Name
n = n + 1
End Select
Next sh
With Me.ListBox1
.Clear
.ColumnCount = 1
.BoundColumn = 1
.ColumnWidths = "40"
.ListStyle = fmListStyleOption
.MultiSelect = fmMultiSelectMulti
End With
Me.ListBox1.List() = liste
End Sub
Bonjour Seb et SabV.
Merci d'avoir pris le temps de répondre.
Je me suis levé ce matin avec un "Eureka" qui traduisait ce que dit Seb: le contrôle des feuilles masquées ou présentes et la mise à jour de la checkbox correspondante.
On s'est rejoints mais avec une nuit de retard.
@Seb: pour ton premier bout de code, je ne vois pas la différence avec ce que j'ai écrit.
Pour le deuxième, c'est à ça que j'ai pensé en me levant, mais je voudrais le faire dynamiquement car j'ai une macro principale qui crée des sheets: je ne peux donc pas écrire "en dur" (même s'il y a effectivement (5-6 feuilles qui restent immuables).
Mais alors pour le traduire en code avec une boucle !
Quelle galère !
Je m'étais dit que j'allais compter le nb de sheets dans le classeur et boucler dessus avec une variable i et utiliser cette même variable pour le nom des checkbox.
Déjà, rien que la concaténation du nom de la checkbox et de la varaible i.... c'est mort (mais j'ai quand même trouvé un truc).
Ensuite, il faut récupérer, non pas le name de la sheet, mais le codeName de la sheet, ou son numéro d'item.
Il faut s'assurer que sheet (item & i) corresponde bien checkbox & i.
Ensuite, si je crée une nouvelle sheet, vais-je être sûr que le nouveau codename ou le nouveau numéro d'item de la feuille sera bien le suivant de celui qui existe déjà et la checkbox aussi !
@SabV: sympa le bout de code que tu as bien voulu m'écrire !
Je les ai essayés mais pas encore "digérés"...
Le premier présente un bug: en effet, si tu masques une des feuilles variables dynamiquement puis que tu les coches toutes, la feuille masquée toute seule n'apparaît pas ou ne se cache pas comme les autres.
Le deuxième est dans l'esprit de ce que je souhaite faire (je voulais rendre les checkbox de certaines feulles fixes disabled).
Ton code présente aussi un défaut similaire d'affichage, mais l'esprit est là et surtout je suis extrêmement sensible au temps passé pour un parfait inconnu tel que moi.
Dans tous les cas, je souhaite passer par les checkbox pour ne pas avoir à valider.
Je vais donc creuser, mais ça me paraît hard (surtout la correspondance des numéros d'items de sheets ou le numéro du codename en relation avec le numéro des checkbox en utilisant une variable commune i)...
Merci encore pour votre implication !
Bonne matinée.
- Messages
- 4'100
- Excel
- 2021 FR 64 bits
- Inscrit
- 13/06/2016
- Emploi
- bénévole associations Goutte d'Or
Bonjour,
ci-jointe proposition peut-être un peu sophistiquée mais adaptable au nombre de feuilles du classeur.
Bonjour Thev.
Merci beaucoup pour le code que tu as bien voulu écrire.
Je m'excuse de ne pas m'être manifesté plus tôt, je suis à fond dans ma macro et cette fonctionnalité de masquage de feuilles est un peu "the cherry on the cake", mais j'ai des soucis quant à la procédure principale.
Je viens de télécharger le fichier et l'ai testé.
C'est d'la balle !
Mais c'est un chaud pour moi.
Y a du code partout !
Déjà que je débute dans les userforms, mais alors les modules de classe...
ils sert à quoi ce module de classe que tu as déclaré ?
Les objets me font... peur (sauf ceux déjà créés par excel).
Un coup tu utilises du private, un coup du Public.
Le ByVal... je ne l'utilises que parce que j'ai une erreur de passage d'arguments, alors je mets byRef ou Byval et je vois si ça me supprime l'erreur...
Bref, je suis encore à des années lumière !
Merci encore Thev.
Je vais essayer de l'adapter, mais le coup du module de classe.
Je suis obligé de passer par ça ?
- Messages
- 4'100
- Excel
- 2021 FR 64 bits
- Inscrit
- 13/06/2016
- Emploi
- bénévole associations Goutte d'Or
Bonsoir pipout64,,
Le module de classe permet de gérer l'événement "Clic" de n'importe quelle checkbox se trouvant dans le Userform. Le problème est que les "checkbox" n'existent pas au départ et qu'elles sont créées dynamiquement selon le nombre de feuilles existantes. Dans ce cas, seul un module de classe permet de gérer l'événement "Clic" .pipout64 a écrit :Je vais essayer de l'adapter, mais le coup du module de classe.Je suis obligé de passer par ça ?
Le fonctionnement est le suivant :
A chaque checkbox créée dynamiquement, on crée un élément (on dit une instance) de la classe de ce module et on stocke sa référence dans une collection que j'ai nommée : "cases". Dans l'instance de classe créée, 2 variables objet sont stockées :
1- la variable USF correspondant à l'objet Userform = UserForm1
2- la variable case_n correspondant à l'objet CheckBox
Le fait de déclarer Public dans le code de UserForm1, les 2 variables objet : cases et case_i permet de faire fonctionner dans le module de classe l'instruction ci-dessous, sinon ces 2 variables ne pourraient pas être reconnues comme propriétés de Userform1 dans un autre module que celui associé à UserForm1pipout64 a écrit :Un coup tu utilises du private, un coup du Public.
'activation évenements de la classe dans le formulaire
Set USF.case_i = USF.cases(case_n.Name)