IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

1 seule VBA Excel pour plusieurs CheckBox [XL-2016]


Sujet :

Macros et VBA Excel

  1. #1
    Candidat au Club
    Femme Profil pro
    Ingénieur contrôle qualité analytique
    Inscrit en
    Janvier 2025
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur contrôle qualité analytique

    Informations forums :
    Inscription : Janvier 2025
    Messages : 3
    Par défaut 1 seule VBA Excel pour plusieurs CheckBox
    Bonjour,

    Je fais un peu de VBA, et je trouves toujours ce que je veux faire grâce aux forums. Mais pas aujourd'hui, j'espère trouver de l'aide par ce tout premier post :

    Sur ma feuille excel, j'ai 4 CheckBox, qui correspondent chacun à un "Kit" → CheckBox1 = Kit1, CheckBox2 = Kit2, etc...
    J'aimerais que si je coche "Kit1", il me fasse apparaitre des lignes en lien avec le Kit1, et que si je le décoche, que ça le fasse disparaitre.
    Pour ça, c'est bon, j'ai le code suivant :
    Private Sub CheckButton1_Click()


    Application.ScreenUpdating = False 'Pour accélérer la procédure


    Dim Kit1 As Range 'CheckButton1 = J'ai renommé les CheckBox par "CheckButton"
    Dim Kit2 As Range 'CheckButton2
    Dim Kit3 As Range 'CheckButton3
    Dim Kit4 As Range 'CheckButton4


    Set Kit1 = Rows("11:19") 'je définis les lignes associées au kit
    Set Kit2 = Rows("20:28")
    Set Kit3 = Rows("29:36")
    Set Kit4 = Rows("38:43")


    If CheckButton1 Then
    Kit1.Hidden = False
    Else
    Kit1.Hidden = True
    End If

    If CheckButton2 Then
    Kit2.Hidden = False
    Else
    Kit2.Hidden = True
    End If

    'Faut répéter le même petit code pout Kit3 et Kit4

    Application.ScreenUpdating = True

    End Sub

    J'ai 2 problèmes :
    - Ce type de code (le Private Sub CheckButton1 () ) ne fonctionne que pour le CheckBox1. Si je coche après CheckBox2, il ne se passe rien...
    - J'aimerais créer une boucle pour anticiper l'arrivée de nouveau kit, j'avais pensé au code ci-dessous, mais il ne fonctionne pas...

    Private Sub CheckButton_Click()


    Application.ScreenUpdating = False 'Pour accélérer la procédure


    Dim i As Integer
    Dim Kit1 As Range 'CheckButton1 = J'ai renommé les CheckBox par "CheckButton"
    Dim Kit2 As Range 'CheckButton2
    Dim Kit3 As Range 'CheckButton3
    Dim Kit4 As Range 'CheckButton4


    Set Kit1 = Rows("11:19") 'je définis les lignes associées au kit
    Set Kit2 = Rows("20:28")
    Set Kit3 = Rows("29:36")
    Set Kit4 = Rows("38:43")




    For i = 1 To 4
    If Controls("CheckButton" & i) Then 'si coché
    "Kit" & i.Hidden = False 'le tableau apparait
    Else
    "Kit" & i.Hidden = True 'le tableau disparait
    End If
    Next


    Application.ScreenUpdating = True

    End Sub

    J'avais trouvé cette boucle dans la partie "LES CASES A COCHER (CHECKBOX)" du site : https://excel-pratique.com/fr/vba/controles
    Mais ça ne marche pas car :
    - Il considère le "Private Sub CheckButton_Click ()" comme "(Générale)"
    - Et il n'apprécie pas les deux lignes : Kit & i.Hidden → si je met des parenthèses, des guillemets, les deux ou aucun, il me dit "Erreur de compilation"

    J'aimerai que mon code vba :
    - fonctionne pour toutes mes CheckBox,
    - faire fonctionner ma boucle

    Pouvez-vous m'aider ?

    Pour rappel :
    Les CheckBox ne sont pas dans un UserForm, ils sont directement dans des cellules de ma feuille Excel

    Merci d'avance

  2. #2
    Rédacteur
    Avatar de Philippe Tulliez
    Homme Profil pro
    Formateur, développeur et consultant Excel, Access, Word et VBA
    Inscrit en
    Janvier 2010
    Messages
    13 107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur, développeur et consultant Excel, Access, Word et VBA

    Informations forums :
    Inscription : Janvier 2010
    Messages : 13 107
    Billets dans le blog
    53
    Par défaut
    Bonjour,
    Pour pouvoir intercepter l'événement click de n'importe quel CheckBox présent dans une feuille, il faut passer par un module de classe.
    Il y a lieu d'invoquer la procédure InitializeCheckBox depuis un événement (CommandButton ou Workbook.Open ou encore Worksheet.Activate

    Code de la procédure à placer dans un module de classe nommé clsCheckBoxEvents
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Option Explicit
    Public WithEvents chk As MSForms.CheckBox
    ' Capture l'événement Click de chaque CheckBox
    Private Sub chk_Click()
     ' Appelle la procédure en lui passant le CheckBox qui a déclenché l'événement
     CheckBoxClicHandler chk
    End Sub
    Procédures à placer dans un ou deux modules Standard
    La première procédure est celle qui est appelée depuis le module de classe et la deuxième procédure est l'initialisation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ' Procédure appelée lors d'un clic sur un CheckBox
    Sub CheckBoxClicHandler(chk As MSForms.CheckBox)
      MsgBox "CheckBox cliqué : " & chk.Name, vbInformation, "Événement Intercepté"
    End Sub
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    Sub InitializeCheckBox()
      Dim sht As Worksheet
      Dim shp As Shape
      Dim objCheck As clsCheckBoxEvents
      ' Initialise la collection
      Set colCheckBox = New Collection
      Set sht = ActiveSheet ' A modifier si nécessaire
      ' Parcoure toutes les formes de la feuille
      For Each shp In sht.Shapes
        ' Vérifier si la forme est un CheckBox
        If shp.Type = msoOLEControlObject Then
          If TypeOf shp.OLEFormat.Object.Object Is MSForms.CheckBox Then
            ' Crée une nouvelle instance du module de classe
            Set objCheck = New clsCheckBoxEvents
            ' Associe le CheckBox à l'objet de classe
            Set objCheck.chk = shp.OLEFormat.Object.Object
            ' Ajoute l'objet à la collection pour éviter sa destruction
            colCheckBox.Add objCheck
          End If
        End If
      Next
      Set sht = Nothing: Set shp = Nothing: Set objCheck = Nothing
    End Sub

    Explications :
    • Module de classe (clsCheckBoxEvents) : Intercepte l'événement Click de chaque CheckBox.
    • Module standard :
      InitialiserCheckBox : Ajoute tous les CheckBox dans une collection pour éviter la perte de référence.
      CheckBoxClicHandler : Reçoit le CheckBox cliqué en paramètre.


    Attention : Ligne 7 de la procédure InitializeCheckBox j'assigne l'objet ActiveSheet à la variable objet sht parce-que j'ai invoqué la procédure depuis la procédure événementielle Worksheet_Activate. Il y a donc lieu d'effectuer la modification si la procédure est invoquée depuis l'ouverture du classeur (sauf si l'on active la bonne feuille à l'ouverture)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Private Sub Worksheet_Activate()
     mMain.InitializeCheckBox
    End Sub
    Philippe Tulliez
    Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément. (Nicolas Boileau)
    Lorsque vous avez la réponse à votre question, n'oubliez pas de cliquer sur et si celle-ci est pertinente pensez à voter
    Mes tutoriels : Utilisation de l'assistant « Insertion de fonction », Les filtres avancés ou élaborés dans Excel
    Mon dernier billet : Utilisation de la fonction Dir en VBA pour vérifier l'existence d'un fichier

  3. #3
    Candidat au Club
    Femme Profil pro
    Ingénieur contrôle qualité analytique
    Inscrit en
    Janvier 2025
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur contrôle qualité analytique

    Informations forums :
    Inscription : Janvier 2025
    Messages : 3
    Par défaut
    Bonjour,

    Je souhaitais tout d'abord vous remercier pour la rapidité de votre réponse.
    Malheureusement pour moi, je trouve cela bien compliqué, je ne suis pas sûre de bien comprendre les différents codes.

    Si je décompose les codes, je comprends que :
    Avec Option Explicit dans le module de classe, je déclare que chk sont des CheckBox. Puis avec Private Sub, je déclenche l'action vba quand on clique sur les CheckBox.
    Sur le module standards, le premier code m'ouvre un MsgBox quand on clique sur un CheckBox.
    Et comme vous avez dit pour le code
    InitializeCheckBox, cela ajoute tous les CheckBox dans une collection.

    J'ai copié/collé les codes tel quel :
    Dans un module de classe : clsCheckBoxEvents
    Dans un même module standards : CheckBoxClicHandler puis InitializeCheckBox
    Mais il ne se passe rien quand je clique sur mes CheckBox...
    De plus, je n'ai pas compris où je devais mettre la partie du code où je dis de faire apparaitre/disparaitre mes lignes. J'ai essayé :
    - Dans le Private Sub chk_Click(), avant et après CheckBoxClicHandler chk,
    - Dans Sub CheckBoxClicHandler(chk As MSForms.CheckBox), avant et après le MsgBox...

  4. #4
    Rédacteur
    Avatar de Philippe Tulliez
    Homme Profil pro
    Formateur, développeur et consultant Excel, Access, Word et VBA
    Inscrit en
    Janvier 2010
    Messages
    13 107
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur, développeur et consultant Excel, Access, Word et VBA

    Informations forums :
    Inscription : Janvier 2010
    Messages : 13 107
    Billets dans le blog
    53
    Par défaut
    Bonjour,
    Si je décompose les codes, je comprends que :
    Avec Option Explicit dans le module de classe, je déclare que chk sont des CheckBox.
    Absolument pas. L'instruction Option Explicit qui doit être placée avant toute procédure au niveau du module force la déclaration explicite de toutes les variables dans ce module.
    Pour éviter de devoir la taper à chaque fois que l'on insère un nouveau module, il y a lieu de cocher l'option "Déclaration obligatoire des variables" de l'onglet [Editeur] de la boite de dialogue "Options" (Outils/Options/ [Editeur])

    Sur le module standards, le premier code m'ouvre un MsgBox quand on clique sur un CheckBox.
    Et comme vous avez dit pour le code InitializeCheckBox, cela ajoute tous les CheckBox dans une collection.
    La procédure nommée CheckBoxClicHandler est une procédure événementielle qui se déclenche lorsque l'on clique sur n'importe quelle CheckBox. Pour l'exemple, j'ai utilisé la fonction MsgBox qui affiche le nom de l'objet sur lequel on a cliqué mais évidemment c'est là qu'il faut placer votre code qui affiche ou masque les lignes de la feuille.

    Exemple qui correspond à ce que vous cherchez
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Sub CheckBoxClicHandler(chk As MSForms.CheckBox)
      Dim t As Variant
      Dim n As Byte
      ' Liste des numéros de lignes à traiter
      t = Array("10:19", "20:29", "30:34", "35:39")
      With chk
        ' Extraction du n° du CheckBox
        n = Val(Right(.Name, 1))
        ' Affiche ou Masque les lignes
        Rows(t(n)).Hidden = Not .Value
      End With
    End Sub
    Mais il ne se passe rien quand je clique sur mes CheckBox...
    Il y a lieu d'abord, comme je l'ai écrit, de lancer la procédure InitializeCheckBox soit à l'ouverture du classeur, soit à l'aide d'un CommandButton soit encore lors de la sélection de la feuille qui contient les CommandButton

    Exemple à l'ouverture du classeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Private Sub Workbook_Open()
      sht_Home.Activate  ' Active la feuille des checkBox's
      InitializeCheckBox ' Initialise les CheckBox
    End Sub
    De plus, je n'ai pas compris où je devais mettre la partie du code où je dis de faire apparaitre/disparaitre mes lignes. J'ai essayé :
    - Dans le Private Sub chk_Click(), avant et après CheckBoxClicHandler chk,
    - Dans Sub CheckBoxClicHandler(chk As MSForms.CheckBox), avant et après le MsgBox...
    Voir mes explications précédentes. Il est évident que la ligne avec MsgBox doit disparaître

    Classeur joint
    Dans le classeur joint, j'ai ajouté la ligne objCheck.chk.Value = True pour que tous les CheckBox soit cochés
    L'initialisation se fait à l'ouverture du classeur
    Fichiers attachés Fichiers attachés
    Philippe Tulliez
    Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément. (Nicolas Boileau)
    Lorsque vous avez la réponse à votre question, n'oubliez pas de cliquer sur et si celle-ci est pertinente pensez à voter
    Mes tutoriels : Utilisation de l'assistant « Insertion de fonction », Les filtres avancés ou élaborés dans Excel
    Mon dernier billet : Utilisation de la fonction Dir en VBA pour vérifier l'existence d'un fichier

  5. #5
    Candidat au Club
    Femme Profil pro
    Ingénieur contrôle qualité analytique
    Inscrit en
    Janvier 2025
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur contrôle qualité analytique

    Informations forums :
    Inscription : Janvier 2025
    Messages : 3
    Par défaut
    Super ça marche !
    J'ai un peu mieux compris, merci beaucoup !

  6. #6
    Membre expérimenté
    Homme Profil pro
    libre
    Inscrit en
    Septembre 2024
    Messages
    126
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : libre

    Informations forums :
    Inscription : Septembre 2024
    Messages : 126
    Par défaut
    Cette méthode est un peu risquée, les checkbox peuvent se détacher le mode création est activé lors de l'ajout de nouveaux contrôles

  7. #7
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    1 454
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 1 454
    Par défaut
    Bonjour,

    @Philippe Tulliez:
    Si je puis me permettre, quitte à faire de l'objet, autant le faire jusqu'au bout:
    1) Les variables membre d'une classe n'ont pas vocation à être publique (principe d'encapsulation).
    2) Les fonctions prenant en charge les evennements générés par la case à cocher (checkbox) n'ont aucune raison d'être externalisées, et encore moins publique.

    VBA ne propose ne permet d'écrire qu'un seul constructeur par classe (évènement initialise), on peut cependant écrire un pseudo-constructeur, et prendre en charge tous le processus d'instanciation / initialisation de la classe via une fonction (ou classe) "Factory".
    Ce qui donne le code suivant:
    Module de classe MyCheckBox:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
        '// Classe: MyCheckbox
    Option Explicit
     
    Public WithEvents mCheckbox As MSForms.CheckBox
     
        '// Pseudo constructeur:
    Friend Sub Construct(ByRef checkBox As MsForms.CheckBox
        Set mCheckBox = checkBox
    End Sub
     
    ' Capture l'événement Click de chaque CheckBox
    Private Sub mCheckBox _Click()
     ' Appelle la procédure en lui passant le CheckBox qui a déclenché l'événement
     CheckBoxClicHandler mCheckBox 
    End Sub
     
    Private Sub CheckBoxClicHandler(ByRef checkBox As MsForms.CheckBox)
        '// Faire quelque chose
    End Sub
    Module Standard: Factory
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        '// Factory
    Option Explicit
     
    Public Function Create_MyCheckBox(ByRef checkBox As MsForms.Checkbox) As MyCheckBox
        Dim Chk As MyCheckBox
        Set Chk = New MyCheckBox    '// Instanciation de la classe
        Chk.Construct(checkBox)        '// Initialisation (appel du pseudo constructeur)
        Set Create_MyCheckBox = Chk
    End Function
    Utilisation dans le module du classeur (ou un module de feuille):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Option Explicit
     
    Private mMyCheckBoxs As Collection
     
    Private Sub Workbook_Open()
        InitialiseCheckBoxes
    End Sub
     
    Private Sub InitialiseCheckBoxes()
        Set mMyCheckBoxs = New Collection
     
        '// Code de recherche des checkboxes
            mMyCheckBoxs.Add(Factory.Create_MyCheckBox(objCheck)
        '// --------------------------------------
    End Sub
    Au final, un peut plus de réflexion en amont et un peut plus de code à écrire, Mais:
    Le code intéressant (celui du classeur) et plus court, plus clair, plus lisible, plus facile à comprendre.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [VBA-Excel] copier plusieurs fois une colonne dans une feuille Excel
    Par ash_rmy dans le forum Macros et VBA Excel
    Réponses: 14
    Dernier message: 09/08/2006, 19h43
  2. [VBA Excel] Une même macro pour plusieurs CheckBox
    Par Choupett' dans le forum Macros et VBA Excel
    Réponses: 11
    Dernier message: 16/06/2006, 14h54
  3. [VBA][Excel]Rendre un checkbox ou textbox grisée
    Par Ania dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 16/01/2006, 10h17
  4. [VBA Excel] Créer plusieurs contrôles dynamiquement
    Par loacast dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 08/12/2005, 18h27
  5. [excel vba]case à cocher dans excel pour plusieurs lignes
    Par fcoisb dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 02/03/2005, 12h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo