Cancel = true ne fonctionne pas sur sortie textbox

Bonjour,

J'ai un souci avec ce bout de code en sortie d'un textbox:

Private Sub Tbx_UsersModification_NewTel_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If Not ControlerFormatTelephone(me.Tbx_UsersModification_NewTel.Value) Then
MsgBox "Le numéro de téléphone doit contenir 10 chifres."
Cancel = True
End If
End Sub

je ne comprends pas pourquoi le textbox ne se vide pas, ni pourquoi il ne garde pas le focus. j'ai regardé un peu partout sans succés et essayé d'autres solutions, notamment en ajoutant me.Tbx_UsersModification_NewTel.Value = vbnullstring et me.Tbx_UsersModification_NewTel.SetFocus. J'ai même refait intégralement le formulaire , mais rien n'y fait. Quelqu'un aurait-il une idée? Merci d'avance

Bonjour,

L'event Exit n'existe pas pour les TextBox, votre Sub n'est donc jamais appelé.

Il ne faut pas écrire les events à la main, dans le VBE vous devez cliquer en haut à gauche pour choisir l'objet, et en haut à droite pour choisir la procédure à implémenter.

De plus évitez les "_" dans le nom de vos objets, comme vous pouvez le constater c'est utilisé pour séparer le nom d'une variable de son Event. Donc ça ne fait pas bon ménage et rend votre code moins lisible.

merci de cette réponse rapide. je vais voir pour les noms. pour exit, j'ai retesté. j'ai crée un nouveau textbox. si je clique sur code, l'évenement change est proposé par défaut, mais dans la liste à droite, j'ai bien l'événement exit :

capture d ecran 2025 04 04 153606

et en sélectionant j'ai le code

Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)

End Sub

c'est ce que j'ai fait dans mon code, donc je ne comprends pas quand vous dites exit n'existe pas pour les textbox Pouvez vous préciser? Merci

Ah toutes mes excuses, j'ai regardé la mauvaise documentation. Bon alors votre syntaxe est correcte c'est déjà ça.

Je pense que le Cancel = True est bloqué par votre MsgBox qui oblige a perdre le focus…

Regardez le code proposé ici, à mon avis il vous convient parfaitement. L'idée étant de déplacer la msgbox autre part pour ne pas "perdre le focus" du Cancel. Càd que le code reste dans la TextBox en attendant que l'on ferme la MsgBox.

Après bon personnellement je n'ai jamais trop joué avec ces events, je pense que par exemple @LooReed s'il passe par là aura de meilleures explications.

merci de ces réponses rapides. je suis allé voir sur le lien. j'ai adapté comme suit mais je ne suis pas que doValidation corresponde bien à ce que j'ai fait dans la mesure ou çà semble être fait pour Access au départ.

donc: dans le userform:

Private Sub Tbx_UsersModification_NewTel_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
Cancel = ControlerFormatTelephone(Tbx_UsersModification_NewTel.Value)
End Sub

dans le module standard

Function ControlerFormatTelephone(ByVal telephone As String) As Boolean
Dim telNettoye As String

' Suppression des espaces et caractères non numériques
telNettoye = Replace(Replace(telephone, " ", ""),".","")

' Vérifier que le téléphone contient bien 10 chiffres après nettoyage
If Len(telNettoye) <> 10 Or Not IsNumeric(telNettoye) Then
MsgBox "Le numéro de téléphone doit contenir exactement 10 chiffres.", vbExclamation
ControlerFormatTelephone = True ' True signifie qu'il y a une erreur (pour Cancel)
End If
End Function

le contrôle reste bien sur le textbox, (quand je tabule sur le champ suivant, le message d'erreur se réaffiche), mais je ne vois pas le focus.

merci

au cas ou et pour être complet le code que j'ai adapté :

je pense que Valid fait référence à des critéres de textbox dans Access?

Private Sub TextBox1_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
    Cancel = doValidation(Textbox1.Text) 'Validation Route
End Sub

Private Function doValidation(strText) as Boolean
    'Do Validation
    if Valid then
        doValidation = False
    Else
        msgBox "Not Valid"
        doValidation = True
    End if
End Sub

Non pas exactement, DoValidation c'est une fonction "fictive" dans l'exemple qui correspond à votre ControlerFormatTelephone. L'auteur a mis une variable "valid" sans expliquer d'où elle vient mais grosso modo c'est une variable qui contient ce que va renvoyer votre fonction ControlerFormatTelephone : si contrôle ok, valid = True, sinon, False.

L'idée ce serait donc de déplacer votre msgbox d'avertissement dans la fonction ControlerFormatTelephone. Et qu'ensuite vous utilisiez le résultat de la fonction ControlerFormatTelephone pour assigner son inverse à "Cancel" (càd que si ControlerFormatTelephone validé alors on ne Cancel pas, et inversement).

ok, il me semblait pourtant qu'en faisant

If Len(telNettoye) <> 10 Or Not IsNumeric(telNettoye) Then
MsgBox "Le numéro de téléphone doit contenir exactement 10 chiffres.", vbExclamation
ControlerFormatTelephone = True

le résultat étant faux, je renvoie bien la valeur true à cancel ?

Il y a quelque chose qui m'échappe

Merci

Bonsoir,

un fichier qui semble fonctionné :

10textbox1.xlsm (19.05 Ko)
Dim Sortie As Boolean
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
    If Sortie = False And ControlerFormatTelephone(TextBox1.Value) Then
        MsgBox "Erreur dans le numéro de téléphone, recommencez !"
        TextBox1.Value = ""
        Cancel = True
    End If
End Sub
Function ControlerFormatTelephone(ByVal telephone As String) As Boolean
    Dim telNettoye As String
    ControlerFormatTelephone = False
    ' Suppression des espaces et caractères non numériques
    telNettoye = Replace(Replace(Replace(telephone, " ", ""), ".", ""), "-", "")

    ' Vérifier que le téléphone contient bien 10 chiffres après nettoyage
    If Len(telNettoye) <> 10 Or Not IsNumeric(telNettoye) Then ControlerFormatTelephone = True
End Function
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
    Sortie = True
End Sub

J'ai ajouté la suppression des tirets "-".
Une variable Sortie afin d'éviter l'affichage du message lorsque l'on ferme le USF.

@ bientôt

LouReeD

merci à vous deux pour vos réponses. j'ai mis le code comme indiqué.

dans le userfom :

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
Sortie = True
End Sub

Private Sub Tbx_UsersModification_NewTel_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If Sortie = False And ControlerFormatTelephone(Tbx_UsersModification_NewTel.Value) Then
MsgBox "Erreur dans le numéro de téléphone, recommencez !"
Tbx_UsersModification_NewTel.Value = ""
Cancel = True
End If
End Sub

dans un module standard (j'ai prévu d'ajouter ce contrôle à d'autres endroits du projet, notamment dans la gestion des tiers, il faut que je puisse réutiliser le contrôle)

Function ControlerFormatTelephone(ByVal telephone As String) As Boolean
Dim telNettoye As String
ControlerFormatTelephone = False
' Suppression des espaces et caractères non numériques
telNettoye = Replace(Replace(Replace(telephone, " ", ""), ".", ""), "-", "")
' Vérifier que le téléphone contient bien 10 chiffres après nettoyage
If Len(telNettoye) <> 10 Or Not IsNumeric(telNettoye) Then ControlerFormatTelephone = True
End Function

en premier : je ne comprends pas ce que fait query_close, pouvez vous m'expliquer cette commande? je suis allé voir dans l'aide excel qui me dit "force l'utilisateur à cliquer sur la zone cliente UserForm pour la fermer", donc à utiliser la croix pour fermer le userform?

ensuite j'ai testé. Tbx_UsersModification_NewTel.Value est bien vide mais je ne vois toujours pas le focus. il faut que je clique dans le champ pour qu'il apparaisse. j'ai ajouté MsgBox ActiveControl.Name juste avant le end sub de Tbx_UsersModification_NewTel_Exit. j'ai bien en retour le nom du textbox. je m'arrache mes derniers cheveux.

Précision mon userform est en mode non modal

Merci d'avance

je prépare une extraction du fichier pour mieux voir

voila, j'espère que çà va fonctionner et que je n'ai rien oublié

Bonsoir,

vu que vos USF prennent tout l'écran, pourquoi alors les lancer en non modal ? Puisqu'en mode modal comme sur mon fichier le mode de saisie fonctionne ?

Ou bien alors un nouveau USF juste pour mettre à jour le n° de téléphone ou autre :
on entre dans le textbox new tel, cela déclenche l'ouverture du USF "mise à jour" en mode modal, avec juste un textbox dans lequel on aura copier la valeur du New Tel, puis le contrôle de la modification avec retour du focus s'il le faut ou si c'est bon transfert de la donnée dans le textbox new tel.

@ bientôt

LouReeD

bonsoir

le but c'est de ne pas accéder aux feuilles de calcul directement. J'ai donc un usf qui me sert de menu de navigation et qui reste affiché, avec des boutons de commande qui permettent d'accéder aux différentes fonctionnalités. En fonctionnement, les formulaires ne peuvent être fermés, et le mode excel n'est accessible que par un bouton, actif ou non, selon la personne.

En modal, je ne peux afficher qu'un seul userform, il me semble, et il faudrait que j’intègre la navigation sur chaque userform, mais je suis preneur de toute autre idée.

Merci et bonne fin de soirée.

Bonjour à tous,

le but c'est de ne pas accéder aux feuilles de calcul directement.

Bon pourquoi ne pas le gérer avec le ruban, ci-joint un petit exemple que javais concocter, il y a quelques temps et dont vous pouvez vous inspirer.

p.s. Je peux vous aider à mettre en place les modifications.

bonjour et merci jean-paul.

j'ai regardé le fichier et effectivement on peut personnaliser le ruban. j'utilise cela dans d'autres fichiers avec office ribbonx, mais là, mon souci est de faire en sorte qu'on n’accède pas aux feuilles de calcul. mais je me mets le fichier précieusement de côté. dans votre fichier sur type Itemsval, il y a un bout de code: Public Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" ( _
ByRef Destination As Any, _
ByRef Source As Any, _
ByVal Length As Long _
) que je devrais adapter.

sinon, j'ai remarqué des annotations dans les modules qui me font penser à l'utilisation de rubberduck. ce n'est pas le sujet initial mais juste une question rapide, apparemment rubberduck détecte une organisation par dossiers. comment avez vous fait car chez moi, il ne parvient pas à détecter cette organisation?

merci

Bonjour à tous et jvoitu,

mais là, mon souci est de faire en sorte qu'on n’accède pas aux feuilles de calcul

Si vous regardez bien le fonctionnement du classeur, sur le ruban le premier contrôle Liste Déroulante n'affiche que les Feuilles qui commencent par "R" on peut modifier le fonctionnement pour qu'il n'affiche que certaines feuilles.

apparemment rubberduck détecte une organisation par dossiers. comment avez vous fait car chez moi, il ne parvient pas à détecter cette organisation?

Pour se faire Afficher d'abord Affichez la fenêtre Explorateur de code

  • Menu/Rubberduck/Windows/Explorateur de code.
  • Dans la fenêtre sélectionnez l'objet que vous voulez déplacer (Fenêtre, Module, etc) avec un clic droit.
  • Dans le menu qui s'affiche sélectionner Annoter/Folder
000003
  • Renseignez le nom (Attention c'est sensible à la casse)
  • Si vous voulez changer un objet de dossier Faire un clic droit sur l'objet puis, cliquez sur Changer de dossier.

Toutes les informations en détails ici : https://github.com/rubberduck-vba/Rubberduck/wiki/Using-@Folder-Annotations

Bonsoir et merci Jpaul. c'est ok, j'ai compris comment faire et je vais pouvoir regrouper par fonctionnalité. j'avais lu que rubberduck regroupait automatiquement les modules et formes en fonction de leur nom, donc ce n'est pas le cas. il faut créer la structure. un peu de manip mais çà va le faire. ce sera plus pratique quand même. merci beaucoup

Oui, de plus toujours avec un clic droit vous avez la possibilité de changer de dossier pour organiser au mieux tout ce petit monde.

J'utilise aussi beaucoup la description que ce soit au niveau des module ou des procédures.

000001

Bonjour et merci de cette dernière précision Jean Paul.

Sur le problème initial, le problème semble bien lié au fait que j'utilise les formulaires en non modal. Dans ce cas, avec setfocus, le focus est "dans les limbes" pour reprendre une expression que je viens de trouver dans une explication au problème que je rencontre.

Dans la mesure ou je souhaite continuer à utiliser des formulaires pour éviter l’accès aux feuilles de calcul, la seule solution a priori serait que j’intègre le frame de mon menu dans chacun des formulaires du projet et donc d'en dupliquer le code à chaque fois. je ne vois pas comment n'avoir le code des boutons qu'en un seul endroit. Une idée? Merci d'avance

Rechercher des sujets similaires à "cancel true fonctionne pas sortie textbox"