Valider une "textBox" par "enter"?
Bonsoir à tous
j'ai un userform composé d'un "textbox" et d'une "image" qui, cet dernière, me permet de valider par "clik" (je trouvais le bouton très laid
Mon problème est, que je n'ai pas de validation par la touche "enter"
J'ai (enfin je pense) trouvé des solutions sur le forum, mais avec la combinaison "textbox" et "commandbouton"!
Merci d'avance
édit: rajout du fichier (allégé)
Bonsoir,
C'est d'une clarté d'encre !
En attendant que tu précises ce que tu veux valider et comment se traduit cette validation,
et que tu te décides à montrer ton Userform,
voilà ce que tu peux faire :
1) Tu places un bouton (CommandButton) dans ton Userform, tu le dimensionnes à la taille qui te convient.
2) Dans la fenêtre Propriétés, tu cherches la propriété Picture du bouton, tu sélectionnes et tu cliques sur les 3 points (...) à droite...
3) Cela ouvres une fenêtre d'explorateur qui te permet d'aller chercher sur ton disque l'image que tu souhaites mettre sur le bouton.
4) Image trouvée, tu cliques sur Ouvrir pour valider ton choix : l'image apparaît sur le bouton.
5) Tu vas maintenant chercher la propriété Default du bouton : tu la passes à True.
Ce bouton devient le bouton par défaut de ton Userform, ce qui signifie qu'en appuyant sur la touche Entrée cela déclenchera la procédure associée au bouton.
Cordialement.
Bonsoir MFerrand
En effet, l'encre était un peu sombre ..
l'userform s'affiche en cliquant le bouton "Admin", car je voulais qu'il ne s'applique que par mot de passe.
voici son code:
Sub userform_unprotect()
Password = ""
UserForm1.TextBox1.Value = ""
UserForm1.Show
If Password = "test" Then
Call UnprotectAllSheets
Else
MsgBox ("! Pas de bras, pas de chocolats !") 'lol, ce n'est que pour le test!
End If
End Sub
En attendant que tu précises ce que tu veux valider..
Quand j'inscris le mdp dans le "TextBox" et veux le valider je suis obliger de cliqué sur l'image!
voilà le code de l'image
Private Sub Image1_Click()
Password = TextBox1.Value
Unload UserForm1
End Sub
pour ceci:
1) Tu places un bouton (CommandButton) dans ton Userform, tu le dimensionnes à la taille qui te convient.
2) Dans la fenêtre Propriétés, tu cherches la propriété Picture du bouton, tu sélectionnes et tu cliques sur les 3 points (...) à droite...
3) Cela ouvres une fenêtre d'explorateur qui te permet d'aller chercher sur ton disque l'image que tu souhaites mettre sur le bouton.
4) Image trouvée, tu cliques sur Ouvrir pour valider ton choix : l'image apparaît sur le bouton.
Je l'avais déjà fais, mais ça ne me plais pas du tout! ce n'est pas du tout le même rendu!
Au plaisir
Je viens de trouver une solution (peut-être temporaire), mais qui résous mon problème pour le moment.
Explication:
Je laisse mon image (click) et je met en arrière plan, plus petit que l'image, le "CommandButton" associé (tout deux) a la même macro.
Mais, si il y a des solutions plus adaptées, je suis preneur
Ça c'est ton choix... !
Si tu n'utilises pas de bouton, tu peux toujours utiliser l'évènement AfterUpdate de la TextBox... plus d'intermédiaire pour valider.
Je te conseillerais cependant d'apporter un peu plus de soin à ton code !
Cordialement.
Ça c'est ton choix... !
Bien disons, qu'entre les deux messages, c'était la solution, mais comme je l'ai dis je suis toujours preneur de solution plus propre.
"Pourquoi mettre les crasses en dessous du tapis alors qu'il suffis de les ramassées pour les mètres à la poubelle"
Si tu n'utilises pas de bouton, tu peux toujours utiliser l'évènement AfterUpdate de la TextBox
Je ne connaissais pas! eh bien je me documentes sur la fonction et je vais la mettre d'application.
Je te conseillerais cependant d'apporter un peu plus de soin à ton code !
Je considère que l'indentation n'est pas une option mais une obligation.
Oui, j'en suis conscient, mais je ne maitrise pas encore , et je ne vois pas trop les différences entre les différents paragraphe du code, de façon à les indentées convenablement
un code dont l'écriture part dans tous les sens, truffé de lignes inutiles...
Je m'en doute
Je vais essayé de voir ce que je peut nettoyer ou simplifié dans les macros que j'ai rajouté.
Merci pour les infos
Juste en complément, n'oublie pas qu'une variable non initialisée, si elle est String renverra la valeur "", si elle est numérique renverra la valeur 0. Inutile donc d'initialiser à ces valeurs...
Et d'autre part, je ne pense pas qu'une variable de niveau module pour recueillir un mot de passe soit une bonne idée, une variable de niveau module ne disparaissant pas à la fin d'une procédure, ce qui implique que pour le faire disparaître il faut réinitialiser la variable, et sûrement en plusieurs endroits... Rester au niveau procédure garantit qu'il ne soit pas conservé, et si plusieurs procédures sont utilisées dans l'opération, il peut être passé en argument d'une proc. à une autre.
Dans ton cas (si je me souviens bien de ce que j'ai vu), le mot de passe est tapé dans ton Userform. Il y a une procédure qui va le vérifier (il ne doit y en avoir qu'une) : c'est à elle de lancer le Userform, après Show le Userform prend le relais, lorsque le mot de passe est validé par l'utilisateur, tu peux te contenter de masquer le Userform avec Hide, la main revient à la proc appelante juste après Show donc : elle récupère la valeur de la TextBox (le mot de passe), opère la vérification et décharge (Uload) le Userform.
Tu peux même prévoir qu'en cas de mot de passe faux, elle puisse relancer le Userform une seconde fois pour une nouvelle tentative...
Cordialement.
Je te relis demain dans la matinée, car là je ne suis plus
j'ai essayer plusieurs choses avec AfterUpdate, mais ça ne donnais rien, enfin si, à ce que, sur un des tests, la macro tourne en rond, à ne plus savoir l’arrêter que par "Ctrl + Pause" et ensuite tuer "excel" par le gestionnaire et le relancer, sans toucher au bouton "admin"
pourtant l'userform fonctionne très bien, je cherchais juste à pouvoir faire "enter" pour valider, je pensais vraiment que la procédure serais plus simple
au cas où, je te souhaite un bon réveillon.
Bonjour tous mondes
Néttoyage commencé
module2:
avant:
Public Password As String
Sub userform_unprotect()
Password = ""
UserForm1.TextBox1.Value = ""
UserForm1.Show
If Password = "test" Then
Call UnprotectAllSheets
Else
MsgBox ("! Pas de bras, pas de chocolats !")
End If
End Sub
Sub UnprotectAllSheets()
Dim Sht As Worksheet
For Each Sht In ThisWorkbook.Worksheets
Sht.unprotect Password:="test"
Next
Sheets("RECHERCHE").Select
ActiveWindow.DisplayWorkbookTabs = True
End Sub
apres:
Sub userform_unprotect()
UserForm1.Show
If Password = "test" Then
Dim Sht As Worksheet
For Each Sht In ThisWorkbook.Worksheets
Sht.unprotect Password:="test"
Next
Sheets("RECHERCHE").Select
ActiveWindow.DisplayWorkbookTabs = True
Else
MsgBox ("! Pas de bras, pas de chocolats !")
End If
End Sub
Par contre je n'arrive pas régler "AfterUpdate"!
Je pense être sur la voie, car avec le code ci-dessous, il enregistre bien le mot de passe du "TextBox" mais ne valide toujours pas avec "enter" mais quand je ferme l'UserForm il exécute convenablement la macro du module2
Voici le code:
Private Sub TextBox1_AfterUpdate()
Password = TextBox1.Value
Unload UserForm1
End Sub
j'ai aussi essayé:
Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
If KeyCode = 13 Then
End If
UserForm1.Hide
End Sub
mais là, dès la première lettre tapé l'UserForm ce ferme!
ps: le fichier joint est nettoyé.
Bonjour,
Pas d'affolement !
Le pb d'AfterUpdate est réglé (on y reviendra). Pour l'instant j'essaie d'équilibrer une boucle pour répéter une seule fois la saisie... et sur 3 cas, j'ai toujours un cas où ça disjoncte
A+
Bonjour MFerrand
Cool, car j'y ai passé presque la nuit, pour trouvé (sans succès), il y a tellement de méthodes d'écrites sur le net, qu'à la fin fin je ne m'en sort plus
par contre que pense tu de mon nettoyage du module?
au plaisir
Ouf ! J'ai eu un peu de mal mais ça à l'air d'être à peu près au point...
Je n'ai pas vu ce que tu as fait depuis... donc si ça recoupe...
Je comptais de laisser analyser toi-même le dispositif, mais il vaut finalement mieux le décrire.
J'ai un petit peu agrémenté, mais tu feras les modifs qui te conviennent...
Eléments modifiés :
- Elimination de la variable password niveau module.
- Le mot de passe est tapé sur la feuille ATELIER en Z1 (police à blanc).
- On ne l'atteint pas en pointant Z1, mais par [Crit].Cells(1, 16)
Le problème rencontré pour le déclenchement d'AfterUpdate vient du fait que TextBox1 est le seul contrôle sur lequel se marque un arrêt de tabulation, donc le focus ne le quitte jamais... Je m'en suis rendu compte en allant vérifier l'ordre de tabulation : Seuls TextBox1 et Label1 apparaissaient et il n'y a pas d'arrêt sur une Label. Image1 n'apparaît pas ! (j'aurai appris quelque chose !
Donc : j'ai ajouté TextBox2, qui est un contrôle sur lequel la tabulation s'arrêtera, qui permet donc de sortir de TextBox1.
Le code interne au userform devient donc :
Private Sub TextBox1_AfterUpdate()
Me.Hide
End Sub
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
Cancel = True
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
If CloseMode = vbFormControlMenu Then Cancel = True
End Sub
La première proc. est la proc. utile : la touche Entrée valide la saisie et fait sortir de TextBox1, AfterUpdate se déclenche et masque le Userform (ce qui rend la main à la proc. appelante, voir après...)
Mais s'il fallait sortir de TextBox1, il fallait éviter de s'engluer sur TextBox2. Après des essais avec SetFocus qui n'aboutissait pas au bon résultat, la programmation de l'évènement Exit (qui se déclenche après AfterUpdate) en procédant simplement à l'annulation de la sortie joue bien son rôle et permet de rester sur TextBox1.
La 3e procédure est motivée par le fait que si l'utilisateur veut sortir du userform par la croix de fermeture au milieu de l'opération, cela déclenche une erreur, donc on l'empêche.
Le reste se passe dans la procédure appelante :
Sub Ouvrir()
Dim psw$, i%
With UserForm1
Do While i < 3
.Show
With .TextBox1
psw = .Value: i = i + 1: MsgBox i: MsgBox psw
If psw = [Crit].Cells(1, 16) Then Exit Do
If i = 1 Then MsgBox "! Fatigue ? Un petit effort !": .Value = ""
If i = 2 Then i = 3
End With
Loop
End With
Unload UserForm1
Select Case i
Case 1, 2
If i = 1 Then
MsgBox "OK ! OK !!"
Else
MsgBox "Voilà qui est mieux !"
End If
UnprotectAllSheets psw
Case Else
MsgBox "! Pas de bras, pas de chocolats !"
End Select
End Sub
Voyons pas à pas comment elle procède : une variable psw pour recueillir le mot de passe saisi, une variable 1 pour sérier les cas...
On utilise une boucle (la boucle For... Next ne faisait que me faire me mélanger les pieds
- La boucle s'exécutera tant que i est inférieur à 3 ; quand on y entre : i = 0
- on ouvre le Userform : l'utilisateur saisit et appuie sur Entrée (le Userform se masque)
- on récupère la saisie dans psw et on incrémente i qui vaut alors 1
- on vérifie le mot de passe, s'il est bon on sort de la boucle (avec i=1)
- sinon on affiche un message, on efface la saisie dans TextBox1, et on boucle...
- on réaffiche le Userform, l'utilisateur ressaisit, appuie sur Entrée (le userform se masque à nouveau)
- on récupère à nouveau la saisie dans psw et on incrémente i qui vaut alors 2
- on vérifie à nouveau le mot de passe, s'il est cette fois bon, on sort de la boucle (avec i=2)
- sinon on incrémente alors i, qui vaudra 3 et fera sortir de la boucle (avec i=3).
En sortie de boucle, on teste i. Si i =1 ou i =2, le mot de passe est bon. On affiche un message (différencié selon que i = 1 ou 2) et on lance la proc. de déverrouillage en lui passant le mot de passe.
Si i =3, le mot de passe n'est pas bon. Un message, et c'est tout.
La proc, de déverrouillage :
Sub UnprotectAllSheets(pw As String)
Dim Sht As Worksheet
For Each Sht In ThisWorkbook.Worksheets
Sht.unprotect pw
Next Sht
ActiveWindow.DisplayWorkbookTabs = True
End Sub
Dans la foulée, j'ai fait le pendant inverse pour reverrouiller (sans l'attacher à un bouton, à toi de voir quel déclencheur prendre.
Sub Fermer()
Dim pw$, Sht As Worksheet
pw = [Crit].Cells(1, 16)
For Each Sht In ThisWorkbook.Worksheets
Sht.Protect pw
Next Sht
Sheets("RECHERCHE").Activate
ActiveWindow.DisplayWorkbookTabs = False
End Sub
NB- Si j'ai supprimé des lignes par rapport à ta rédaction initiale, c'est qu'elles n'étaient pas utiles...
Exemple : la procédure de déverrouillage est lancée par un bouton sur RECHERCHE : inutile d'activer la feuille à la fin, elle est active et elle le reste, puisqu'on n'aura pas bougé entretemps.
Par contre, ne sachant dans quelles conditions la proc. de verrouillage sera lancée, là je l'active pour être sûr d'être sur cette feuille une fois les onglets désactivés. (Ce qui peut être revu si on la lance à partir de cette feuille).
Je te laisse étudier le détail des commandes.
Cordialement.
Magnifique
Par contre je me suis permis de modifier certaines chose, car l'affichage du mot de passe dans une MsgBox n'est pas top
Modification de:
psw = .Value: i = i + 1: MsgBox i: MsgBox psw'partie suprimé
Supression de:
MsgBox "OK ! OK !!"
par ceci et ensuite c'est surtout de personalisation des MsgBox:
With UserForm1
Do While i < 3
.Show
With .TextBox1
psw = .Value: i = i + 1
If psw = [Crit].Cells(1, 16) Then Exit Do
If i = 1 Then MsgBox "! MDP incorrect, encore 1 essai !", vbExclamation, "Attention !": .Value = ""
If i = 2 Then i = 3
End With
Loop
End With
Unload UserForm1
Select Case i
Case 1, 2
If i = 1 Then
MsgBox "OK ! OK !!"'suprimer
Else
MsgBox "Voilà qui est mieux !", vbInformation, "Félicitation"
End If
UnprotectAllSheets psw
Case Else
MsgBox "! Pas de bras, pas de chocolats !", vbCritical, "Perdu!"
End Select
End Sub
Travail magnifique, encore une fois
Il s'agissait de tests intermédiaires... car j'ai eu une période où chaque fois la TextBox était vide au moment du test. J'avais donc mis ça pour savoir la valeur avant test et positionner correctement l'effacement de la TextBox.
Ce n'est évidemment pas à conserver !
Tu as par ailleurs tout à fait raison d'étoffer tes messages et les adapter (je suppose) aux particularités de ton environnement...
Bonne continuation.
Pour moi, cela suffira comme effort de réflexion pour la journée...
Joyeuses fêtes.
Merci passe aussi un bon réveillon.