Comment avoir la classe avec des TextBox numériques ?
TextBoxNum
Forcer la saisie d'une valeur numérique dans une TextBox.
Il peut être très utile de mettre des zones de texte ne pouvant prendre que des valeurs numériques dans nos formulaires (montant de facture, pourcentage à appliquer, …).
Malheureusement le control TextBox ne possède pas de paramètre permettant cela.
Alors nous allons créer notre propre TextBoxNum !
Une première solution
Une solution qui est souvent employer est d’utiliser l’évènement KeyPress d’une TextBox afin de contrôler la saisie que fait l’utilisateur et de la valider ou non.
Exemple :
1 2 3 4 5 6 7
| Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
If KeyAscii = 44 Then
KeyAscii = 46
ElseIf (KeyAscii < vbKey0 Or KeyAscii > vbKey9) And KeyAscii <> vbKeyBack And KeyAscii <> vbKeyDelete Then
KeyAscii = 0
End If
End Sub |
Ici lors de la saisie d’un caractère dans la zone de texte nommée TextBox1, le code Ascii du caractère est renvoyé sous forme de nombre dans la variable KeyAscii.
Dans la première partie du bloc IF KeyAscii = 44 correspond au cas où une virgule est saisie. Dans ce cas KeyAscii est remplacé par 46 qui est le point (séparateur décimal en VB).
Dans la seconde partie les caractères autres que les nombres de 0 à 9, le retour ou Suppr sont remplacés par 0 ce qui a pour effet de rien renvoyer dans le TextBox1.
L’utilisation de cette méthode nous oblige à écrire ce morceau de code autant de fois qu’il y a de TextBox devant être numérique.
Nous allons donc créer notre propre TextBoxNum.
Création d'une classe TextBoxNum et d'une classe pour la collection des TextBoxNum
Commencons par créer deux modules de classe que nous nommons TextBoxNum et TextBoxNums.
Le premier va servir à gérer l’objet TextBoxNum et le second la collection des objets TextBoxNum.
Code du module TextBoxNum :
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
Public WithEvents ZoneTextNum As MSForms.TextBox
Private mParent As TextBoxNums
Property Set Parent(ByRef objTBNs As TextBoxNums)
If objTBNs Is Nothing Then
mParent = objTBNs
End If
End Property
Property Get Parent() As TextBoxNum
Parent = mParent
End Property
Private Sub ZoneTextNum_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
If KeyAscii = 44 Then
KeyAscii = 46
ElseIf (KeyAscii < vbKey0 Or KeyAscii > vbKey9) And KeyAscii <> vbKeyBack And KeyAscii <> vbKeyDelete Then
KeyAscii = 0
End If
End Sub
Private Sub ZoneTextNum_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
If (Shift = 2 And KeyCode = 86) Or (Shift = 1 And KeyCode = 45) Then
KeyCode = 0
End If
End Sub |
Code du module TextBoxNums :
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 40 41 42 43 44 45
| Option Explicit
Private mTextBoxNums As Collection
Private iKey As Long
Private Const TypeNum = "Num"
Private Sub class_Initialize()
Set mTextBoxNums = New Collection
iKey = 0
End Sub
Private Sub class_Terminate()
If Not (mTextBoxNums Is Nothing) Then _
Set mTextBoxNums = Nothing
End Sub
Public Sub Add(ByRef objTBN As TextBoxNum)
Dim key As String
iKey = iKey + 1
key = "TextBoxNum" & iKey
mTextBoxNums.Add objTBN, key
Set objTBN.Parent = Me
Set objTBN = Nothing
End Sub
Public Function CreateTBN(ctrl As MSForms.TextBox) As TextBoxNum
Dim objTBN As TextBoxNum
Set objTBN = New TextBoxNum
Set objTBN.ZoneTextNum = ctrl
Set CreateTBN = objTBN
If Not (objTBN Is Nothing) Then _
Set objTBN = Nothing
End Function
Sub InitCollectionTBN(ByRef UF As UserForm, ByRef TBNs As TextBoxNums)
Dim ctrl As Control
With TBNs
For Each ctrl In UF.Controls
If TypeName(ctrl) = "TextBox" And ctrl.Tag = TypeNum Then _
.Add .CreateTBN(ctrl)
Next
End With
End Sub |
Je passe les explications du code des deux modules de classes car tout est déjà expliquer dans des tutoriels DVP. Vous les retrouverez en lien plus bas.
Je vais seulement m'attarder sur ce code ci :
1 2 3 4 5
| Private Sub ZoneTextNum_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
If (Shift = 2 And KeyCode = 86) Or (Shift = 1 And KeyCode = 45) Then
KeyCode = 0
End If
End Sub |
Shift = 2 correspond au fait que la touche Ctrl soit enfoncée et KeyCode = 86 correspond au fait que la touche v soit frappée. Nous détectons en fait une tentative de Ctrl + v. hors le contenu du presse-papier n'étant pas obligatoirement numérique nous décidons ici de ne rien renvoyer.
Shift = 1 And KeyCode = 45 correspond à MAJ + Inser donc même principe.
Ce bout de code peut donc être améliorer en testant le contenu du presse-papier par exemple.
Nous avons donc maintenant deux modules de classe pour gérer nos TextBox. Il ne reste plus qu’à instancier les TextBoxNum qui doivent être numérique à l’ouverture du formulaire.
Vous pouvez remarquer que dans la procédure InitCollectionTBN tous les contrôles du formulaire passé en premier paramètre sont parcourus et les TextBox qui ont la valeur Num dans leur propriété Tag sont ajoutés à la collection passée en second paramètre.
Vous devait donc indiquer Num dans la propriété Tag des TextBox devant être numériques et ajouter le code ci-dessous au code du formulaire.
1 2 3 4 5 6 7 8 9 10 11
| Option Explicit
Dim TBNs As New TextBoxNums
Private Sub UserForm_Activate()
Call TBNs.InitCollectionTBN(Me, TBNs)
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
Set TBNs = Nothing
End Sub |
Vous avez maintenant tout ce qu'il faut pour avoir vos propre TextBoxNum seulement en ajoutant Num dans la propriété Tag d'un TextBox.
C'est pas la classe ça ?
En espérant que toutes mes explications soient claires et que ce petit tuto vous soit utile
Merci d'avoir pris le temps de me lire et un surtout un grand merci à tous les membres de DVP grâce a qui ce site est une mine d'or pour ceux comme moi qui veulent apprendre
Antony
Liens utiles :
Partager