BeforeUpdate comment ça marche ?

Ours masqué

XLDnaute Junior
Bonsoir,

Encore une fois, je viens solliciter votre aide : je suis sur une userform avec des textbox qui ont chacune une date.
Je voudrais saisir une nouvelle date et avant de reporter le texte dans ma feuille de calcul, vérifier le format. Je pensais utiliser textbox1_beforeupdate et afterupdate. Alors, autant j'arrive à utiliser afterupadte, autant, je ne comprends pas l'autre.

Merci de m'aider sur ce problème. Je sèche... :S J'ai essayé :

Private Sub TextBox1_AfterUpdate()
If TextBox1.Text Like '[0-9][0-9]/[0-9][0-9]/[0-9][0-9]' Or _
TextBox1.Text Like '[0-9]/[0-9][0-9]/[0-9]' Or _
TextBox1.Text Like '[0-9][0-9]/[0-9]/[0-9]' Or _
TextBox1.Text Like '[0-9]/[0-9]/[0-9]' Then
Call Couleurs.InitPiloteCouleur(DonnéesPilote.Caption)
TextBox1.BackColor = Range('A6').Interior.Color
Else
TextBox1_BeforeUpdate (True) 'ne fonctionne pas !!!!
End If
End Sub
 

myDearFriend!

XLDnaute Barbatruc
Bonsoir Ours masqué,

Si j'ai bien compris, tu voudrais vérifier la saisie lors de la perte du focus par le TextBox et effectuer le traitement si c'est OK ou revenir au TextBox si c'est KO. C'est bien ça ?

Il te faut donc choisir un évènement qui intervient au sortir du curseur... Il en existe effectivement plusieurs pour les TextBox : BeforeUpdate(), AfterUpdate() et Exit(). Lequel choisir ?

Tout d'abord, si tu souhaites empêcher la perte de focus par le contrôle si la saisie n'est pas bonne (pour permettre à l'utilisateur de rectifier sa saisie par exemple), il te faut choisir un évènement qui possède un argument Cancel. Or, dans ce cas, tu n'as pas choisi le bon évènement car AfterUpdate() est le seul des 3 qui ne possède pas d'argument ! Il te reste donc le choix entre BeforeUpdate() et Exit().
J'ai testé les 2 et ça semble fonctionner correctement. Ci-dessous, l'exemple avec Exit() :
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
      With TextBox1
            If .Text Like '##/##/##' Or _
                  .Text Like '#/##/#' Or _
                  .Text Like '##/#/#' Or _
                  .Text Like '#/#/#' Then
                  Call Couleurs.InitPiloteCouleur(DonnéesPilote.Caption)
                  TextBox1.BackColor = Range('A6').Interior.Color
            Else
                  Cancel = True   'Empêche la perte du focus
            End If
      End With
End Sub
Pour info, avec l'opérateur Like, il existe des caractères jokers (voir l'aide) : '#' est l'un d'entre eux et il est équivalent à '[0-9]'.

Si ça peut t'être utile, je te joins un exemple de contrôle de date dans un TextBox que j'avais réalisé il y a quelques temps...

Cordialement,
[file name=mDF_txtDATE_20051117013941.zip size=12552]http://www.excel-downloads.com/components/com_simpleboard/uploaded/files/mDF_txtDATE_20051117013941.zip[/file]
 

Pièces jointes

  • mDF_txtDATE_20051117013941.zip
    12.3 KB · Affichages: 63

Ours masqué

XLDnaute Junior
Encore une fois je crois que je vais pouvoir progresser. Merci beaucoup. Je reprends ces modifications dans mon projet. J'ai d'ailleurs eu le plaisir de vous découvrir dans un projet de calcul des jours d'absence. Je vais m'en inspirer pour la page remerciements si vous n'y voyez pas d'inconvénient... ;)

Juste une question joker elle aussi :
Vu que j'ai 9 textbox en même temps dans ma userform et qu'elles font toutes la même chose, peut on faire une macro globale ou faut'il la recopier 9 fois (là, c'est juste pour la beauté du geste et pour tenter de progresser encore un peu... y'a du chemin à faire, je sais
parce que sinon, je recopie sans pb, je sais faire.

Encore un grand merci
 

myDearFriend!

XLDnaute Barbatruc
Bonsoir Ours masqué, le Forum,

Si le traitement applicable est le même pour les 9 TextBox, le plus simple est de créer une procédure commune de traitement qui sera donc appelée par chaque TextBox. Aussi, on peut éventuellement passer un argument à cette procédure pour identifier le contrôle appelant et adapter le traitement en conséquence...

En reprenant ton exemple précédent, tu pourrais donc simplifier de la même manière : dans les 9 évènements Exit(), un appel à la procédure commune avec la propriété Text passée en argument. Cette procédure vérifiera donc la saisie de l'utilisateur et appliquera le traitement en cas de test réussi.

Une particularité cependant ici : tu as besoin d'affecter une valeur Vrai ou Faux à l'argument Cancel de chacun de ces 9 évènements appelants. En lieu et place d'une simple procédure Sub, on va donc utiliser une Function qui fera la même chose que la procédure Sub, mais permettra le retour d'une valeur True ou False à l'évènement appelant pour affectation à Cancel.

Tu devrais donc pouvoir faire comme ci-dessous :

Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
      Cancel = DateNonConforme(TextBox1.Text)
End Sub

Private Sub TextBox2_Exit(ByVal Cancel As MSForms.ReturnBoolean)
      Cancel = DateNonConforme(TextBox2.Text)
End Sub

Private Sub TextBox3_Exit(ByVal Cancel As MSForms.ReturnBoolean)
      Cancel = DateNonConforme(TextBox3.Text)
End Sub

'On continue ensuite la même chose pour les 6 autres TextBox...
'...
'...


'Ici, la fonction commune aux 9 TextBox qui retournera Vrai ou Faux
Private Function DateNonConforme(T As String) As Boolean
      If T Like '##/##/##' Or _
            T Like '#/##/#' Or _
            T Like '##/#/#' Or _
            T Like '#/#/#' Then
            Couleurs.InitPiloteCouleur (DonnéesPilote.Caption)
            .BackColor = Range('A6').Interior.Color
      Else
            DateNonConforme = True
      End If
End Function
Une autre façon de faire consiste à utiliser un module de classe qui permet de régler ce genre de situation en une procédure évènementielle unique. Mais cette méthode est beaucoup plus complexe à mettre en oeuvre et je ne m'y attarderais pas cette fois... Par ailleurs, cette façon de faire impliquerait un problème supplémentaire pour ton cas : les TexBox gérés par module de classe ne possèdent pas d'évènement Exit(), ni BeforeUpdate() !

Cordialement,
 

Ours masqué

XLDnaute Junior
Merci beaucoup MyDearFriend !

Je vois globalement l'astuce pour la fonction. Il me reste alors à voir l'ordre d'éxecution entre exit beforeupdate et afterupdate (j'ai déjà vu où le trouver, je crois que je vais y arriver) parce que maintenant j'utilise plusieurs fonctions en même temps et j'ai été obligé de faire l'hypothèse que mon commanditaire saura taper une date sans trop se tromper. Ca aide même si ça ne me satisfait pas trop et vous non plus j'imagine : c'est pas très propre.

Voici donc pour une seule textbox, la 1 par exemple, tout ce qui se passe. Vous reconnaîtrez AutoriseFrappe qui n'est certes pas de moi.
Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
'Dans les TextBox de DATE, autorise uniquement les touches numériques et /
KeyAscii = AutoriseFrappe(KeyAscii)
End Sub

Private Sub UserForm_Initialize()
' Limitation des
' Initialisation des couleurs de la fenêtre Données Pilote (Echéances...)
With DonnéesPilote
.Caption = Range('C1').Value
.TextBox1.BackColor = Range('A6').Interior.Color
.TextBox1.MaxLength = 10
End With
End Sub

Private Sub TextBox1_Change()
' Mettre le fond blanc pour que la couleur ne soit plus valable : une MAJ s'impose
TextBox1.BackColor = 16777215
End Sub

Private Sub TextBox1_AfterUpdate()
' Mise à jour de la couleur dans la feuille ainsi que dans le textbox
' dès que le focus quitte le textbox
' C'est la seule façon de faire que j'ai trouvée qui fonctionne
' mais ça ne vérifie pas encore complètement le format de la saisie
Call Couleurs.InitPiloteCouleur(DonnéesPilote.Caption)
TextBox1.BackColor = Range('A6').Interior.Color
End Sub
Je crois que j'ai tout mis. Merci. A le relire, je me demande si la syntaxe est si correcte que ça... :silly:
 

crane99

XLDnaute Nouveau
Re : BeforeUpdate comment ça marche ?

bonjour, je viens solliciter votre aide a mon tour.
Je travaille sur un projet de mon comité d’entreprise de gestion billetterie.
Sur une userform, avec une ComboBox, je souhaite faire confirmer une modification de choix.
Pour empêcher les mises à jour qui suivent la validation de la valeur.
Je blogue sur l'utilisation... beforeupdate.
J'ai essayé

Private Sub ComboBoxDesignParcAtraction_BeforeUpdate()

MsgBox ComboBoxDesignParcAtraction.Value & " vous voulez modifié le type d'attraction.", _
vbOKOnly + vbOKCancel + vbInformation, "Modification Attraction"

End Sub

merci pour votre aide
 

Discussions similaires

Statistiques des forums

Discussions
312 499
Messages
2 088 999
Membres
104 002
dernier inscrit
SkrauzTTV