XL 2013 Sortir de Textbox

agourn

XLDnaute Junior
Bonjour à tous,
J'ai une appli VBA Excel avec Userform contenant 3 Textbox et un nombre élevé de boutons option regroupés dans plusieurs groupes dédiés. Chaque modification de Textbox ou d'état d'un bouton lance un programme complexe. Mon problème est le suivant : impossible de sortir proprement des Textbox, i.e. de façon à permettre à l'utilisateur de continuer de faire ses modifications des autres options.
J'utilise sub Textbox1_Exit sur les 3 box et j'essaie d'en sortir avec la tabulation.
Dans ce post : https://www.excel-downloads.com/thr...e-un-exit-cancel-true.20051292/#post-20379399
La solution a été de séparer la saisie pour la mettre dans autre Userform, ce que je voudrais éviter.
Merci
Agourn
 

Dudu2

XLDnaute Barbatruc
Bonjour,
Est-ce que tu peux préciser ?
Mon problème est le suivant : impossible de sortir proprement des Textbox, i.e. de façon à permettre à l'utilisateur de continuer de faire ses modifications des autres options.
Est-ce que les TextBoxes sont dans des Frames ?
Est-ce que le UserForm est Modal ?

J'ai eu à batailler avec les Control_Exit(). Je ne sais pas si les tiens sont du même acabit.
Par exemple si une erreur est détectée dans un Control TextBox_Exit() et qu'on souhaite laisser l'erreur présente dans la TextBox pour que l'utilisateur puisse la voir et la corriger, on ne peut plus forcer la sortie par un bouton quelconque car le TextBox_Exit() sera toujours prioritaire sur tout autre évènement. Par conséquent on va boucler sur le traitement de l'erreur sans jamais pouvoir en sortir, même si un bouton (Annuler par exemple) a prévu de la faire.
J'ai mis en place un parade basée sur un traitement asynchrone de l'erreur laissant la possibilité aux autres évènements de "s'exprimer".
 
Dernière édition:

agourn

XLDnaute Junior
Bonjour,
Est-ce que tu peux préciser ?

Est-ce que les TextBoxes sont dans des Frames ?
Est-ce que le UserForm est Modal ?

J'ai eu à batailler avec les Control_Exit(). Je ne sais pas si les tiens sont du même acabit.
Par exemple si une erreur est détectée dans un Control TextBox_Exit() et qu'on souhaite laisser l'erreur présente dans la TextBox pour que l'utilisateur puisse la voir et la corriger, on ne peut plus forcer la sortie par un bouton quelconque car le TextBox_Exit() sera toujours prioritaire sur tout autre évènement. Par conséquent on va boucler sur le traitement de l'erreur sans jamais pouvoir en sortir, même si un bouton (Annuler par exemple) a prévu de la faire.
J'ai mis en place un parade basée sur un traitement asynchrone de l'erreur laissant la possibilité aux autres évènements de "s'exprimer".
Bonsoir Dudu2,
Un seul Textbox est dans un frame.
Le Userform est modal.
Merci
 

Dudu2

XLDnaute Barbatruc
Ok mais alors quel est ton problème ? Sortir proprement des TextBoxes ça veut dire quoi ?

Pour info je m'étais noté:
Une TextBox placée dans un Frame peut être quittée par clic dans une autre TextBox à l'extérieur du Frame sans qu'on passe dans la fonction Exit().
Sur une TextBox unique dans un UserForm (cas rare) ou pour la dernière TextBox d'un Frame (cas fréquent) on NE passe PAS dans l'Exit().
Toutefois, l'évènement n'est pas perdu pour autant et reste en attente. Par exemple, en re-cliquant dans une TextBox du Frame ou en quittant le UserForm, Excel active d'abord l'Exit() de la dernière TextBox bypassé auparavant.

Donc les Frames c'est un peu la merdouille car il y a une logique spécifique derrière.
Il vaut mieux les éviter. Sauf éventuellement pour grouper les boutons d'options.
 

Dranreb

XLDnaute Barbatruc
Bonjour.
Je me pose aussi la question. Seul la mise à True de l'argument Cancel empêche de sortir.
VB:
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
   Cancel = MsgBox("Erreur à corrigez", vbOKCancel, Me.Caption) = vbOK
   End Sub
 

agourn

XLDnaute Junior
Ok mais alors quel est ton problème ? Sortir proprement des TextBoxes ça veut dire quoi ?

Pour info je m'étais noté:
Une TextBox placée dans un Frame peut être quittée par clic dans une autre TextBox à l'extérieur du Frame sans qu'on passe dans la fonction Exit().
Sur une TextBox unique dans un UserForm (cas rare) ou pour la dernière TextBox d'un Frame (cas fréquent) on NE passe PAS dans l'Exit().
Toutefois, l'évènement n'est pas perdu pour autant et reste en attente. Par exemple, en re-cliquant dans une TextBox du Frame ou en quittant le UserForm, Excel active d'abord l'Exit() de la dernière TextBox bypassé auparavant.

Donc les Frames c'est un peu la merdouille car il y a une logique spécifique derrière.
Il vaut mieux les éviter. Sauf éventuellement pour grouper les boutons d'options.
Au fait, il faut cliquer plusieurs fois sur les autres contrôles, ici les boutons option, pour que le clic soit pris en compte. Et quand le Userform est terminé, il exécute les instructions définies dans un Textbox_Exit, celui du frame justement.
D'ailleurs je comprends maintenant que le frame est problématique. Je vais tester sans.
 

Dranreb

XLDnaute Barbatruc
Ne pourriez vous joindre un classeur montrant votre problème ?
Remarque: d'habitude on met plutôt un traitement final sur un CommandButton. S'il a sa propriété Default à True, sa procédure _Click est même exécutée en utilisant la touche Entrée. Un autre CommandButton peut aussi avoir sa propriété Cancel à True pour que ça réagisse à la touche Echap.
 

agourn

XLDnaute Junior
Ne pourriez vous joindre un classeur montrant votre problème ?
Remarque: d'habitude on met plutôt un traitement final sur un CommandButton. S'il a sa propriété Default à True, sa procédure _Click est même exécutée en utilisant la touche Entrée. Un autre CommandButton peut aussi avoir sa propriété Cancel à True pour que ça réagisse à la touche Echap.
Au fait, c'est un énorme programme que je ne peux envoyer. En revanche, je vais créer un Userform qui reprend les contrôles en espérant reproduire le problème sur un cas simplifié.
Ça va un peu mieux en retirant le frame dans lequel se trouve un textbox. Mais j'ai toujours un comportement bizarre : en cliquant sur un bouton d'option, il exécute d'abord la routine d'un textbox comme si le programme vient de faire Exit de ce textbox.
 

Dranreb

XLDnaute Barbatruc
Oui c'est normal: la TextBox_Exit est exécutée si elle a le focus et qu'on clique sur un autre contrôle.
Sauf si c'est un CommandButton dont on a mis la propriété TakeFocusOnClick à False.
Vraiment, votre traitement ne devrait pas être dans une TextBox_Exit. Celle ci est réservée exclusivement à une vérification de la validité du contenu tapé.
 
Dernière édition:

agourn

XLDnaute Junior
Oui c'est normal: la TextBox_Exit est exécutée si elle a le focus et qu'on clique sur un autre contrôle.
Sauf si c'est un CommandButton dont on a mis la propriété TakeFocusOnClick à False.
Vraiment, votre traitement ne devrait pas être dans une TextBox_Exit. Celle ci est réservée exclusivement à une vérification de la validité du contenu tapé.
Merci Dranreb. Je fais le Userform demain matin et je le poste.
 

agourn

XLDnaute Junior
Bonsoir Dranreb & Dudu2,
j'ai créé ce fichier très simplifié de ma configuration réelle mais malheureusement je n'arrive pas à reproduire les problèmes. CJ néanmoins pour voir les Controls dans le Userform.
la suppression du frame des Textbox règle une partie des problèmes mais pas tout.
En effet dans mon appli, il y a très souvent un "retard " dans la validation : quand je clique sur un control option-button, c'est le programme d'une des 3 Textbox qui s'exécute quand bien même j'ai déjà cliqué ne fois pour sortir de Textbox_Exit. Et quand je termine le userform, exécution de ce même programme...
merci
agourn
 

Pièces jointes

  • test1_textbox_exit.xlsm
    18 KB · Affichages: 20

Dudu2

XLDnaute Barbatruc
Bonsoir @agourn,
Dans ce classeur je ne vois pas de problème particulier parce que toutes tes TextBoxes sont hors Frame.

La description de tes problèmes correspond assez bien au commentaire que j'ai mis dans le post #4.
Mais il n'y a aucune solution à ce phénomène puisqu'on est totalement dépendant de la gestion qu'Excel fait des évènements.
Donc il faut retirer toutes les TextBoxes des Frames pour utiliser _Exit().
Et si le phénomène de retard sur l'_Exit() persiste c'est qu'il reste des TextBoxes en Frame.

Il y a aussi la situation, normale cette fois, où, Frame ou pas Frame, on passe dans l'_Exit() après que la fermeture du UserForm a été provoquée, quelque soit la raison (CloseMode) et là ça part en live à l'utilisation des objects du UserForm si en premier dans l'_Exit() il n'y a pas un test du genre If Not Me.Visible Then Exit Sub.

Pour les contrôles des valeurs saisies, tu n'es pas obligé de le faire dès la sortie des zones sur l'_Exit().
Tu peux ajouter un bouton <Valider> qui déclenchera le contrôles de toutes les valeurs et repositionnera la Focus sur la 1ère zone détectée en erreur. Ça va aussi alléger ton code.
Et si une valeur dépend d'une autre, il vaut mieux la traiter sur l'_Enter() de la 1ère que sur l'_Exit() de la 2ème.
 
Dernière édition:

agourn

XLDnaute Junior
OK @Dudu2. Si je comprends bien, autant abandonner les Textbox_Exit (y compris pour tester si valeurs numériques par exemples) et créer un bouton de validation pour valider les 3 dimensions de mon Userform.
Par contre, les autres Controls : boutons option peuvent garder leurs évènements _Click ou _Change sans problème, je pense. N'est-ce pas ?
merci
agourn
 

Dudu2

XLDnaute Barbatruc
J'utilise parfois les fonctions _Exit() mais en connaissance de cause (et maintenant toi aussi tu sais ce qu'il en est).
Si tes TextBoxes sont garanties hors Frames ça doit fonctionner. Il faut juste gérer la fermeture du UserForm avec l'instruction If Not Me.Visible Then Exit Sub à placer en tête de toutes les fonctions _Exit().

L'option du bouton <Valider> est aussi possible, c'est une approche différente mais parfaitement légitime. Cette option est plus souple pour l'utilisateur qui n'a pas le désagrément signalé en post #2. Sans compter le problème mentionné en post #6 avec un UserForm NON Modal.

Pour les Boutons d'Options, on n'a guère le choix à partir du moment où il y en a des groupes indépendants. Il faut obligatoirement des Frames qui, à ma connaissance, ne posent pas de problème sur la gestion des évènements _Click() ou _Change().

Edit: Non, pour les boutons d'options il ne faut pas obligatoirement des Frames !
Dans ce post, @eriiiic mentionne l'utilisation de la propriété GroupName des boutons d'options qui permet de les grouper sans utiliser de Frame.
 
Dernière édition:

Statistiques des forums

Discussions
312 177
Messages
2 085 972
Membres
103 073
dernier inscrit
MSCHOE16