Developpez.com - Rubrique Excel

Le Club des Développeurs et IT Pro

VBA : Obliger une saisie numérique dans une TextBox - Approche d'une résolution de besoin en VBA niveau débutant

Par Ormonth

Le 2010-03-18 14:19:57, par Didier Gonard, Expert éminent
Bonjour,

Ci-dessous, le lien vers un nouveau tutoriel :
« Approche d'une résolution de besoin en VBA - niveau débutant - Obliger une saisie numérique dans une TextBox »

Le but de ce tutoriel est :

  • De présenter une bonne approche de la résolution d’un problème simple en VBA.
  • D’expliciter en détail la démarche employée pour arriver à la solution voulue.
  • D’expliciter les instructions VBA retenues à cette fin.
  • De proposer un fichier téléchargeable qui présente une solution à un problème qui est source de fils de questions récurrentes.


Lien vers ce tutoriel

Vos commentaires et remarques seront les bienvenus dans l'esprit de nos forums.

cordialement,

Didier
  Discussion forum
13 commentaires
  • Didier Gonard
    Expert éminent
    Envoyé par davido84
    Bonjour,
    après être tombé sur votre tutoriel, l'avoir étudié et adapté à mes besoins, je me permets de vous contacter afin de vous remercier pour ce travail et vous signaler les 2 points suivants :
    1) le code proposé dans le Private Sub txtEcritFeuille_KeyPress permet de saisir une virgule avant tout chiffre, ce qui fait qu'une saisie telle que ",123" est acceptée. Même si une telle saisie dans une feuille de calcul est acceptée et automatiquement modifiée en "0,123", la Sub txtEcritFeuille_BeforeUpdate la rejette puisque la fonction ChainePasOK ne l'accepte pas.
    J'ai personnellement modifié l'événement KeyPress comme suit afin d'empêcher ce type de saisie :
    Code :
    1
    2
    3
    4
    5
       If InStr("1234567890,-", Chr(KeyAscii)) = 0 Or txtEcritFeuille.SelStart > 0 And Chr(KeyAscii) = "-" _
         Or (InStr(txtEcritFeuille.Value, ",") <> 0 Or txtEcritFeuille.SelStart = 0) And Chr(KeyAscii) = "," Then
          KeyAscii = 0: Beep
       End If
    2) l'ayant adapté pour des saisies de latitude et de longitude je me suis aperçu que la fonction ChainePasOK rejetait des données numériques dont le nombre de chiffres après la virgule dépassait 13, ce qui était problématique dans certains cas (la partie "If Len(CStr(Val(strpass))) <> Len(strpass)" fait barrage).
    J'ai personnellement résolu le problème en utilisant une expression rationnelle à la place de cette fonction.
    Comme ceci dépasse peut-être le cadre de votre tutoriel puisqu’il s'adresse aux débutants, je ne vous détaille pas l'expression utilisée mais si cela vous intéresse je pourrai vous la communiquer.
    Ce type de travail étant à encourager, je me suis donc permis ce petit retour.
    Merci encore !
    Cordialement
    Bonjour,

    Je vous remercie de ce retour, effectivement comme annoncé dans le titre « Approche d'une résolution de besoin en VBA niveau débutant Obliger une saisie numérique dans une TextBox », ce Tuto est orienté débutant et sur l'approche de résolution de problème, il vise à dire que pour arriver à ses fins, on ne se jette pas sur le code, mais on construit d’abord ce qu’on pourrait appeler un cahier des charges.

    Donc, comme vous l’avez si bien fait, si le besoin est proche du sujet traité, il convient d’en réécrire certaines parties au niveau liste des besoins et d’adapter ensuite les code aux besoins.

    Sinon,

    Pour ce qui est de l’entrée d’un nombre à virgule sans chiffre devant, c’est le fonctionnement de la fonction VAL (comme ci-dessous) qui en est responsable comme vous le montrerait l’ajour d’une ligne du genre Mavar = Val(strpass) et la visualisation de MaVAr dans la fenêtre variable locale.Le rajout du zéro fait que les longueurs de chaînes sont différentes.

    Pour ce qui des 13 décimales, en fait 14 passent aussi genre « 1,23456789123456 », la limite n’est pas sur les décimales, mais, en simplifiant, sur le nombre de chiffres significatifs liés au Double retourné par la fonction Val qui est de 15. De toutes façons, c’est aussi la limite des chiffres significatifs dans une cellule Excel, au-delà on passe dans la gestion des grands nombres (cf articles y afférents). En VBA en utilisant le type Decimal, on peut monter à 28 chiffres et faire des pirouettes après.
    Comme vous le dites cela dépasse le cadre de ce tutoriel, mais votre approche peut intéresser des lecteurs et faire l’objet d’un post dans le forum contribuez, sur les grands nombres, si ceci n’a pas déjà été traité.

    cordialement,

    Didier

    PS : merci de ne pas traiter de sujets techniques par MP
  • Bonjour

    Ayant eut la chance de lire ce tuto, j'ai adoré l'approche qui est faite pour résoudre un problème

    Philippe
  • edelweisseric
    Membre éclairé
    Bonjour à tous
    Bonjour Ormonth

    Il m'est toujours agréable de lire les tutos de ce site, mais, surtout, à chaque fois je découvre et j'apprends encore et encore.

    Merci pour ce travail

    Eric
  • GOLDINGMAROC
    Membre à l'essai
    Bonjour DIDIER,
    J'ai lu votre tutoriel il est très intéressant c'est un travail de Pro.
    Mais qu'on est il pour une VSFlexGrid. Comment peut on exploiter le tutoriel pour une VSFlexGrid en cellule courante du tableur?
    J'ai essayé de l'appliquer mais je me suis bloqué sur l'instruction en rouge (voir code ci aprés) :
    Code :
    1
    2
    3
    4
    5
    Private Sub VSFlexGrid_KeyPressEdit(ByVal Row As Long, ByVal Col As Long, KeyAscii As Integer)
    If InStr("1234567890.", Chr(KeyAscii)) = 0 Or (InStr(VSFlexGrid.????, ".") <> 0 And Chr(KeyAscii = ".")) Then
     KeyAscii = 0: Beep
    End If
    End Sub

    Cordialement
  • Didier Gonard
    Expert éminent
    Bonjour,

    Je n'ai pas ce contrôle et ne l'ai jamais utilisé, à première vue, il est sous licence payante et je n'ai pas ce projet d'acquisition.

    Bref, je ne peux donc pas tester quelque-chose....

    désolé,

    Didier
  • GOLDINGMAROC
    Membre à l'essai
    Bonjour,
    Ce Control n'est pas sous licence payante, au moins dans mon poste.
    J'ai résolut le problème à mon niveau. Consulté ce lien :
    http://www.developpez.net/forums/d1286407/logiciels/microsoft-office/excel/macros-vba-excel/obliger-saisie-numerique-vsflexgrid/#post7020796
  • levcha
    Candidat au Club
    Bonjour,

    Merci pour ce tutoriel, qui répond parfaitement à mon besoin (obliger la saisie de chiffres pour des infos clients ex: numéro de téléphone, numéro SIRET,etc.)

    Je rencontre un problème sur un champ où l'utilisateur renseigne le chiffre d'affaires prévus pour le nouveau client, les lettres / symboles renvoient bien un message d'erreur;
    En revanche le symbole € donne le message d'erreur suivant : "Erreur d'exécution '5': Argument ou appel de procédure incorrect".

    J'ai repris votre code presque tel quel en ajoutant une msgbox en cas d'erreur :

    Code :
    1
    2
    3
    4
    Private Sub CTR3_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    If InStr("1234567890", Chr(KeyAscii)) = 0 Then KeyAscii = 0: MsgBox "Saisie non valide", vbCritical
    
    End Sub
    J'ai essayé en téléchargeant le fichier disponible dans le tutoriel et j'obtiens la même erreur.

    Avez vous une idée de l'origine du bug ?

    Merci beaucoup
  • Orestie
    Futur Membre du Club
    Bonjour!
    J'ai beaucoup apprécié votre tutoriel Je suis de niveau débutant en VBA. J'aimerais svp savoir s'il est possible d'affecter votre code à plus d'une TextBox? Par exemple, j'ai 34 textbox. J'ai tenté d'inscrire Textbox(1,2,3, etc.)_KeyPress, mais ça ne fonctionne pas... Le message d'erreur est Erreur de compilation : Attendu : identificateur.

    Code :
    1
    2
    3
    Private Sub textbox2_KeyPress(ByVal KeyAscii As MSFORMS.ReturnInteger)
            If InStr("1234567890,-", Chr(KeyAscii)) = 0 Then KeyAscii = 0: Beep
    end sub
    Je vous remercie grandement pour avoir pris le temps de lire cette question et peut-être même d'y répondre

    Bonne journée!
  • Fabien_pe
    Nouveau Candidat au Club
    Bonjour,

    Votre tutoriel est très intéressant.

    En testant ce dernier je me suis rendu compte que lorsque l'on rentre un nombre avec virgule qui se termine par 0 (exemple: 1,10), la saisie ressort en non valide.
    Ce problème de validation proviendrait, dans la Fonction ChainePasOk, de If Len(CStr(Val(strpass))) <> Len(strpass) Then ChainePasOK = True.

    Je ne parviens pas à voir ce que je peux faire pour qu'une saisie avec un chiffre à virgule se terminant par 0 ne renvoie pas une erreur.

    Quelqu'un peut il me fairte par de ces lumières .

    Merci

    Fabien
  • BackDev1
    Membre à l'essai
    Bonjour, et merci pour ce tutoriel, très agréable à lire et facile à comprendre.

    Depuis sa publication, je pense qu'il y a eu des mises à jour office qui ont impactés au moins une chose.
    En effet, la procédure "xxx_BeforeUpdate" ne prend pas en compte le coller, il faut désormais passer par la procédure "xxx_BeforeDropOrPaste"

    Et du coup, utiliser "Data.GetText" à la place de "txtEcritFeuille.Value"

    Ce qui donne pour l'intégralité de cette procédure modifiée :
    Code :
    1
    2
    3
    4
    5
    6
    Private Sub txtEcritFeuille_BeforeDropOrPaste(ByVal Cancel As MSForms.ReturnBoolean, ByVal Action As MSForms.fmAction, ByVal Data As MSForms.DataObject, ByVal X As Single, ByVal Y As Single, ByVal Effect As MSForms.ReturnEffect, ByVal Shift As Integer)
       Dim strpass As String
       strpass = Data.GetText
       If ChainePasOK(strpass) = True Then Cancel = True: txtEcritFeuille.Value = "": Beep: MsgBox "Saisie non valide !"
    End Sub