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é)

103ne-atelier-test.xlsm (133.02 Ko)

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 ! Je considère que l'indentation n'est pas une option mais une obligation. Et je n'ai aucune envie de travailler sur un code dont l'écriture part dans tous les sens, truffé de lignes inutiles...

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 ,moi c'est pareil quand je dois réparer un pc (hardware ou software) je n'aime pas non plus travailler dans un fouillis.

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é.

54ne-atelier-ep.xlsm (168.64 Ko)

Bonjour,

Pas d'affolement ! J'ai commencé sur ton fichier précédent, je continue...

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 Grrr !

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)
NB- Cela ne tromperait pas un pratiquant chevronné, mais un débutant aura au moins du mal à s'y retrouver, et un utilisateur lambda sera vite noyé...

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 , j'ai donc finir par me rabattre sur Do... Loop...)

  • 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

Effectivement !!!

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... On va aussi penser au repas...

Joyeuses fêtes.

Merci passe aussi un bon réveillon.

Rechercher des sujets similaires à "valider textbox enter"