Ejecter une procédure évènementielle
Bonjour à tous,
Presque 10 ans, jour-pour-jour par rapport à l'ouverture de cette discussion (non encore fermée !) que je viens de découvrir, je voudrais vous soumettre une solution au problème posé que j'ai souvent appliquée depuis 3 ans, qui fonctionne très bien et qui me semble bien plus simple que toutes celles proposées.
Je suis un nouveau membre et encore loin de maitriser VBA comme la plupart d'entre vous. Si vous pouviez me faire savoir si ma solution tient la route, cela me ferait le plus grand plaisir !
Je résume le problème : éviter que l'action sur un contrôle d'un UserForm ne déclenche en cascade d'autres procédures évènementielles que celle qui lui est associée (lorsque ce contrôle modifie, même indirectement, les propriétés d'autres contrôles associés à des procédures du type "_Change").
Pour éviter cela, je défini une seule variable "Public" du type "Boolean" que je nomme "CE".
Voici, en quelques lignes, la structure de mes procédures:
Sub (NomProcédure)
If Ce = False then Ce = True else Exit Sub
... instructions
Ce = False
End Sub
Merci de vos réponses que j'attends avec impatience...
Bloquer une procédure évènementielle
Réponse à Ben_L
Désolé, mais je n’ai pas retenu la solution #3 car elle me semblait plus compliquée que la mienne.
Je la reprend ci-dessus, mais je remplace «MonObjet_ProcessusEnCours» par mon «Ce» qui me paraît plus simple à lire…
Je défini une variable globale dans la section Déclarations d’un module de code (Pas de l’UserForm car les procédures du code n’y ont pas accès)
Public Ce as Boolean
Avant d'affecter une nouvelle valeur au contrôle je mets dans la procédure appelante (PA) avant l’instruction qui va modifier le contrôle :
Ce = True
Ensuite, dans :
Private Sub MonObjet_Change()
If Ce = True Then Ce = False: Exit Sub (en une ligne, cela me semble plus clair)
...
End Sub
D’accord ça marche, mais on risque d’oublier le «Ce = True» lorsque l’on écrit le code dans la PA.
De plus chaque instruction (dans une ou plusieurs PA !) destinée à modifier l’une des propriétés de chaque contrôle devra être précédée de «Ce = True»
A cela, Il y a bien la solution consistant à placer «Ce = False» dans la PA avant son «End Sub» … et ne pas l’oublier.
Mais je reviens sur ma solution.
Je ne vois pas ce qui empêche d'activer ma variable "Ce" dans une procédure évènementielle (PE).
Car si mon code veut modifier un contrôle, c’est suite à une action sur un autre contrôle.
Si toutes mes PE associées à une contrôle commencent par la simple instruction …
If Ce = False Then Ce = True Else Exit Sub
… et se terminent par …
Ce = False
… je suis sûr que la première qui sera déclenchée bloquera toutes les suivantes.
Et cela en employant seulement 2 lignes d’instruction dans les seules PE qui risquent de créer l’effet «domino» que je veux éviter et sans encombrer les autres procédures, bien plus complexes, de mon code.
Ma solution permet aussi à 2 contrôles d’interférer l’un sur l’autre, par exemple :
> Sélection d’un modèle de voiture proposé en colonne 1 d’une ListBoxA
ListBoxA_Change propose dans une ListBoxB les couleurs disponibles pour ce modèle (ListBoxB_Change est bloqué par Ce = True)
> Sélection de la couleur dans la ListBoxB
ListBoxB_Change inscrit la couleur choisie dans la colonne 2 de la ListBoxA (ListBoxA_Change est bloqué par Ce = True)
Merci encore de m’avoir répondu si vite. Votre réponse m’a permis d’approfondir un problème essentiel pour mes développements mais je reste toujours ouvert à vos remarques et suggestions.
Je tiendrais compte de votre première remarque. Le problème est le site de «développez.net» est assez complexe et je ne sais pas si je saurais créer un lien avec une précédente discussion.