non jacques reli j'ai dis quand je tape "0,"
j'ai resolu le soucis a ajoutant la ligne en gras dans ton code
autrement dis si j'ai "0.5" et que je fait un back je vide le textbox
non jacques reli j'ai dis quand je tape "0,"
j'ai resolu le soucis a ajoutant la ligne en gras dans ton code
autrement dis si j'ai "0.5" et que je fait un back je vide le textbox
mes fichiers dans les contributions:
mail avec CDO en vba et mail avec CDO en vbs dans un HTA
survol des bouton dans userform
prendre un cliché d'un range
si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
et n'oublie pas de voter
je pense avoir corrigé ces points dans ma version et ajouté le presse papier
pour le point c'est simple tu remplace 48 par 46
seul le soucis de la touche 46 demeure sauf si j'utilise des variables de memo (ce que je cherche a eviter)
@jacques tu a vu pour le zero? dans ta version
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 TextBox1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single) With CreateObject("htmlfile").parentwindow.clipboardData.clearData("Text"): End With End Sub ' ' ' ' Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger) If Len(TextBox1.Value) > 0 And TextBox1.SelStart > 0 Then If Mid(TextBox1.Value, TextBox1.SelStart) = ".5" Then KeyAscii = 0: Exit Sub End If If Right(TextBox1, 2) = ".5" And TextBox1.SelStart = Len(TextBox1) Then KeyAscii = 0: Exit Sub If KeyAscii < 46 Or KeyAscii > 57 Then If KeyAscii = 44 Then KeyAscii = IIf(InStr(TextBox1, ".") < 1, 46, 0) Else KeyAscii = 0 End If If Left(TextBox1.Value, 1) = "." Then KeyAscii = 0 'le point ne peut pas etre le premier caractere tapé End Sub ' ' ' Private Sub TextBox1_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) 'MsgBox KeyCode If KeyCode <> 8 And KeyCode <> 46 And Right(TextBox1, 2) = ".5" Then KeyCode = 0 If KeyCode = 188 Or KeyCode = 110 Then TextBox1 = TextBox1 & "5" If KeyCode = 8 Then If Right(TextBox1, 1) = "." Then TextBox1 = Replace(TextBox1, ".", "") If TextBox1.SelStart + 1 = Len(TextBox1) Then TextBox1 = Left(TextBox1, TextBox1.SelStart) End If If KeyCode = 46 Then If TextBox1.SelStart + 1 = Len(TextBox1) Then TextBox1 = Left(TextBox1, TextBox1.SelStart) End If End Sub
mes fichiers dans les contributions:
mail avec CDO en vba et mail avec CDO en vbs dans un HTA
survol des bouton dans userform
prendre un cliché d'un range
si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
et n'oublie pas de voter
@jacques
dans ta version aussi si l'utilisateur supprime le "5" du ".5" avec suppr en placant le curseur avant le "5" il peut retaper n'inporte quel chiffre ensuite
mes fichiers dans les contributions:
mail avec CDO en vba et mail avec CDO en vbs dans un HTA
survol des bouton dans userform
prendre un cliché d'un range
si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
et n'oublie pas de voter
Nouvelle petite modif (notée MODIF 3) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 Option Explicit Private Sub TextBox1_Change() TextBox1.Text = VerifTextBox(TextBox1.Text) End Sub Private Function VerifTextBox(Texte) As String Static toto As String Dim c As String c = Replace(Texte, ",", ".") If InStr(c, ".") = 0 And InStr(toto, ".") > 0 Then VerifTextBox = Int(Val(toto)): toto = VerifTextBox: Exit Function End If If c = "" Then toto = "": Exit Function If Right(c, 1) = "." Then If Not toto Like "*.5" Then c = c & "5" ElseIf c Like "*.5." Then 'MODIF 1 c = Mid(c, 1, Len(c) - 1) Else c = Int(Val(toto)) End If End If If Len(CStr(Val(c))) = Len(c) And c Like "[0-9]*" And Not c Like ("*.##*") Then VerifTextBox = c toto = VerifTextBox ElseIf Left(c, 1) = "0" Then 'MODIF 2 If InStr(c, ".") > 0 Then c = Left(c, InStr(c, ".") + 1) 'MODIF 3 VerifTextBox = CStr(Val(c)) toto = VerifTextBox Else VerifTextBox = toto End If End Function
Cordialement,
Franck
C'est pas Jacques hein depuis tout à l'heure, c'est Franck...
Nouvelle modif (notée MODIF 4) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
37 Option Explicit Private Sub TextBox1_Change() TextBox1.Text = VerifTextBox(TextBox1.Text) End Sub Private Function VerifTextBox(Texte) As String Static toto As String Dim c As String c = Replace(Texte, ",", ".") If InStr(c, ".") = 0 And InStr(toto, ".") > 0 Then VerifTextBox = Int(Val(toto)) toto = VerifTextBox Exit Function End If If c = "" Then toto = "": Exit Function If Right(c, 1) = "." Then If Not toto Like "*.5" Then c = c & "5" ElseIf c Like "*.5." Then c = Mid(c, 1, Len(c) - 1) Else c = Int(Val(toto)) End If End If If Len(CStr(Val(c))) = Len(c) And c Like "[0-9]*" And Not c Like ("*.##*") Then VerifTextBox = c toto = VerifTextBox ElseIf Left(c, 1) = "0" Then If InStr(c, ".") > 0 Then c = Left(c, InStr(c, ".")) & "5" ' MODIF 4 VerifTextBox = CStr(Val(c)) toto = VerifTextBox Else VerifTextBox = toto End If End Function
Cordialement,
Franck
@Franck je travaille avec la version de jacques dans l'evenement
je n'ai pas encore testé la tienne dans une fonction
le probleme du zero est résolu puisque le textbox est vidé donc on repart a zero en terme d'evaluation de toto et de C et textbox
je cherche toujour comment faire sans me servir du tag ou d'une variable dans ma version pour remedier a touche 46 sur (len -2) avec ou sans decimale
en tout cas interessant cet discussion
mes fichiers dans les contributions:
mail avec CDO en vba et mail avec CDO en vbs dans un HTA
survol des bouton dans userform
prendre un cliché d'un range
si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
et n'oublie pas de voter
Coucou (de retour de la pêche)
J'étais pressé tout-à-l'heure (la pêche, c'est sacré) et n'ai pas testé --->> et il y avait une faille.
La voilà réparée et plus rien ne devrait maintenant manquer --->>
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 Private Sub TextBox1_Change() Static toto As String Dim c As String c = Replace(TextBox1.Text, ",", ".") If InStr(c, ".") = 0 And InStr(toto, ".") > 0 Then TextBox1.Text = Int(Val(toto)): toto = TextBox1.Text: Exit Sub End If If c = "" Then toto = "": Exit Sub If Right(c, 1) = "." Then If Not toto Like "*.5" Then c = c & "5" Else c = CStr(Int(Val(toto))) End If End If If IsNumeric(Replace(c, ".", "")) And Not c Like ("*.##*") Then TextBox1.Text = Replace(Val(c), ",", ".") Else TextBox1.Text = toto End If toto = TextBox1.Text End Sub
Je n'accepte pas de demande d' "amitié" individuelle. Tout développeur est pour moi un ami.
Je n'ouvre AUCUN classeur tiers (avec ou sans macro ******). Ne m'en proposez donc pas .
****** : Non, non ... un classeur .xlsx ne "peut" par exemple et entre autres pas contenir un activex (de surcroît invisible) , "bien sûr" ...
Il est illusoire de penser que l'on saurait exprimer valablement et précisément en un langage (rigide) de développement ce que l'on peine à exprimer dans le langage naturel, bien plus souple.
Re-coucou
Plus je regarde mon propre code, plus je me dis que je peux faire encore mieux et plus court.
Allez, je vais essayer (et suis déjà certain d'y parvenir)
A plus, donc.
Je n'accepte pas de demande d' "amitié" individuelle. Tout développeur est pour moi un ami.
Je n'ouvre AUCUN classeur tiers (avec ou sans macro ******). Ne m'en proposez donc pas .
****** : Non, non ... un classeur .xlsx ne "peut" par exemple et entre autres pas contenir un activex (de surcroît invisible) , "bien sûr" ...
Il est illusoire de penser que l'on saurait exprimer valablement et précisément en un langage (rigide) de développement ce que l'on peine à exprimer dans le langage naturel, bien plus souple.
Ben voilà (c'est bien ce que je pensais) :
Voilà encore une autre méthode (toujours sur un seul évènement), bien plus courte : --->>
EDIT : et si le temps m'en laisse le temps et qu'il fait mauvais temps, je m'amuserai à en faire une troisième encore (histoire de ne pas faire ce que je déteste : copier, y compris sur moi-même).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 Private Sub TextBox1_Change() Static toto As String, c As String c = Replace(TextBox1.Text, ",", ".") If c = "" Then toto = c: Exit Sub If Right(c, 1) = "." Then TextBox1.Text = IIf(InStr(toto, ".") = 0, c & "5", Int(Val(toto))) toto = TextBox1.Text: Exit Sub End If pos = InStr(c, ".") Select Case pos Case Is > 0: flt = String(pos - 1, "#") & ".5" Case Else: flt = String(Len(c), "#") End Select TextBox1.Text = IIf(c Like flt, Replace(CStr(Val(c)), ",", "."), toto) toto = TextBox1.Text End Sub
Je n'accepte pas de demande d' "amitié" individuelle. Tout développeur est pour moi un ami.
Je n'ouvre AUCUN classeur tiers (avec ou sans macro ******). Ne m'en proposez donc pas .
****** : Non, non ... un classeur .xlsx ne "peut" par exemple et entre autres pas contenir un activex (de surcroît invisible) , "bien sûr" ...
Il est illusoire de penser que l'on saurait exprimer valablement et précisément en un langage (rigide) de développement ce que l'on peine à exprimer dans le langage naturel, bien plus souple.
Bonjour à tous,
Merci Jacques, une fois de plus tu mérites ton lot de ...
J'ai toutefois modifié ta solution pour y faire :
> 1 ajout : cas de l'effacement du point par la touche Suppr ==> j'enlève le 5 qui suivait
> 1 ajout potentiel : si l'utilisateur saisi un point ou une virgule après le .5, il efface le .5.
J'ai traité ce cas en commentaires car cette méthode de suppression me plait.
C'est plus un avantage qu'un inconvénient; quand l'utilisateur se sera "fait avoir" plusieurs fois, il considérera cette méthode d'effacement judicieuse.
Mais c'est parfait!
Merci encore.
ps : la "sécurité" supplémentaire, dans le code en commentaire, est-elle utile?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
37
38
39 Option Explicit Private Sub TextBox1_Change() TextBox1.Text = Verif(TextBox1.Text) End Sub Private Function Verif(T As String) As String Static toto As String, c As String, pos As Long, flt As String c = Replace(T, ",", ".") If c = "" Then toto = c: Exit Function If Right(c, 1) = "." Then 'cas si second point ajouté après .5 ==> évite l'effacement de .5 dans ce cas 'au final je ne traite pas ce cas car cela représente un "avantage" 'If InStr(toto, ".") > 0 Then '---- AJOUT POTENTIEL ' Verif = Left(c, Len(c) - 1) ' toto = Verif ' Exit Function 'Else Verif = IIf(InStr(toto, ".") = 0, c & "5", Int(Val(toto))) toto = Verif: Exit Function 'End If End If pos = InStr(c, ".") Select Case pos Case Is > 0: flt = String(pos - 1, "#") & ".5" Case Else 'cas de l'effacement du point par la touche Suppr ==> supprime également le 5 qui suivait ce point 'ici toto contient un "." et c n'en contient pas. flt est like "*#.5" 'comme c Not Like flt, suffit de changer toto..... If InStr(toto, ".") > 0 Then '---- AJOUT toto = Int(Val(toto)) 'flt = "#.5" 'sécurité supplémentaire, utile????? Else flt = String(Len(c), "#") End If End Select Verif = IIf(c Like flt, Replace(CStr(Val(c)), ",", "."), toto) toto = Verif End Function
Cordialement,
Franck
Bonjour
J'avais déjà mis à Jacques, j'en rajoute un pout toi pijaku , pour la petite modif que je trouve sympa !
Petite question qd même :
N'y a t-il pas une durée maxi ? genre 8 ou 12 ou 24 ou autres … ??Il s'agit en fait de durées, avec un minimum d'une demi-heure.
Ryu
Cordialement
Ryu
La connaissance s’acquiert par l’expérience, tout le reste n’est que de l’information. – Albert Einstein
Pensez à la Balise [ CODE][/CODE ] - à utiliser via le bouton # => Exemple
Une fois votre problème solutionné pensez à mettre en n'oubliant pas d'indiquer qu'elle est la solution finale choisie
Chose promise, chose due --->>
voila pour conforter l'idée que plusieurs chemins mènent à Rome -->>
Nous utilisons ici la méthode des videurs (boîtes de nuit, etc ...). Elle est la même (en moins sévère car en admet plusieurs, que celle de l'admission des spermatozoïdes au "paradis" )
J'ai utilisé ici une procédure couic, uniquement pour ne pas me répéter dans les lignes qui "éjectent". Il va de soi que l'on peut la supprimer, si l'on préfère, en ajoutant ces actions avant chaque "exit sub"
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 Private Sub TextBox1_Change() Static toto As String, c As String, TB As MSForms.TextBox Set TB = TextBox1 c = Replace(TB.Text, ",", ".") If c = "." Or c = "0" Then TB.Text = "0.5": Exit Sub If c Like "0#" Then c = Mid(c, 2): couic TB, c: Exit Sub If c Like "*.#?" Then couic TB, toto: Exit Sub If c Like "*." And toto Like "*.5" Then couic TB, Int(Val(toto)): Exit Sub If InStr(Replace(TB, ".", "", 1, 1), ".") > 0 Then couic TB, toto: Exit Sub If Right(c, 1) = "." Then c = c & "5": couic TB, c: Exit Sub If Replace(c, ".", "") Like "*[!0-9]*" Then couic TB, toto: Exit Sub If TB.Text Like "0#.*" Then TB.Text = Mid(TB.Text, 2) toto = TB.Text End Sub Private Sub couic(TB As MSForms.TextBox, t As String) If t Like ("0*") Then t = Mid(t, 2) TB.Text = t t = TB.Text End Sub
Ce qu'il faut retenir (ce qui est finalement le plus important dans toute cette discussion), c'est qu'il est toujours plus amusant (souvent plus positif) de ne pas "réciter"
Je n'accepte pas de demande d' "amitié" individuelle. Tout développeur est pour moi un ami.
Je n'ouvre AUCUN classeur tiers (avec ou sans macro ******). Ne m'en proposez donc pas .
****** : Non, non ... un classeur .xlsx ne "peut" par exemple et entre autres pas contenir un activex (de surcroît invisible) , "bien sûr" ...
Il est illusoire de penser que l'on saurait exprimer valablement et précisément en un langage (rigide) de développement ce que l'on peine à exprimer dans le langage naturel, bien plus souple.
Bonjour Jacques,
Merci pour ce nouveau code.
Tu n'as pas tord.
Mais j'ai tout de même appris autre chose dans cette discussion.
C'est que, grâce à une variable Static dans une procédure événementielle, on peut aisément (et agilement) se passer de l'utilisation de la propriété tag d'un contrôle.
Et ça n'est pas rien non plus.
Merci encore.
Amicalement,
Franck
Cordialement,
Franck
Bonjour Franck
Je suis certain, te connaissant bien, de ce que tu penses déjà (et tu n'as pas tord) à une utilisation beaucoup plus fine -->> propriété tag ainsi restée disponible et utilisée alors pour définir le type de contrôle de saisie (nombre, date, format, etc ...) --->> et une seule procédure dans un module standard pour traiter en fonction du tag.
EDIT : pour être plus clair : on pourrait (dans la cas ici traité) utiliser n'importe quelle variable "générale" ou "publique" à la place d'une variable "static". Mais si plusieurs textboxes traitées, il faudrait alors une variable de l'espèce pour chacune d'entre elles, alors qu'une variable static reste, elle, "accrochée" à SA textbox et qu'elle peut donc porter le même nom dans une seule procédure publique, quelle que soit la textbox, sans se mélanger les pinceaux. Il suffit alors, dans l'évènement Change de chacune des textboxes à traiter, d'appeler (si sa propriété tag contient quelque chose), la procédure publique en lui passant en paramètres :
- l'objet (la textbox traitée) par valeur
- le contenu de son tag, par valeur
- la variable static par référence
Je n'accepte pas de demande d' "amitié" individuelle. Tout développeur est pour moi un ami.
Je n'ouvre AUCUN classeur tiers (avec ou sans macro ******). Ne m'en proposez donc pas .
****** : Non, non ... un classeur .xlsx ne "peut" par exemple et entre autres pas contenir un activex (de surcroît invisible) , "bien sûr" ...
Il est illusoire de penser que l'on saurait exprimer valablement et précisément en un langage (rigide) de développement ce que l'on peine à exprimer dans le langage naturel, bien plus souple.
Bonjour Jacques,
Je ne suis pas fan de ce genre de procédé.et une seule procédure dans un module standard pour traiter en fonction du tag.
Je préfères avoir une procédure bien distincte pour gérer la saisie d'un type de textbox.
Chacun son goût en la matière, cela importe finalement peu.
Néanmoins, tu affirmes qu'une procédure Publique (dans un module donc?), si l'on passe une variable Static ByRef, celle-ci est modifiée dans l'Userform.
Si j'ai bien compris hein...
Et bien non.
En code, pour être clair :
Pré-requis : un userform avec dessus trois textbox (TextBox1, TextBox2, TextBox3)
Dans le module de l'userform :
Dans le module Module1 :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 Private Sub TextBox1_Change() Static MaDate As String Application.Run "Module1." & TextBox1.Tag, MaDate MsgBox MaDate End Sub Private Sub UserForm_Activate() TextBox1.Tag = "FuncDate" End Sub
MsgBox MaDate est toujours vide...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 Public Function FuncDate(ByRef D As String) D = D & " P" MsgBox "Fonction de vérification de date " & D End Function
Certainement dû, à mon avis, à son appel par Application.Run.*****
J'ai testé donc d'autres méthodes, et on a le choix.
Soit de placer les fonctions de vérif directement dans le module de l'userform, soit de créer un module de classe nommé "verifTB".
Les codes deviennent donc :
Code de l'Userform (j'y ai placé la fonction de vérification du Textbox 2 Function FuncNumeric):
Code de la classe verifTB :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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 Option Explicit Dim MyClassTb As New verifTB Private Sub TextBox1_Change() Static MaDate As String CallByName MyClassTb, TextBox1.Tag, VbMethod, MaDate End Sub Private Sub TextBox2_Change() Static MonNum As Long CallByName Me, TextBox2.Tag, VbMethod, MonNum End Sub Private Sub TextBox3_Change() Static MaDuree As String CallByName MyClassTb, TextBox3.Tag, VbMethod, MaDuree End Sub Private Sub UserForm_Activate() TextBox1.Tag = "FuncDate" TextBox2.Tag = "FuncNumeric" TextBox3.Tag = "FuncDuree" End Sub Public Function FuncNumeric(ByRef N As Long) As Long N = N + 10 MsgBox "Fonction de vérification numérique " & N End Function
Et là, ça fonctionne très bien.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 Option Explicit Public Function FuncDate(ByRef D As String) D = D & " P" MsgBox "Fonction de vérification de date " & D End Function Public Function FuncDuree(ByRef Du As String) As String Du = Du & "A" MsgBox "Fonction de vérification de durée " & Du End Function
***** EDIT :
c'est bien dû à Run.
Avec un Call cela fonctionne à merveille.
Par contre, là, tu as raison, il convient d'utiliser une unique fonction et d'y passer le TextBox (et donc son Tag suivra...) et la variable Static.
Cordialement,
Franck
Pourquoi utiliser run ? ou call, d'ailleurs ?
Regarde
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 Private Sub TextBox1_Change() Static toto As String regarde TextBox1, toto MsgBox toto End Sub Private Sub TextBox2_Change() Static toto As String regarde TextBox2, toto MsgBox toto End Sub Private Sub regarde(ByVal Tb As MSForms.TextBox, ByRef X As String) X = "coucou dans" & Tb.Name End Sub
Je n'accepte pas de demande d' "amitié" individuelle. Tout développeur est pour moi un ami.
Je n'ouvre AUCUN classeur tiers (avec ou sans macro ******). Ne m'en proposez donc pas .
****** : Non, non ... un classeur .xlsx ne "peut" par exemple et entre autres pas contenir un activex (de surcroît invisible) , "bien sûr" ...
Il est illusoire de penser que l'on saurait exprimer valablement et précisément en un langage (rigide) de développement ce que l'on peine à exprimer dans le langage naturel, bien plus souple.
Aucun intérêt, je suis d'accord.Pourquoi utiliser run ?
C'est encore une histoire de goût.ou call, d'ailleurs ?
Lorsque j'ai des gros projets à réaliser, et que je sais que j'aurais de la maintenance à faire dessus, j'aime préciser Call "NomDuModule"."LaMacro"
Lorsque j'ai un projet avec x modules, x modules de classe et 2-3 userforms, je trouve cette façon de procéder plus claire lorsque, un an après, tu dois revenir dessus.
Mais c'est juste une histoire de goût.
Idem, je préfères placer les méthodes de mes userforms dans un module standard affecté à cet userform (nommé pour l'occasion : ModNomdeluserform).
Pourquoi?
Simplement pour laisser toute la place, dans le module de l'Userform, aux événements.
Ce n'est pas forcément la meilleure façon de procéder car, en cas d'export, on est obligé d'exporter deux modules, mais ça me clarifie l'esprit
Cordialement,
Franck
Cordialement,
Patrice
Personne ne peut détenir tout le savoir, c'est pour ça qu'on le partage.
Pour dire merci, cliquer sur et quand la discussion est finie, penser à cliquer sur
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager