Au moins une checkbox cochée dans le userForm

Bonjour à tous,

Ça fait quelques années que je fais du VBA, assez ponctuellement, et j'utilise donc des fonctions assez basiques.

En guise de boucles, j'utilise à 95 % des boucles FOR NEXT car faciles à comprendre et à utiliser.
J'essaie parfois d'utiliser les boucles DO WHILE mais j'ai beaucoup de mal.

Pourtant, quand je traduis et que je lis ma boucle codée VBA en bon "français", tout semble correct mais ça plante (boucle infinie ou comportement non souhaité).

Contexte:
J'ai créé un userForm dans lequel se trouve des cases à cocher et un bouton de validation:

capture 1058

je veux m'assurer qu'au moins une case est cochée sans quoi l'utilisateur ne peux pas permettre à la procédure de continuer.
Ou alors il clique sur la croix et la macro prend fin.

Et bien pour un truc aussi "simple", je me casse les dents depuis des heures.
J'ai cherché sur le net et en français et en anglais mais je ne trouve pas vraiment (vba excel userform exit only if at least one checkbox is ticked etc...).

Mon code originel était le suivant:

Private Sub CmdButton_ChoixValid_Click()

'Dim TableauIPPN() As String 'Déclarée en public dans le module 5
Dim NbIPPNticked As Byte
Dim x As Integer
Dim Ctrl As control

NbIPPNticked = 0
For Each Ctrl In Me.Controls 'Boucle sur tous les contrôles du USF
    If TypeName(Ctrl) = "CheckBox" Then 'Test si le contrôle en cours est une checkBox
        If Ctrl.Value = True Then 'Teste si la checkBox en cours est cochée
            NbIPPNticked = NbIPPNticked + 1
        End If
    End If
Next Ctrl

'Remplissage du tableau
..........................
Unload Me

End Sub

J'ai donc voulu ajouté une boucle pour empêcher que le traitement ne se poursuive si aucune checkbox n'était cochée.
J'ai tenté d'utiliser les différentes boucles Do While, Do Until, Loop While mais rien à faire.
Soit j'obtiens une boucle infinie, soit pour une raison que je ne comprends pas, le traitement se poursuit et le remplissage du tableau se fait alors que NbIPPNticked est toujours égal à zéro.

Ce qui m'intéresse, outre que je puisse mettre en place ce garde-fou ici, c'est de comprendre une bonne fois pour toutes ces bon sang de boucle.
Encore une fois, dit en français, c'es boucles semblent...évidentes dans leur construction mais dans les faits: Oualou !

Do 'Faire le traitement ci-dessous tant que NbIPPNticked = 0 ---> Boucle infinie !!
For Each Ctrl In Me.Controls 'Boucle sur tous les contrôles du USF
    If TypeName(Ctrl) = "CheckBox" Then 'Test si le contrôle en cours est une checkBox
        If Ctrl.Value = True Then 'Teste si la checkBox en cours est cochée
            NbIPPNticked = NbIPPNticked + 1
        End If
    End If
Next Ctrl
MsgBox "Au moins une case à cochée doit être cochée !" & vbCrLf & "Cliquez sur la croix si vous voulez sortir."
DoEvents 'Permet de cocher d'intéragir avec le UserForm mais ne prend qu'une seule case à cocher en compte
Loop While NbIPPNticked = 0
NbIPPNticked = 0
Do Until NbIPPNticked <> 0 'Faire traitement ci-dessous jusqu'à NbIPPNticked <> 0 --> aboutit au remplissage du tableau même si NbIPPNticked = 0 !
For Each Ctrl In Me.Controls 'Boucle sur tous les contrôles du USF
    If TypeName(Ctrl) = "CheckBox" Then 'Test si le contrôle en cours est une checkBox
        If Ctrl.Value = True Then 'Teste si la checkBox en cours est cochée
            NbIPPNticked = NbIPPNticked + 1
        End If
    End If
Next Ctrl
MsgBox "Au moins une case à cochée doit être cochée !" & vbCrLf & "Cliquez sur la croix si vous voulez sortir."
Loop 

Bref, qu'est-ce qui cloche chez moi nom de nom !
Le truc basique par excellence et je suis incapable de comprendre, de débrouiller ce problème.

Évidemment, j'ai essayé des tas d'autres trucs, en déplaçant la boucle dans le If de sélection des cases à cocher, mis en place des compteurs...
Je pourrais utiliser un goto mais je m'y refuse.

Bref, merci pour votre indulgence et si vous êtes hyper pédagogue (je suis allé voir quelques tutos, bien entendu) merci de m'expliquer pourquoi je suis nul à ièch comme ça.

Merci d'avance pour votre aide et votre... indulgence.

Bonjour pipout64

Private Sub CmdButton_ChoixValid_Click()
'Dim TableauIPPN() As String 'Déclarée en public dans le module 5
Dim NbIPPNticked As Byte
Dim x As Integer
Dim Ctrl As control

NbIPPNticked = 0
For Each Ctrl In Me.Controls 'Boucle sur tous les contrôles du USF
    If TypeName(Ctrl) = "CheckBox" Then 'Test si le contrôle en cours est une checkBox
        If Ctrl.Value = True Then 'Teste si la checkBox en cours est cochée
            NbIPPNticked = NbIPPNticked + 1
        End If
    End If
Next Ctrl
' Si rien n'est coché, on sort
If NbIPPNticked = 0 Then Exit Sub
' Sinon
'Remplissage du tableau
..........................
Unload Me

End Sub

A+

Bonjour,

Si je peux proposer, en supposant que votre userForm n'accepte qu'une des conditions dans la liste, alors un OptionButton (icone ronde) serait plus adapté qu'une CheckBox.

Autrement vous pourriez définir un choix par défaut afin d'avoir toujours au moins une case pré-cochée. Il suffit de l'affecter sur True lors l'initialisation.

Pour vos boucles elles semblent correctes. Vous comptez le nombre de boxes cochées dans NbIPPNticked. Ok.

C'est après que vous devez faire un second test, que je ne vois pas dans votre code tel que:

Si le nombre de cases cochées = 0, alors ne pas fermer le userform...

Par exemple ce pourrait etre :

If NbIPPNticked < 1 Then MsgBox "aucune case cochée"

à ajouter sous votre boucle, comme ceci :

Private Sub CmdButton_ChoixValid_Click()

'Dim TableauIPPN() As String 'Déclarée en public dans le module 5
Dim NbIPPNticked As Byte
Dim x As Integer
Dim Ctrl As control

NbIPPNticked = 0
For Each Ctrl In Me.Controls 'Boucle sur tous les contrôles du USF
    If TypeName(Ctrl) = "CheckBox" Then 'Test si le contrôle en cours est une checkBox
        If Ctrl.Value = True Then 'Teste si la checkBox en cours est cochée
            NbIPPNticked = NbIPPNticked + 1
        End If
    End If
Next Ctrl

If NbIPPNticked < 1 Then MsgBox "aucune case cochée"

'Remplissage du tableau
..........................
Unload Me

End Sub

Bonjour JExceL2fr et saboh12617,

Merci d'avoir pris le temps de répondre.

Je n'ai pas été assez précis.
La condition que vous évoquez, je l'avais bien en tête mais le but est que le userform reste toujours affiché tant qu'aucune checkbox n'est cochée (ou clic sur la croix).
D'où mon souhait d'utiliser une boucle While.

C'est exactement la même chose que de boucler sur une inputBox qui restera affichée tant que l'utilisateur clique sur Ok sans avoir rempli le champ (ou décide de quitter en cliquant sur la croix).

Pour mon userForm, si je fais le test que NbIPPNticked < 1, je suis obligé de réafficher le userForm mais je serais obligé de remettre une condition après et ainsi de suite tant que l'utilisateur décide de valider sans cocher une seule checkbox...

Re,

Vous êtes dans un USF, votre procédure est dans un bouton "Private Sub CmdButton_ChoixValid_Click()"
Si vous testez avec ce que je vous ai donné, vous sortez de la Sub mais vous restez dans votre USF tant que vous n'avez pas fait Unload

Mais oui JExceL2fr !!!

C'est parfaitement juste !
Je n'avais pas capté ça !
J'ai vraiment manqué de hauteur nul à ièch que je suis !

Merci pour la soluce !
Le pire, c'est que j'étais tombé sur la même soluce sur le site stackoverflow mais j'ai réagi de la même manière que celle avec laquelle je vous ai répondu...

C'est résolu.

Merci encore JExceL2fr et saboh12617, vous aviez vu juste tous les 2.
Bonne continuation.

Rechercher des sujets similaires à "checkbox cochee userform"