[VBA]Condition TextBox = Nombre positif

Résolu/Fermé
micaub Messages postés 32 Date d'inscription lundi 9 mars 2009 Statut Membre Dernière intervention 18 juin 2015 - 20 avril 2009 à 10:41
micaub Messages postés 32 Date d'inscription lundi 9 mars 2009 Statut Membre Dernière intervention 18 juin 2015 - 22 avril 2009 à 18:35
Bonjour à tous,

Je suis en train de créer un formulaire en VBA pour Excel. Dans ce dernier se trouve une grande quantité de Textbox dont certaines (une 20aine) ne peuvent accueillir que des nombres positifs (ce sont des longueurs en mm) ou du vide si on ne remplit pas la case.

Pour ce faire, j'ai créer ce code :

Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If IsNumeric(TextBox1.Text) = False And TextBox1.Text <> "" Then
Cancel = True
MsgBox "La valeur rentrée n'est pas pas un nombre."
ElseIf TextBox1 < 0 Then
Cancel = True
MsgBox "La valeur rentrée n'est pas un nombre positif."
End If
End Sub

Et je le duplique ensuite pour chacune de mes textbox. J'obtiens le résultat escompté, mais je trouve cette programmation lourde : j'ai du recopier 20 fois ce code dans ma macro. Quelqu'un aurait-il une idée pour optimiser ce code ou pour éviter de le recopier 20 fois, si tant est qu'il y ait une solution plus optimale (ce que je pense) ?

D'avance merci pour votre aide.

Cordialement.

MA

13 réponses

Bidouilleu_R Messages postés 1181 Date d'inscription mardi 27 mai 2008 Statut Membre Dernière intervention 12 juillet 2012 289
20 avril 2009 à 11:28
Bonjour,

j'ai rencontré lemême problème il y a quelques temps,
jse fais un scan de tous les controls puis je regarde si le nom est textbox xx
et je regarde si ce n'est pas vide ( on peut modifier )
si cela ne correspond pas on quitte la procedure puis on place le focus sur l'intrus...
bon courage.



If IK > 1 Then
For Each MyControl In Controls
If Left(MyControl.Name, 7) = "TextBox" Then ' on lit un textbox
If MyControl.Name="" then
s = Chr(10) & "Manque une valeur" & Chr(10)
suite = MsgBox(s, vbOKOnly)
Userform1.Mycontrols.SetFocus
Exit Sub
End If

End If
Next
End If
3
Bidouilleu_R Messages postés 1181 Date d'inscription mardi 27 mai 2008 Statut Membre Dernière intervention 12 juillet 2012 289
21 avril 2009 à 16:06
Le problème vient du fait que tu utilise un variant pour mycontrol2
donc il ne possède pas la propriété .caption
mycontrol2 est une variable qui contient "Lab...."
mycontrol est un objet de la classe controls.
je corrige comme suit....

For Each mycontrol In Controls
mycontrol2 = "Lab" & Mid(mycontrol.Name, 4, 100)
If Left(mycontrol.Name, 3) = "Txt" Then ' on lit un textbox
If IsNumeric(mycontrol.Text) = False And mycontrol.Text <> "" Then
s = MsgBox("Vous n'avez pas rempli la case " & mycontrol2 & " avec une valeur numérique !", vbCritical, "Erreur")
Exit Sub
mycontrol.Name.SetFocus
ElseIf mycontrol < 0 Then
s = MsgBox("La valeur " & mycontrol2 & " ne peut pas être négative !", vbCritical, "Erreur")
mycontrol.SetFocus
Exit Sub
Exit For
End If
End If
Next

et je te propose ce code ... retour sur le controle qui est en défaut.



For Each mycontrol In Controls
mycontrol2 = "Lab" & Mid(mycontrol.Name, 4, 100)
If Left(mycontrol.Name, 3) = "Txt" Then ' on lit un textbox
If IsNumeric(mycontrol.Text) = False And mycontrol.Text <> "" Then
s = MsgBox("Vous n'avez pas rempli la case " & mycontrol2 & " avec une valeur numérique !", vbCritical, "Erreur")
mycontrol.SetFocus
Exit for


ElseIf mycontrol < 0 Then
s = MsgBox("La valeur " & mycontrol2 & " ne peut pas être négative !", vbCritical, "Erreur")
mycontrol.SetFocus
mycontrol.SetFocus
Exit for

End If
End If
Next


A+
1
Bidouilleu_R Messages postés 1181 Date d'inscription mardi 27 mai 2008 Statut Membre Dernière intervention 12 juillet 2012 289
22 avril 2009 à 13:11
Je comprends le soucis...

le problème c'est que l'utilisation de la boucle for each entraine un examen des objets
dans l'ordre de création. et je ne pense pas qu'ilsoient tous créés ....label1, textbox1,label2,textbox2
Ce qui limite les possibilités.

il est possible d'utiliser mycontrol2 en tant qu'objet en écrivant

Dim mycontrol2 As Control
mais il n'aura jamais la propriété "caption" mais "value"

dim mycontrol2 as object
'...
'....

i=0
For Each mycontrol In Controls

set mycontrol2=controls.item(i)

'...
'...
i=i+1 ' incrémente le controle
next

j'aimerai te soumettre une suggestion.
lorsque la boucle for each lit un controle textbox : pourquoi lire le contenu d'un autre controle (le label)?
Ne serait-il pas judicieux de faire référence à controltiptex
ainsi il serait possible d'utiliser mycontrol.controltiptext
et dans controltiptext tu écris ce que tu veux.

sinon sans faire "d'usine à gaz" je ne vois pas
1
Utilisateur anonyme
20 avril 2009 à 11:10
VBA ne gère pas la programmation objet et donc il n'y a pas d'autre solution que de faire de la programmation procédurale. Donc il n'est pas possible de faire autrement.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Bidouilleu_R Messages postés 1181 Date d'inscription mardi 27 mai 2008 Statut Membre Dernière intervention 12 juillet 2012 289
20 avril 2009 à 12:01
la réponse post 2 m'a laissé perplexe, je viens de vérifié


on peut aussi écrire

toujours dans le bouton de validation


Private Sub Valider_Click()


' pour ecrire le contenu des textbox paramètre

For Each mycontrol In Controls
If Left(mycontrol.Name, 7) = "TextBox" Then ' on lit un textbox
If mycontrol.Value = "" Then
s = MsgBox(" vide ici dans " & mycontrol.name, vbCritical, "Erreur")
Exit For
End If

End If
Next

End Sub
0
micaub Messages postés 32 Date d'inscription lundi 9 mars 2009 Statut Membre Dernière intervention 18 juin 2015
20 avril 2009 à 12:31
Merci à vous deux pour vos réponses.

Je craignais que la programmation objet ne soit pas gérée par VBA, c'est le cas. Tant pis...

@Bidouilleu_R
Merci pour l'astuce. Je l'ai experimenté, l'adaptant à mes besoins... Ca a l'air de fonctionner, même si ça ne marche que lors de la validation du formulaire et non pas lors de la saisie des TextBox ; je vais donc combiner les 2. De plus, il va falloir que je modifie un peu le nom de mes textBox afin de différencier celles qui doivent répondre à la condition (les TextBox de longueur) et les autres qui n'ont pas à avoir de telles conditions.

Encore merci pour votre aide à vous 2 et à bientôt.

MA
0
Bidouilleu_R Messages postés 1181 Date d'inscription mardi 27 mai 2008 Statut Membre Dernière intervention 12 juillet 2012 289
20 avril 2009 à 12:55
une deuxième astuce

pour pour gagner du temps il est possible d'ajouter....
ce qui permet d'aller immédiatement sur le control en défaut


For Each mycontrol In Controls
If Left(mycontrol.Name, 7) = "TextBox" Then ' on lit un textbox
If mycontrol.Value = "" Then
s = MsgBox(" vide ici dans " & mycontrol.name, vbCritical, "Erreur")
mycontrol.setfocus
Exit For
End If

End If
Next
0
micaub Messages postés 32 Date d'inscription lundi 9 mars 2009 Statut Membre Dernière intervention 18 juin 2015
21 avril 2009 à 10:02
Merci Bidouilleu_R, le programme fonctionne bien avec ce que j'ai fait.

Seule petite optimisation que j'ai tenté d'effectuer, c'est de remplacer le nom de la textbox (un peu rébarbatif) par le caption du Label qui lui est associé. J'ai tenté une petite astuce mais je ne comprends pourquoi ça ne fonctionne pas :

For Each mycontrol In Controls
mycontrol2 = "Lab" & Mid(mycontrol.Name, 4, 100)
If Left(mycontrol.Name, 3) = "Txt" Then ' on lit un textbox
If IsNumeric(mycontrol.Text) = False And mycontrol.Text <> "" Then
s = MsgBox("Vous n'avez pas rempli la case " & mycontrol2.Caption & " avec une valeur numérique !", vbCritical, "Erreur")
Exit Sub
mycontrol.Name.SetFocus
ElseIf mycontrol < 0 Then
s = MsgBox("La valeur " & mycontrol2.Caption & " ne peut pas être négative !", vbCritical, "Erreur")
mycontrol.SetFocus
Exit Sub
Exit For
End If
End If
Next

L'erreur semble venir de mycontrol2.Caption alors que mycontrol2 semble bien renvoyer ce que je désire....

Je tiens à préciser que toutes mes TextBox commencent par Txt et que tous mes Labels commencent par Lab...
Pour chaque TextBox Txt[nom], un Label Lab[nom] lui est associé avec [nom] identique, cela va de soi...

Si quelqu'un a une petite idée ^^

Bonne journée à tous !

MA
0
micaub Messages postés 32 Date d'inscription lundi 9 mars 2009 Statut Membre Dernière intervention 18 juin 2015
21 avril 2009 à 18:35
Merci pour ton explication Bidouilleu_R, je comprend mieux pourquoi il refusait de faire mon .Caption.
Merci également pour tes corrections : il n'y a plus aucun bug dans ce code et tout fonctionne de manière impecable !
Promis, c'est la dernière question et après, j'arrête de vous embêter :
N'y a-t-il pas moyen de transformer un Variant en Objet afin que je puisse au final utiliser mon .Caption ?

Exemple :
Le nom de ma Textbox est "TxtRisque".
Le nom du Label qui lui est associé est "LabRisque".
Le Caption du Label, donc LabRisque.Caption, est "Risque identifié".
Avec la méthode élaborée gràçe à toi, si je remplis mal, la MsgBox écrit : "La valeur LabRisque ne peut pas être négative !"
Ne pourrait-on avoir "La valeur Risque identifié ne peut pas être négative !" ?

Bah, si ce n'est pas possible, c'est pas grave : le code tel que tu m'as permis de l'avoir est déjà très bien XD.

Encore une fois, merci à tous pour l'aide que vous accordez aux plus nuls (ne soyons pas si méchants, on dira plutôt aux moins bons) en prenant sur votre temps : une fois plus calé en VBA, j'espère bien pouvoir moi aussi participer activement.

A bientôt.

MA
0
Bidouilleu_R Messages postés 1181 Date d'inscription mardi 27 mai 2008 Statut Membre Dernière intervention 12 juillet 2012 289
22 avril 2009 à 11:27
j'ai une idée mais il faut que je teste....
Pour information je ne considère pas que les autres sont nuls en ceci ou cela
Je dirai plutôt qu'ils prennent le chemin pour apprendre ou découvrir ce que d'autres ont vu avant...
je regarde et je te tiens au courant.
0
micaub Messages postés 32 Date d'inscription lundi 9 mars 2009 Statut Membre Dernière intervention 18 juin 2015
22 avril 2009 à 15:27
Mais c'est bien sûr !!!
Je n'avais pas du tout pensé à ta suggestion, pourtant simple, alors que j'avais utilisé l'équivalent avec des OptionButton dont je ne voulais pas retranscrire le .Caption tel quel dans mon tableur.

Merci encore une fois de plus Bidouilleu_R : ta dernière astuce me permet vraiment de faire tout ce que je voulais faire. Associer à l'autre bout de programme, j'ai vraiment qqch qui correspond en tous points à mes attentes.

Et pour couronner le tout, j'aurais appris qq trucs dans ce topic grace à tes explications.

Encore merci et bravo pour ces interventions.

A bientôt p-ê sur un autre topic !

MA
0
Bidouilleu_R Messages postés 1181 Date d'inscription mardi 27 mai 2008 Statut Membre Dernière intervention 12 juillet 2012 289
22 avril 2009 à 15:47
Ben! je suis content pour toi!

tu peux mettre résolu si ... tu pense que c'est résolu

Bonne journée.

R
0
micaub Messages postés 32 Date d'inscription lundi 9 mars 2009 Statut Membre Dernière intervention 18 juin 2015
22 avril 2009 à 18:35
Ne t'inquiète pas, c'est fait depuis hier : ta dernière astuce n'était que du bonus alors j'avais déjà résolu le Topic ;)

Encore merci et bonne soirée.

MA
0