Vous ne trouvez pas de réponse à votre problème ? Alors posez la question dans le forum. Souvenez-vous qu'il n'y a jamais de question bête, mais rester dans l'ignorance parce que l'on n'ose pas poser une question, ça c'est une erreur !

ZONE DE SAISIE DE DATE FORMAT JJ/MM/AAAA, N'UTILISEZ PLUS LE CONTROLE MASKEDIT.OCX !


Information sur la source



Description

Je sais que ce type de projet n'est pas dans mes habitudes pour ceux qui me connaissent (je préfère en effet faire de l'inédit qui sert rarement que du tout cuit qui sert vraiment lol), mais suite à une demande, j'ai réalisé le coding des 2 evènements "Change" et "Keypress", qui une fois implémenté transforme une zone de saisie (principalement une TextBox) en véritable Maskedit 00/00/0000, avec en plus un controle des valeurs Jour et Mois.
 

Source

  • 'Dessinez une TextBox, nommez-la ZT, puis mettez sa propriété MaxLength à 10
  • 'Puis dans le code, collez ces 2 courtes procédures :
  • Private Sub ZT_Change()
  • Dim p As Integer
  • p = ZT.SelStart
  • If Len(ZT.Text) = 3 Then
  • If Mid$(ZT.Text, 3, 1) <> "/" Then
  • If Mid$(ZT.Text, 2, 1) = "/" Then ZT.Text = "0" & ZT.Text Else ZT.Text = Left$(ZT.Text, 2) & "/" & Right$(ZT.Text, 1)
  • p = p + 1
  • End If
  • If Val(Left$(ZT.Text, 2)) > 31 Then ZT.Text = "31" & Mid$(ZT.Text, 3, Len(ZT.Text) - 2)
  • End If
  • If Len(ZT.Text) = 6 Then
  • If Mid$(ZT.Text, 6, 1) <> "/" Then
  • If Mid$(ZT.Text, 5, 1) = "/" Then ZT.Text = Left$(ZT.Text, 3) & "0" & Right$(ZT.Text, 3) Else ZT.Text = Left$(ZT.Text, 5) & "/" & Right$(ZT.Text, 1)
  • p = p + 1
  • End If
  • If Val(Mid$(ZT.Text, 4, 2)) > 12 Then ZT.Text = Left$(ZT.Text, 3) & "12" & Mid$(ZT.Text, 6, Len(ZT.Text) - 5)
  • End If
  • ZT.SelStart = p
  • End Sub
  • Private Sub ZT_KeyPress(KeyAscii As Integer)
  • If KeyAscii = 47 Then
  • Select Case Len(ZT.Text)
  • Case 1, 2, 4, 5
  • Case Else
  • KeyAscii = 0
  • End Select
  • Else
  • If InStr(1, "0123456789/" & Chr$(vbKeyBack), Chr$(KeyAscii)) = 0 Then KeyAscii = 0
  • End If
  • End Sub
'Dessinez une TextBox, nommez-la ZT, puis mettez sa propriété MaxLength à 10
'Puis dans le code, collez ces 2 courtes procédures :


Private Sub ZT_Change()
Dim p As Integer
  p = ZT.SelStart
  If Len(ZT.Text) = 3 Then
    If Mid$(ZT.Text, 3, 1) <> "/" Then
      If Mid$(ZT.Text, 2, 1) = "/" Then ZT.Text = "0" & ZT.Text Else ZT.Text = Left$(ZT.Text, 2) & "/" & Right$(ZT.Text, 1)
      p = p + 1
    End If
    If Val(Left$(ZT.Text, 2)) > 31 Then ZT.Text = "31" & Mid$(ZT.Text, 3, Len(ZT.Text) - 2)
  End If
  If Len(ZT.Text) = 6 Then
    If Mid$(ZT.Text, 6, 1) <> "/" Then
      If Mid$(ZT.Text, 5, 1) = "/" Then ZT.Text = Left$(ZT.Text, 3) & "0" & Right$(ZT.Text, 3) Else ZT.Text = Left$(ZT.Text, 5) & "/" & Right$(ZT.Text, 1)
      p = p + 1
    End If
    If Val(Mid$(ZT.Text, 4, 2)) > 12 Then ZT.Text = Left$(ZT.Text, 3) & "12" & Mid$(ZT.Text, 6, Len(ZT.Text) - 5)
  End If
  ZT.SelStart = p
End Sub

Private Sub ZT_KeyPress(KeyAscii As Integer)
  If KeyAscii = 47 Then
    Select Case Len(ZT.Text)
      Case 1, 2, 4, 5
      Case Else
        KeyAscii = 0
    End Select
  Else
    If InStr(1, "0123456789/" & Chr$(vbKeyBack), Chr$(KeyAscii)) = 0 Then KeyAscii = 0
  End If
End Sub

Conclusion

Cela permet de se passer du masked.ocx, mais certains, peut soucieux du déploiement, y préféreront toujours un bon vieux Calendar bien lourd... dommage pour eux ;)

@+
Celiphane
 

Commentaires et avis

signaler à un administrateur
Commentaire de scoder le 18/06/2004 10:20:39

Simple et court, pas mal. Mais il doit y avoir une erreur au niveau de la vérif des jours/mois puisque j'arrive à saisir 31/02/2004....

signaler à un administrateur
Commentaire de moustachu le 18/06/2004 10:38:46

Je crois qu'il s'agit de formatage pas de vérif... enfin c'est ce que je comprends.

++
Moustachu

signaler à un administrateur
Commentaire de celiphane le 18/06/2004 13:32:16

C'est exactement ça Moustachu.

S'il eu fallut que j'implémente une gestion exact du temps, le code aurait été trop lourd. Ce que j'ai reproduit ici, c'est le fonctionnement exact d'un MaskEdit, rien d'autre. D'où, je me cite : "00/00/0000".

Et ça peut servir, donc voilà

@+
Celiphane

signaler à un administrateur
Commentaire de celiphane le 18/06/2004 13:41:38

vous remarquerez aussi que si vous tapez par exemple :

1
puis /

il retranscrit tout seul en 01/

idem pour les mois.

signaler à un administrateur
Commentaire de scoder le 18/06/2004 14:34:29

c'est sûr que le code aurait été plus lourd avec une gestion exacte du temps. Enfin c'est très bien comme ça et puis ça sera probablement utile à pas mal de codeurs

signaler à un administrateur
Commentaire de moustachu le 18/06/2004 14:41:43

Boohhh, tu "pètes" ,une erreur lors de l'évènement LostFocus si CDate(ZT.Text) n'est pas valide.

signaler à un administrateur
Commentaire de celiphane le 18/06/2004 14:50:44

J'ai pas bien saisi ton dernier message Moustachu...

@+
Celiphane

signaler à un administrateur
Commentaire de moustachu le 18/06/2004 15:00:06

C'est vrai qu'à le relire, il est un peu ésotérique ...

Je voulais juste dire que tu pouvais tester la validité de la date avec IsDate (pas CDate) lors que le controle perds le focus.

++
Moustachu

signaler à un administrateur
Commentaire de celiphane le 18/06/2004 15:30:23

C'est exact.

Cependant, en cas de date non réelle, il faut encore ajouter du code pour la remplacer par la date la plus proche de celle erronée.

Perso, je m'y colle pas, bien que ce n'est pas l'épreuve en elle-même qui me repousse mais plutôt la volonté...

Alors tout est dit ! Le code est là, le "perfectionnement", pour faire plus que du format, a été proposé par Moustachu, et par 2 fois même.


:)

@+
Celiphane

signaler à un administrateur
Commentaire de moustachu le 18/06/2004 16:14:08

Ouais ok... c'est le coup du Refresh après un poste. Désolé...

:o)

Moustachu

signaler à un administrateur
Commentaire de Olilefou le 19/06/2004 01:48:57

Moi, je mets ce qui suit, ca ne m'empeche pas de saisir une erreur, mais ca me dis si la date est valide, et je peux saisir '02 jan 04' , '3 avril 2002' ou '01/02/03' .

Private Sub Text1_LostFocus()
On Error GoTo Erreur:
  Text1.Text = Format(DateValue(Text1.Text), "dd/mm/yyyy")
Exit Sub
Erreur:
  MsgBox "Erreur de saisie..."
End Sub

signaler à un administrateur
Commentaire de celiphane le 19/06/2004 10:14:21

Heu... je vois pas là : c'est un code qui remplace le mien ou qu'il le complète ?

Parceque si ça le remplace, tu n'as pas bien compris le but, si ça le complète, je vois pas pourquoi tu précises qu'on peut saisir '02 jan 04' etc vu que mon appli a pour but d'empêcher ce genre de bêtise.

Teste le code avant de dire que tu fais X ou Y en plus court, tu verras exactement ce qu'il fait, et là je veux bien que tu me montres comment tu fais plus court pour les mêmes fonctionnalités...


@+
Celiphane

NB: pour faire plus clair, ton code est un code des années passées de l'informatique, c'est un code de restriction : l'utilisateur mange un message d'erreur qu'il doit valider à chaque fois qu'il saisit quelque chose sans trop comprendre pourquoi. C'est aujourd'hui appelé "vieille école", c'est comme faire valider toutes ses saisies à l'utilisateur.
Le but d'un contrôle Masked, comme celui proposé ici, est de GUIDER l'utilisateur vers la bonne syntaxe... nuance des applications récentes, on a appelé ça l'ergonomie ;)

signaler à un administrateur
Commentaire de celiphane le 19/06/2004 10:16:41

en me relisant je trouve mon message "pet sec", mais le but n'était pas là, je voulais vraiment expliquer mon point de vue.
Je remet ce message pour adoucir le ton parceque je suis un gentil :)

@+
Celiphane

signaler à un administrateur
Commentaire de Olilefou le 19/06/2004 20:36:43

1) J'ai bien marqué que mon exemple ne remplace pas le tien puisqu'il fait autre chose.

2) Puisque tu veux bien que je te montre un code plus cour que le tien et qui fait la même chose, en voici un :

Private Sub Text1_KeyPress(KeyAscii As Integer)
Select Case KeyAscii
Case Asc("0") To Asc("9")
  If Len(Text1.Text) = 2 Or Len(Text1.Text) = 5 Then Text1.Text = Text1.Text & "/"
Case Asc("/")
  If Not IsNumeric(Right(Text1.Text, 1)) Then KeyAscii = 0
  If Len(Text1.Text) = 1 Then Text1.Text = "0" & Text1.Text
  If Len(Text1.Text) = 4 Then Text1.Text = Left(Text1.Text, 3) & "0" & Right(Text1.Text, 1)
Case vbKeyBack
Case Else
  KeyAscii = 0
End Select
If Len(Text1.Text) &gt; 1 And Val(Left(Text1.Text, 2)) &gt; 31 Then Text1.Text = "31" & Mid(Text1.Text, 3)
If Len(Text1.Text) &gt; 4 And Val(Mid(Text1.Text, 4, 2)) &gt; 12 Then Text1.Text = Left(Text1.Text, 3) & "12" & Mid(Text1.Text, 6)
Text1.SelStart = Len(Text1.Text)
End Sub

L'événement Change est vide.

3) Mes clients préfèrent des zones de saisies libres et contrôlées plutôt que des masques, le client et roi (Evidement, mes MsgBox sont plus clairs dans mes applis).

4) Pour les curieux, voici un code mieux que le précédent,
- il gère les dates comme 00/00/0000 ou 31/04/2004
- on n'est pas obligé de mettre MaxLength à 10
- il autorise ctrl+x, ctrl+c et ctrl+v

Private Sub Text1_KeyPress(KeyAscii As Integer)
Dim Borne As Long
Select Case KeyAscii
Case Asc("0") To Asc("9")
  If Len(Text1.Text) = 2 Or Len(Text1.Text) = 5 Then Text1.Text = Text1.Text & "/"
  If Len(Text1.Text) &gt; 9 Then KeyAscii = 0
Case Asc("/")
  If Not IsNumeric(Right(Text1.Text, 1)) Then KeyAscii = 0
  If Len(Text1.Text) = 1 Then Text1.Text = "0" & Text1.Text
  If Len(Text1.Text) = 4 Then Text1.Text = Left(Text1.Text, 3) & "0" & Right(Text1.Text, 1)
  If Len(Text1.Text) &gt; 6 Then KeyAscii = 0
Case vbKeyBack, 24, 3, 22 'ctrl x c v
Case Else
  KeyAscii = 0
End Select
If Len(Text1.Text) &gt; 4 Then
  Borne = 31
  Select Case Val(Mid(Text1.Text, 4, 2))
  Case 0
    Text1.Text = Left(Text1.Text, 3) & "01" & Mid(Text1.Text, 6)
  Case 4, 6, 9, 11
    Borne = 30
  Case 2
    Borne = 29
  Case Is &gt; 12
    Text1.Text = Left(Text1.Text, 3) & "12" & Mid(Text1.Text, 6)
  End Select
  If Val(Left(Text1.Text, 2)) &gt; Borne Then Text1.Text = Borne & Mid(Text1.Text, 3)
  If Val(Left(Text1.Text, 2)) &lt; 1 Then Text1.Text = "01" & Mid(Text1.Text, 3)
End If
Text1.SelStart = Len(Text1.Text)
End Sub

Je vous laisse gérer les années bissextiles, j'ai la flemme.

5) Moi aussi je suis un gentil.

Bye

signaler à un administrateur
Commentaire de celiphane le 19/06/2004 22:41:59

Je n'ai pas le temps de tester tout tout de suite, mais c'est excellent.

merci pour ces précisions !



@+
Celiphane

signaler à un administrateur
Commentaire de celiphane le 19/06/2004 22:53:28

Vu que le test consiste en un simple copier-coller sous vb, j'ai en fait eu le temps de tester ;)

Ces codes sont mieux pensés et plus clair à comprendre (niveau développeur) que le miens ci-dessus proposé.

M'autorises-tu à rééditer ma source en remplaçant mes lignes par les tiennes ? Cela vaudra mieux pour tout le monde !

Beau boulot, j'aurai du me fouiller un peu plus avant de balancer ma "trouvaille" :)

merci,

@+
Celiphane

signaler à un administrateur
Commentaire de Olilefou le 20/06/2004 13:00:18

Bien sur que tu peux utiliser mes exemples, sinon je ne viendrais pas sur ce site.

Bye

signaler à un administrateur
Commentaire de celiphane le 01/07/2004 11:08:49

non ba en fait en ayant approndi les tests (dans le cadre d'une utilisation professionnelle en faite), je conserve mon code, parceque les 2 codes que tu as proposé Olilefou sont "buggés" :

Le premier, le court, autorise la saisie de N caractères slash (0 slash 0 slash 0 slash ca passe !!!)

Le second, le long, n'autorise pas l'utilisateur à modifier du texte DANS la date : si tu mets 12/05/2003, et que tu sélectionne juste 12 en surbrillance, le fait de taper au clavier remet immédiatement le curseur à la fin de la textbox.

Désolé mais je conserve mon code, plus fonctionnel. A moins que tu ne puisses corriger ca ?

@+
Celiphane

signaler à un administrateur
Commentaire de teddy_bear le 03/08/2004 18:10:28

merci beaucoup pour ce coude ca m'a aidé bcp c'est exactement ce ke je cherchait
si tu peu m'aider je voudrai bien savoir comment calculer le nombre de jours entre 2 dates
je serai trè reconnaissante
merci encore

signaler à un administrateur
Commentaire de moustachu le 04/08/2004 09:36:34

C'est DateDiff("d",date1,date2)

++
Moustachu

signaler à un administrateur
Commentaire de mictif le 16/12/2004 23:00:04

chez moi ca ne marche pas!!!
le format est "000000/00"
si chez vous ca marrche je comprend pas pourquoi chez moi ca marche pas!!! enfin je rergarde...
ps merci pour ce code
        mictif l'apprenti DI

Ajouter un commentaire



Nos sponsors

Sondage...

CalendriCode

Décembre 2008
LMMJVSD
1234567
891011121314
15161718192021
22232425262728
293031    

Consulter la suite du CalendriCode



Développement réalisé par Nicolas SOREL (Nix) avec l'aide de : Cyril DURAND et Emmanuel BAÏSE, Merci à Vincent pour ses précieux conseils
CodeS-SourceS.com© Toute reproduction même partielle est interdite sauf accord écrit du Webmaster
CodeS-SourceS.com© est une marque déposée tous droits réservés
Temps d'éxécution de la page : 0,218 sec

Google Coop CodeS-SourceS Google Coop CodeS-SourceS


Certaines images présentes sur le site (notament certains avatars) sont issues des collections IconShock, donc si vous souhaitez utiliser ces icons vous devez les acheter, ne les copiez pas et ne utilisez pas dans vos sites et applications sans les avoir commandé.