re
bonsoir iliess
il est pret tout beau tout neuf il est maintenant multi format 3 choix
Version imprimable
re
bonsoir iliess
il est pret tout beau tout neuf il est maintenant multi format 3 choix
Bonjour,
Qui c'est qui paye le développement ? Et la maintenance ?
Mille merci Mr patrick c'est le perfectionnement du travail
Pièce jointe 425630
C'est une bien jolie démo, mais pour une appli professionnelle je pense à la maintenance.
Par exemple je peux saisir 12/00/2018 et ça passe.
Donc je déclare une fiche anomalie et le développeur se prend la tête pour corriger.
Comme j'ai mis 5 minutes à trouver un cas en anomalie, je crains qu'il y en ait d'autres.
Pour la "version sans faille" et le "perfectionnement du travail", il faut nuancer.
Salut
En général, je ne travaille pas le mois 0 encore moins le jour 0 8-) !
Ma réflexion ( hors des sentiers battus* j/m/a ): c'est le mois qui décide de la suite ! On le choisit en premier (viendront l'année puis le jour).
- avec février, si l'année n'est pas bissextile on a 28 jours sinon 29 jours
- hors février, certains mois ont 30 jours, d'autres 31.
Le formulaire aura 3 listes nommées respectivement Cj, Cm et Ca (pour les jours, les mois et les années)
* avec un de mes principes : je préfère éviter les erreurs plutôt que de les corriger.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 Option Explicit Dim n As Byte, a As Integer, Dt As Date 'n : variable de jours, de mois, a : variable d'années Private Sub UserForm_Initialize() For n = 1 To 31: Cj.AddItem n: Next 'Cj : liste des jours (entiers de 1 à 31) For n = 1 To 12: Cm.AddItem MonthName(n): Next 'Cm : liste des mois possibles (entiers de 1 à 12) For a = 2018 To 2050: Ca.AddItem a: Next 'Ca : liste des années prévues (2018, ...) à adapter Me.Width = 100 'seule la liste des mois est visible End Sub Private Sub Cm_Click() If Cm <> "" Then Me.Width = 200 'obligation de choisir le mois avant de passer à l'année End Sub Private Sub Ca_Change() If Ca <> "" Then Me.Width = 300 'obligation de choisir l'année If Cm.ListIndex = 1 Then 'si février Cj.Clear: For n = 1 To 28: Cj.AddItem n: Next 'au moins 28 If Ca Mod 4 = 0 Then Cj.AddItem 29 'si année bissextile, 29 en plus Else Cj.Clear: For n = 1 To 30: Cj.AddItem n: Next 'hors février au moins 30 jours For n = 1 To 7 'ajout du 31 aux mois correspondants If Cm.ListIndex + 1 = Array(1, 3, 5, 7, 8, 10, 12)(n - 1) Then Cj.AddItem 31 Next End If End Sub Private Sub Cj_Change() 'date dans l'étiquette nommé E E.Visible = Cj <> "" End Sub Private Sub E_Click() 'transférer ou pas (en cellule E12) Dt = CDate(DateSerial(Val(Ca), Val(Cm.ListIndex + 1), Val(Cj))) If MsgBox(Dt & vbLf & "La transcrire ?", 4, "la date est...") = 7 Then Exit Sub [E12] = Dt Unload Me End Sub
bonsoir
@ordonc
sympa le userform mais ca n'a rien a voir avec un textbox formaté dynamiquement
@Arkham
merci pour le retour de l'erreur "00" c'est corrigé
edit:
@ordonc c'est pour toi
pour la formule ca peut etre ca aussiCode:
1
2
3
4
5
6
7 Private Sub Ca_Change() Dim nbjour If Ca <> "" Then Me.Width = 300 If Cm.ListIndex <> -1 Then Cj.Clear: For n = 1 To Day(DateSerial(Ca.Value, Cm.ListIndex + 2, 1) - 1): Cj.AddItem n: Next End If End Sub
Code:Day(DateSerial(Ca.Value, Cm.ListIndex + 2, 0))
Bonjour à tous (:coucou: Patrick),
j'ai suivi de loin le sujet sans rentrer dans les codes, et j'ai voulu essayer de faire un code depuis 0,
avec des prérogatives penser en amont avant de commencer :
- vérification du jour <= 31
- vérification du mois <=12
- vérification de l'année à + ou - 10 ans
- puis vérification de nouveau du jour par rapport au nb de jours dans le mois
Voilà mon 1er jet :
Code:
1
2
3 Private Sub UserForm_Initialize() TextBox2.Value = "__/__/____" End Sub
Edit: Soyez indulgent, je ne suis pas vraiment habitué aux useform, ne les utilisants quasi jamaisCode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 Private Sub Textbox2_Change() Static VA As String Dim MaskArr(), MinAn As Integer, MaxAn As Integer, Jours As Integer, Mois As Integer, An As Integer, NBJ As Integer, D As String MinAn = Year(Now) - 10: MaxAn = Year(Now) + 10 MaskArr = Array(1, 2, 4, 5, 7, 8, 9, 10) masque = "__/__/____" If TextBox2.Text = "" Then VA = masque: TextBox2 = VA TextBox2.Text = Replace(Replace(TextBox2.Text, Mid(TextBox2.Text, 3, 1), "/", 1, 1), Mid(TextBox2.Text, 6, 1), "/", 1, 1) If TextBox2.Text <> masque Then N = 0 For i = LBound(MaskArr) To UBound(MaskArr) If Not IsNumeric(Mid(TextBox2.Text, MaskArr(i), 1)) Then limite = MaskArr(i) VA = Left(TextBox2.Text, limite - 1) & Mid(masque, limite) Exit For End If If i = 7 Then VA = TextBox2.Text: Exit For Next End If Jours = Val(Mid(VA, 1, 2)): Mois = Val(Mid(VA, 4, 2)): An = Val(Mid(VA, 7, 4)) If i = 2 And Jours > 31 Then VA = masque: i = 0: MsgBox "Mauvais jour :-)" If i = 4 And Mois > 12 Then VA = Mid(VA, 1, 2) & Mid(masque, limite): i = 2: MsgBox "Mauvais mois :-)" If IsNumeric(Right(VA, 1)) And (An < MinAn Or An > MaxAn) Then VA = Mid(VA, 1, 6) & Mid(masque, i): i = 4: MsgBox "Mauvaise année :-)" ElseIf IsNumeric(Right(VA, 1)) Then D = An & "/" & Mois & "/" & "01" NBJ = Day(DateSerial(Year(D), Month(D) + 1, 1) - 1) End If If IsNumeric(Right(VA, 1)) And Jours > NBJ Then VA = masque: i = 0: MsgBox "Encore un mauvais jour :-)" TextBox2.Text = Mid(VA, 1, 10) TextBox2.SelStart = MaskArr(i) - 1 TextBox2.SelLength = 1 TextBox2.SetFocus Exit Sub End Sub
Bonjour Ryu,
Bonne idée que d'utiliser un autre événement que KeyDown.
Tu as vu, je suis indulgent ;)
Mais...
Il manque les déclarations de variables suivantes :
Tu n'utilises qu'un unique format de date. (Bon ça c'est pas le plus important en fait)Code:Dim MASQUE As String, n As Long, I As Long, limite As Long
On peut saisir allègrement :
00/02/2019
Et ça, c'est plus embêtant déjà.
Allez j'ose une dernière remarque...
Ton contrôle en cours de saisie devient, finalement, quasiment un contrôle de fin de saisie.
Notamment pour certaines dates.
Essaie :
31/02/2019.
Ton code :
> ne s'en aperçoit qu'à la fin de la saisie,
> efface tout en précisant : "encore un mauvais jour"
Ben non. En fait, ça peut être le mois qui est faux...
Bon courage, cet exercice est tout sauf simple.
D'ailleurs Pierre le dit :
Ce que je penses bientôt pouvoir démentir, au passage.Citation:
Les élucubrations de code pour contrôler en cours de saisie seront inévitablement battues en brèche lors des tests.
A suivre...
Merci Franck pour tes remarques :plusser: ;)
Salut
@Patrick : c'est le nombre d'affichages de la discussion qui m'a interpellé.
Je pense que beaucoup de lecteurs sont intéressés par la simple question : «comment saisir une date ?»*
Je n'ai donc pas tenu compte de ton cahier des charges** (tu t'en es déjà occupé ;)) en fournissant une réponse non pas réservée au seul demandeur mais à toute personne qui pourrait vouloir une réponse à la question posée ci-dessus.
Je te remercie d'avoir consulté mon programme. Mon souci premier était de détailler les étapes de mon raisonnement pour les débutants, mais je t'avoue n'avoir pas pensé à ta simplification de macro (que je vais adopter).
* avec les problèmes de portabilité des calendriers d'EXCEL
**à mon avis, cet exercice n'est utile qu'en tant que plaisir personnel :pc:.
Coucou Jacques,
Je confirme :mrgreen:
Amitié
re
bonsoir a tous
@ryu: et oui tu vois l'execice n'est pas aussi facile qu'on peut le croire a depart on s'apercoit vite que le principe de 30/31 01/12 est loin loin d'etre suffisant
le formatage dynamique de textbox est un sujet que j'aime bien c'est sportif
et oui j'en convient c'est le sport qui est interessant
malgré toute les erreurs possible avec ton code je salut quand meme le fait de le faire avec le change
cela dit en terme de navigation clavier tu es chocolat les touche back et suppr et fleche ou taB ou enter c'est mort
Re Franck,
Maintenant que j'ai du temps je peux te répondre plus amplement …
Pour cela il faut utiliser des api windows il me semble, et moi je suis sur Mac, de cette manière je peux alors l'utiliser aussi bien sur Mac que sur PC
(en plus la saisie dans le masque est quasi automatique, à moins que j'ai loupé d'autres choses …)
PS : J'avais suivi ton sujet sur le textbox avec le ".5", j'avais trouvé une solution que je n'avais pas posté, car ton post était arrivé à terme avec une solution qui te convenait …
(Comme a mon habitude j'évitait d'étudier les codes afin de partir de 0)
Le voilà, on s'est jamais peut être que cela pourrait te servir/t'intéressé (ou pas ) ;) :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13 Private Sub TextBox1_Change() ' OK Static VA As String, VB$ If TextBox1.Text = "" Then VA = "": Exit Sub VB = TextBox1.Text If Right(VB, 1) = "[0-9]" Then TextBox1.Text = Val(VB) ElseIf (VB Like "*[0-9]" & "[,.]" Or VB = "0") And Len(VA) < Len(VB) Then TextBox1.Text = Val(VB) & ".5" Else TextBox1.Text = IIf(VB Like "*.5*", Int(Val(VB)) & ".5", Val(VB)) End If If TextBox1.Text = "0" Then VA = "": TextBox1.Text = "" Else VA = TextBox1.Text End Sub
- En effet j'aurais du vérifier pour les déclarations avant de l'envoyer
- C'est clair car avant de s'attaquer à tous les formats il faut déjà en faire un correctement ;)
Oui honte à moi :oops: je l'ai zappé (en plus c'était signalé à Patrick) , je réglais un pb autre sur mon code en heure de déj. avant de l'envoyé (bon les 00 sont vite réglés dans les If en ajoutant la condition)
En effet, c'est voulu (après peut être que ma logique est mal adapté), mais je l'ai fait de tel manière à ce que l'utilisateur se responsabilise et soit attentif dans ce qu'il écris.
au bout de plusieurs fois si il se trompe, il sera plus attentif …
La façon d'écrire la date dans se format est la plus commune en France; les vérifications que j'avais prévu :
Pour le 31/02/2019 il est sur que le jour sera faux, mais comment fais t'on pour savoir si le mois est faux si on reste entre 1 et 12 ? si l'utilisateur le voit pas ça ne changera rienCitation:
- vérification du jour <= 31 + maintenant Jours > 0
- vérification du mois <=12 + maintenant mois > 0
- vérification de l'année à + ou - 10 ans
- puis vérification de nouveau du jour par rapport au nb de jours dans le mois
C'est vrai que l'on pourrait ne faire que corriger que : le jour, le mois ou l'année
Le plus Logique serait d'avoir :
- l'année (cause mois de février)
- puis le mois (peut se régler autrement puisque l'on connait les 11 mois à 30 ou 31 => simplification); j'aime bien quand même Day(DateSerial… mais c'est surement un calcul de plus inutile quand on a des constantes …
- puis le jour
Avec cette base j'ai déjà de quoi amélioré, merci encore Franck :ccool:
@Patrick
ça ne m'a pas gêné, mais cela dit tout peut s'améliorer, à condition que je ne passe pas par des api windows, des ActiveX, etc … appartenant au PCCitation:
cela dit en terme de navigation clavier tu es chocolat les touche back et suppr et fleche ou taB ou enter c'est mort
Comme d'hab j'essaie toujours de faire en sorte que mes codes marche sur Mac/PC ;)
Edit : le code corrigé sur les 00 avant de trouver une meilleure version
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 Private Sub Textbox2_Change() Static VA As String Dim masque As String, MaskArr(), MinAn As Integer, MaxAn As Integer, limite As Long, Jours As Integer, Mois As Integer, An As Integer, NBJ As Integer, D As String, i As Long MinAn = Year(Now) - 10: MaxAn = Year(Now) + 10 MaskArr = Array(1, 2, 4, 5, 7, 8, 9, 10) masque = "__/__/____" If TextBox2.Text = "" Then VA = masque: TextBox2 = VA TextBox2.Text = Replace(Replace(TextBox2.Text, Mid(TextBox2.Text, 3, 1), "/", 1, 1), Mid(TextBox2.Text, 6, 1), "/", 1, 1) If TextBox2.Text <> masque Then For i = LBound(MaskArr) To UBound(MaskArr) If Not IsNumeric(Mid(TextBox2.Text, MaskArr(i), 1)) Then limite = MaskArr(i) VA = Left(TextBox2.Text, limite - 1) & Mid(masque, limite) Exit For End If If i = 7 Then VA = TextBox2.Text: Exit For Next End If Jours = Val(Mid(VA, 1, 2)): Mois = Val(Mid(VA, 4, 2)): An = Val(Mid(VA, 7, 4)) If i = 2 And (Jours < 1 Or Jours > 31) Then VA = masque: i = 0: MsgBox "Mauvais jour :-)" If i = 4 And (Mois < 1 Or Mois > 12) Then VA = Mid(VA, 1, 2) & Mid(masque, limite): i = 2: MsgBox "Mauvais mois :-)" If IsNumeric(Right(VA, 1)) And (An < MinAn Or An > MaxAn) Then VA = Mid(VA, 1, 6) & Mid(masque, i): i = 4: MsgBox "Mauvaise année :-)" ElseIf IsNumeric(Right(VA, 1)) Then D = An & "/" & Mois & "/" & "01" NBJ = Day(DateSerial(Year(D), Month(D) + 1, 1) - 1) End If If IsNumeric(Right(VA, 1)) And Jours > NBJ Then VA = masque: i = 0: MsgBox "Encore un mauvais jour :-)" TextBox2.Text = Mid(VA, 1, 10) TextBox2.SelStart = MaskArr(i) - 1 TextBox2.SelLength = 1 TextBox2.SetFocus Exit Sub End Sub
re
en fait ryu en regardant tes codes je me revois deux ans en arriere avec des if et iif et else a tout va
une chose est sur c'est que pour maitriser toutes les erreurs possibles ca devient vite une usine a gaz et une torture a deboguer je parle en connaissance de cause :mouarf: avec ce principe j'ai fait des codes qui me font faire encore des cauchemards:ptdr::ptdr:
et surtout avec l'evenement change ca s'arrete la (pas de navigation dans les parties pas de back ou suppr maitrisé en gardant le mask etc.....
alors qu'avec l'evenement keydown du textbox
on fait quoi ?
on peut maitriser le keycode ,le selstart ,le sellength,etc
le principe c'est de metre en corrélation le selstart et la touche tapée en fonction de 3 position memorisée et cela pour n'importe quel format pour l'edition et réédition
quand au autres touche avec ma toute derniere methode 2 lignes de code pour naviguer pour chaque touches de navigation (prend le code j'ai pas corrigé dans le fichier )
voir ici
ca reduit le moulin de 80%
Bonjour Patrick,
Concernant ton fichier je l'avais téléchargé mais si je me rappelle bien il y a des contrôles activeX, et donc pas utilisable pour moi sur Mac, c'est pour cela que j'ai cru que les keydown etaient propre à Windows,
mais en essayant le code, j'ai vu que cela marché, il faut que je regarde cela de plus près sur les keydown etc…
PS : MS n'a toujours pas remis la possibilité de créer des useform sur Excel Mac 2016 manuellement, du coup j'ai du repasser sur Excel 2011
Je vais revoir mon code …
@Pijaku, je suis curieux de voir ce que tu prépares … :
Citation:
Ce que je penses bientôt pouvoir démentir, au passage.
Bonjour tout le monde,
Par plaisir personnel, pour le sport, j'aurais été assez d'accord avec vous il y a deux ans.
Mais depuis, on nous a livré, au travail, un nouveau progiciel de gestion/comptabilité comportant X TextBox équipés de masques de saisie. Certains possèdent un contrôle de saisie en cours de saisie (dates, iban, etc) d'autres n'autorisent la saisie que de chiffres, que de caractères alphanumériques, etc, d'autres n'ont aucun contrôle de saisie, juste un masque.
Ces 2 aspects, le masque et la possibilité de contrôle en cours (ou en fin) de saisie, rendent la vie de l'utilisateur extrêmement simple.
Précision: ce logiciel n'est pas codé en VBA hein ;)
@Ryu : je ne suis pas sur de vouloir présenter mon travail à ce sujet :
1- il est loin d'être abouti,
2- je ne maîtrise que très peu les tests à réaliser,
3- au vu des avis lus ici, je ne sais pas si cela pourra s'avérer intéressant.
Quoiqu'il en soit, j'y travaille.
A ++
Franck
Salut.
Pour info, Access propose un masque de saisie pour les données de type date. Ce masque de saisie permet de saisir une date aberrante durant la saisie et ne valide qu'après saisie. Autrement dit, l'utilisateur est guidé pour une saisie syntaxique correcte, mais la validité de la saisie n'est vérifiée qu'après coup. Je suppose que les développeurs d'Access ont voulu ainsi éviter l'usine à gaz qui ne manquait pas de se profiler.
Quoi qu'il en soit, il me semble délicat de vérifier la bonne saisie d'une date durant la saisie, puisque l'on va devoir partir du principe que la partie saisie est correcte pour valider la suite, ce qui est un postulat erroné. Ainsi, si on saisit 29/02/, il va falloir partir du principe que la saisie est correcte pour empêcher de saisir une année non bissextile, alors que c'est peut-être le 29 qui est erroné, ou le 02. Il faut donc permettre le retour en arrière sauf à brider l'utilisateur et à lui interdire, par exemple, le retour en arrière (manipulation intuitive et attendue par l'utilisateur). C'est pourquoi, outre le sport que cela peut représenter, il me paraît inutile, et probablement impossible sans usine à gaz, de tenter de réaliser cela. Il me semble plus raisonnable de se contenter de valider ou d'invalider la saisie après coup, éventuellement en contrôlant la saisie selon un masque de saisie (syntaxe) mais sans valider au fur et à mesure... Et n'a pas encore été envisagé ici le copier/coller d'une donnée.
C'était mon grain de sel, nonobstant qu'il peut être très amusant et sportif d'essayer quand même (en dehors d'un objectif de rentabilité et d'utilisation professionnelle de ce qui sera produit) ;)
Bonjour Pierre,
Selon moi un contrôle en cours de saisie n'est là que pour vérifier que l'utilisateur ne saisit pas :
- de jours inférieurs à 01 et superieurs à 31,
- de mois non compris entre 01 et 12,
- d'années non prises en compte par l'application.
Le reste, (les 31 et autres 29/02) sont des exceptions (8 dates par an!).
Ils peuvent être traités:
- pour les 31 (ex : 31/04) dès la saisie du mois et ou du jour selon le format de date (donc pour le format aaaa/mm/jj en fin de saisie),
- pour les 29/02 en fin de saisie.
Toujours selon moi, il ne faut pas bloquer l'utilisateur et le laisser, à tout instant, naviguer dans son TextBox. Le seul blocage à lui opposer est la sortie si saisie invalide.
Le développeur doit également penser à:
- la saisie d'une valeur par le code,
- le copié collé,
- la sortie par la souris.
Pour ces 3 cas, il existe, pour le contrôle TextBox, un événement adéquat.
A partir de cette base, je ne vois pas pourquoi ce principe ne saurait être appliqué à une appli pro...
Ma question existentielle sur ce sujet est la suivante :
Comment doit réagir le code en cas de mauvaise saisie?
Doit-on :
- supprimer la dernière saisie qui a engendré l'erreur?
- afficher un MsgBox?
- sélectionner la saisie en erreur?
- effacer tout?
- autre solution?
Le progiciel dont je parlais plus haut supprime le dernier "segment" de date saisit. Si le mois engendre une erreur (ex 31/04) il le supprime (résultat: 31/__/____). Si c'est le jour (ex 33/__/____) il le supprime (résultat : __/__/____).
Vos avis éclairés à cette question m'aiderait beaucoup.
Mais je crois bien qu'il n'y a pas de solution universelle qui plaira à tous...
A++
Franck