IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Aide bonnes pratiques contrôle de saisie UserForm [Toutes versions]


Sujet :

Macros et VBA Excel

  1. #1
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 66
    Points : 48
    Points
    48
    Par défaut
    Bonjour,

    je cherche a connaitre les bonnes pratiques pour les controles de saisie sur un UserForm VBA, l'équivalent des évenement type "OnValidating" en C# par exemple.
    Je n'ai pas trouvé grand chose de concluant sur internet.

    J'aimerais par exemple bloquer l'envoi du formulaire si tel ou tel txtbox n'est pas rempli, etc.. en informer l'utilisateur et qu'il puisse ainsi se corriger et renvoyer le formulaire
    J'aimerais donc savoir quels sont les évènements à utiliser etc, et où les placer dans le code (j'imagine directement dans la feuille UserForm)

    Merci

    JahE

    J'aimerais savoir également si il y a la possibilité d'utiliser des regex

  2. #2
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2017
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2017
    Messages : 33
    Points : 48
    Points
    48
    Par défaut Les bonnes pratiques?
    Bonjour,
    Si j'ai bien compris, tu cherches à avertir l'utilisateur si un textbox ou autre est vide durant l'utilisation de ton ton userform.
    Pour parer à cela, je pense que le bon vieux "If.. Then.. Else" serait pratique, c'est à dire :

    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 CommandButton1_Click()
     
    If TextBox1.texte <> "" Then
     
    ' faire l'action prévue
     
    Else
    MsgBox "Vous n'avez pas rempli tous les champs ! ", vbOKOnly + vbDefaultButton1 + vbInformation, "Attention !"
     
    ' averti l'utilisateur qu'il manque des champs
     
    ' On peut aussi préciser la chose en mettant un if
    ' à chaque textbox
     
    End Sub
    J'espère que ça répond à ta question, quant au regex, je ne sais pas ce que c'est, peut être pourrais-tu préciser?

  3. #3
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 677
    Points
    18 677
    Par défaut

    Bonjour,

    voir le tutoriel consacré aux expressions rationnelles en VBA et ceux dédiés aux UserForm

    ___________________________________________________________________________________________________________
    Je suis Paris, Egypte, Stockholm, London, Istanbul, Berlin, Nice, Bruxelles, Charlie, …
    C'est parce que la vitesse de la lumière est plus rapide que celle du son que tant de gens paressent brillants avant d'avoir l'air con ! (Thomas Boishardy)

  4. #4
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 66
    Points : 48
    Points
    48
    Par défaut
    Bonjour et merci de ta réponse,

    C'est bien cela que je cherche à faire, mais je voulais savoir quelles étaient les bonnes pratiques.

    Quant aux regex, ce sont des "expressions regulières" qui permettent de faire des recherches sur une chaîne de caractère, c'est cela qui permet dans les formulaire web de detecter si une adresse mail est valide ou non, ou de remplacer une date au format francais a une date au format américain.
    Par exemple pour verifier un mail en php :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if (preg_match('#^[\w.-]+@[\w.-]+\.[a-z]{2,6}$#i', $email)) {
        echo 'Cet email est correct.';
    } else {
        echo 'Cet email a un format non adapté.';
    }

  5. #5
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 66
    Points : 48
    Points
    48
    Par défaut
    Bonjour Marc,

    Je n'avais pas trouvé de tutoriel ou d'aide concernant les expressions rationnelles en VBA, je vais affiner mes recherches, merci

  6. #6
    Rédacteur
    Avatar de Philippe Tulliez
    Homme Profil pro
    Formateur, développeur et consultant Excel, Access, Word et VBA
    Inscrit en
    Janvier 2010
    Messages
    12 766
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur, développeur et consultant Excel, Access, Word et VBA

    Informations forums :
    Inscription : Janvier 2010
    Messages : 12 766
    Points : 28 625
    Points
    28 625
    Billets dans le blog
    53
    Par défaut
    Bonjour,
    Je n'avais pas trouvé de tutoriel ou d'aide concernant les expressions rationnelles en VBA, je vais affiner mes recherches, merci
    Les Expressions Rationnelles appliquées en VBA Access
    Philippe Tulliez
    Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément. (Nicolas Boileau)
    Lorsque vous avez la réponse à votre question, n'oubliez pas de cliquer sur et si celle-ci est pertinente pensez à voter
    Mes tutoriels : Utilisation de l'assistant « Insertion de fonction », Les filtres avancés ou élaborés dans Excel
    Mon dernier billet : Utilisation de la fonction Dir en VBA pour vérifier l'existence d'un fichier

  7. #7
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 66
    Points : 48
    Points
    48
    Par défaut
    Bonjour,

    Une dernière question concernant les regex qui peut sembler bête mais je débute en VBA:
    Le tutoriel indique qu'il faut ajouter une bibliothèque de code : "Microsoft VBScript Regular Expressions."
    Or l'application que je developpe va être utilisé par plusieurs personnes utilisant des PC différents etc, qui n'auront très probablement pas ajouté cette bibliothèque (les utilisateurs sont non-informaticiens). Est-ce que mes regex fonctionneront alors toujours ?

    Merci

  8. #8
    Responsable
    Office & Excel


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 122
    Points : 55 921
    Points
    55 921
    Billets dans le blog
    131
    Par défaut
    Salut.

    Pour la validation du userform, je passe systématiquement par une fonction qui se charge de la validation et qui renvoie TRUE ou FALSE.

    Un truc du genre
    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
    Private Sub btnValidate_Click()
      If CheckDatas Then
        ...
      Else
        MsgBox "Erreurs de saisie", vbExclamation
      End If
    End Sub
     
    Private Function CheckDatas() As Boolean
      Dim ReturnValue As Boolean
     
      ...
      ...
      ...
     
      CheckDatas = ReturnValue
    End Function
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  9. #9
    Responsable
    Office & Excel


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 122
    Points : 55 921
    Points
    55 921
    Billets dans le blog
    131
    Par défaut
    Salut.

    La librairie est native. Si tu l'as cochée dans ton projet, tes utilisateurs en disposeront également (sauf s'ils sont en Windows 3.1...).
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  10. #10
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 66
    Points : 48
    Points
    48
    Par défaut
    Merci pour ces précisions, je met le sujet en résolu

  11. #11
    Membre émérite
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 814
    Points : 2 949
    Points
    2 949
    Billets dans le blog
    10
    Par défaut
    Bonjour,

    Le problème du contrôle de saisie dépends de ce que tu souhaites réaliser.
    Si tu n'as que 4-5 contrôles à vérifier, placer dans un bouton de commande la vérification ne posera pas de souci à l'utilisateur.
    Par contre, si l'utilisateur a de très nombreux contrôles à saisir, que certains interagissent avec d'autres etc, mieux vaut les prévenir dès la saisie si celle-ci est erronée.
    Pour cela tu disposes de tous les événements disponibles pour chacun des contrôles utilisés :
    _Click
    _KeyPress
    _KeyDown
    _AfterUpdate
    _Exit
    etc...
    Tout dépendant alors du contrôle....
    Cordialement,
    Franck

  12. #12
    Responsable
    Office & Excel


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 122
    Points : 55 921
    Points
    55 921
    Billets dans le blog
    131
    Par défaut
    Citation Envoyé par pijaku Voir le message
    [...]
    Si tu n'as que 4-5 contrôles à vérifier, placer dans un bouton de commande la vérification ne posera pas de souci à l'utilisateur.[...]
    C'est surtout au programmeur que cette technique posera des soucis.

    Perso, je préfère, même pour un seul contrôle à vérifier, déléguer la vérification à une fonction qui ne fait que cela. Une des bonnes pratiques en programmation veut qu'une fonction/Procédure n'ait qu'une seule responsabilité. De cette manière, on ne lie pas des opérations qui devraient pouvoir être lancées séparément.

    En mettant le code de vérification dans l'événement du bouton de fermeture/validation, on s'empêche de pouvoir vérifier à un autre moment qu'à la validation (cas, par exemple, d'un bouton Appliquer et d'un bouton Ok.

    Pour la même raison, dans le code que j'ai proposé tout à l'heure, je n'ai pas mis le msgbox dans la fonction de vérification, dont la responsabilité est de vérifier que tout est correct, mais pas d'avertir l'utilisateur d'un problème. C'est l'événementielle sur le bouton Ok qui a cette responsabilité. En effet, il se pourrait que le formulaire doive être vérifié sans que l'utilisateur doive être informé de la bonne/mauvaise fin de l'opération (traitement par lots, ...). Mettre le message d'erreur dans la fonction bloquerait cette possibilité.

    Cette façon de découper le code permettra, entre autres avantages, de placer la gestion d'erreur correctement.
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  13. #13
    Responsable
    Office & Excel


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 122
    Points : 55 921
    Points
    55 921
    Billets dans le blog
    131
    Par défaut
    Tant qu'à parler de bonnes pratiques, je vois souvent ceci. On met le traitement opérationnel sur le bouton Valider.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Private Sub btnValidate_Click()
      ' Ici, le code de tout le traitement suite à la saisie de données
    End Sub
    Perso, je préfère que le userform ne fasse que ce pour quoi il est fait: saisir de l'information (et pas la traiter). Cela permet de lancer le traitement alors même que les infos seraient collectées d'une autre manière que par le userform.

    Dès lors, mon code est organisé de la manière suivante:
    Dans le userform, qui se contente de collecter les infos, d'en vérifier la validité puis de rendre la main au code appelant avec le choix de l'utilisateur (Validate ou Cancel)
    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
    40
    Option Explicit
     
    Public Choice As String
     
    Private Modified As Boolean ' Bascule à TRUE si contrôle modifié
     
    Private Sub btnCancel_Click()
      Dim Answer As VbMsgBoxResult
     
      If Modified Then
        Answer = MsgBox("Voulez-vous fermer sans enregistrer?", vbQuestion + vbYesNo)
      End If
      If Not Modified Or Answer = vbYes Then
        Choice = "Cancel"
        Me.Hide
      End If
    End Sub
     
    Private Sub btnValidate_Click()
      If CheckDatas Then
        Choice = "Validate"
        Me.Hide
      Else
        MsgBox "Erreurs de saisie", vbExclamation
      End If
    End Sub
     
    Private Function CheckDatas() As Boolean
      Dim IsOk As Boolean
     
    '  ...
    '  ...
    '  ...
     
      CheckDatas = IsOk
    End Function
     
    Private Sub tboFirstName_Change()
      Modified = True
    End Sub
    Dans le code appelant
    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
    Option Explicit
     
    Sub Mycode()
      Dim Choice As String
     
      Load UserForm1 ' Chargement
     
      ' Préparation du userform (chargement données, listbox, combo,...)
    '  ...
    '  ...
      UserForm1.Show ' Affichage
      Choice = UserForm1.Choice
      If Choice = "Validate" Then
     
        ' Ici, la récupération des données du userform
    '    ...
    '    ...
    '    ...
      End If
      Unload UserForm1
      If Choice = "Validate" Then
        ' Ici, le traitement avec les données récupérées du userform
    '    ...
    '    ...
      End If
     
    End Sub
    Je donne un exemple détaillé de cette pratique dans cette discussion.
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  14. #14
    Membre émérite
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 814
    Points : 2 949
    Points
    2 949
    Billets dans le blog
    10
    Par défaut
    Bonjour Pierre,

    pour ton post ici et les deux dans le lien que tu cites.

    Exemple tiré de mon quotidien :
    Dans mon travail, je saisis des informations dans un logiciel qui comporte une centaine de mnémonique (masques de saisie/Form (UserForm)).
    Ceux-ci, pour la plupart, doivent être validés en deux fois (entête puis corps) et comportent deux modes d'affichage : grille ou formulaire.
    Certains contrôles de saisie obligatoire ne sont pas apparent en mode formulaire, le mode d'affichage par défaut.
    Il faut alors à l'utilisateur, avant la validation, passer en mode grille pour saisir les informations nécessaires.
    En cas d'oubli de saisie, la validation intervient à l'enregistrement et nous averti par MsgBox d'alerte, et impossible d'aller plus avant.

    Après plusieurs semaines d'utilisation, nous ne zappons plus ces contrôles, mais cela reste fastidieux.

    C'est pourquoi, j'aurais tendance à préconiser une bonne conception initiale de l'UserForm.
    Comment?
    1. en utilisant chaque contrôle pour ce qu'il est censé faire (une ListBox n'est pas une combobox),
    2. en gérant l'ordre de tabulation,
    3. en validant chacun des contrôles obligatoires en cours de saisie grâce à ses événements,
    4. en vérifiant à la validation (comme tu le préconises) en fin de saisie


    Des exemples de contrôles en cours de saisie sont pléthores sur le net.
    Je vais en citer ici quelques-uns qui pourront, à coups sur, mettre le demandeur (s'il revient) JahExodus sur de bonnes pistes.

    Première partie : cas des TextBox

    Les TextBox sont LES contrôles permettant la saisie d'informations par l'utilisateur, c'est leur job.

    I/ didier gonard obliger saisie numérique dans texbox
    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_BeforeUpdate(ByVal Cancel As MSForms.ReturnBoolean)
    Dim strpass As String
       strpass = TextBox1.Value
       If ChainePasOK(strpass) = True Then Cancel = True: TextBox1.Value = "": Beep: MsgBox "Saisie non valide !"
    End Sub
     
    Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
       If InStr("1234567890,-", Chr(KeyAscii)) = 0 Or TextBox1.SelStart > 0 And Chr(KeyAscii) = "-" _
         Or InStr(TextBox1.Value, ",") <> 0 And Chr(KeyAscii) = "," Then
          KeyAscii = 0: Beep
       End If
    End Sub
     
    Private Function ChainePasOK(strpass As String) As Boolean
       If strpass = "" Then Exit Function
       If Len(Replace(strpass, ".", "")) <> Len(strpass) Then ChainePasOK = True: Exit Function
       If Len(strpass) = 1 And InStr("1234567890", strpass) = 0 Then ChainePasOK = True: Exit Function
       strpass = Replace(strpass, ",", ".")
       If Len(CStr(Val(strpass))) <> Len(strpass) Then ChainePasOK = True
    End Function
    Pour les textbox numériques, ajoutons la méthode de Chip Pearson :
    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
    Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    Select Case KeyAscii
        Case Asc("0") To Asc("9") 
        Case Asc("-")
            If Instr(1,Me.TextBox1.Text,"-") > 0 Or Me.TextBox1.SelStart > 0 Then
                KeyAscii = 0
            End If
        Case Asc(".")
            If InStr(1, Me.TextBox1.Text, ".") > 0 Then
                KeyAscii = 0
            End If
        Case Else
            KeyAscii = 0
    End Select
    End Sub
    II/UcFoutu TextBox date avec ajout de "facilités"
    Sur un userform :
    - 3 textboxes : T-date1, T_date2 et T_date3
    - un label Msg_date avec sa propriété visible = False
    Le code dans le module de l'UserForm :
    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 T_date1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
      alarme Me, ActiveControl, Cancel
    End Sub
    Private Sub T_date1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
     teste_date ActiveControl, KeyCode, "##/##/####", True
    End Sub
     
    Private Sub T_date2_Exit(ByVal Cancel As MSForms.ReturnBoolean)
      alarme Me, ActiveControl, Cancel
    End Sub
    Private Sub T_date2_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
     teste_date ActiveControl, KeyCode, "## ## ####", False
    End Sub
     
    Private Sub T_date3_Exit(ByVal Cancel As MSForms.ReturnBoolean)
      alarme Me, ActiveControl, Cancel
    End Sub
    Private Sub T_date3_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
     teste_date ActiveControl, KeyCode, "##-##-####", False
    End Sub
    Le code dans un module standard :
    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
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    Public Sub teste_date(ByRef t As MSForms.TextBox, ByRef cod As MSForms.ReturnInteger, ByVal flt As String, scl As Boolean)
      Dim ici As Byte, sp As String, cr As String, drf As String, dtt As String, siecle As Boolean
      sp = Left(Replace(flt, "#", ""), 1)
      drf = "31" & sp & "12" & sp & "2000" 'ne touche jamais rien à cette chaine
      With t
        ici = .SelStart
        If cod = 46 And .SelText = Mid(.Text, ici + 1) Then
          .Text = Left(.Text, ici)
          If Len(.Text) = 2 Or Len(.Text) = 5 Then .Text = Left(.Text, Len(.Text) - 1)
           cod = 0: Exit Sub
        End If
        If ici < Len(.Text) Then .SelStart = Len(.Text): cod = 0: Exit Sub
          If cod = 8 Then
            If ici = 3 Or ici = 6 Then .Text = Left(.Text, Len(.Text) - 1)
          Exit Sub
        End If
        If cod = 37 And ici = 0 Then
          If IsDate(.Tag) Then .Text = .Tag: cod = 0: Exit Sub
        End If
        If cod > 95 Then cr = Chr(cod - 48)
        If ici = 3 Then Mid(drf, 1, 5) = IIf(cr = "0", "00" & sp & "01", "00" & sp & "02")
        dtt = .Text & cr & Mid(drf, ici + 2)
        If cod = 32 Then
          If ici = 0 Or ici = 3 Or ici = 6 Or ici = 8 Then
            Dim voir As String
            voir = .Text & Mid(Format(Date, "dd" & sp & "mm" & sp & "yyyy"), ici + 1)
            If IsDate(voir) Then .Text = voir
          End If
         cod = 0:   Exit Sub
       End If
       If ici <> 8 Then
         If Not IsDate(dtt) Or Not dtt Like flt Then cod = 0: Exit Sub
       Else
         If Not IsNumeric(cr) Then cod = 0: Exit Sub
       End If
       Select Case ici
         Case 1, 4
           If ici = 4 And Val(Mid(.Text, ici, 1) & cr) > 12 Then cod = 0: Exit Sub
           If ici = 4 And scl Then
             .Text = Left(dtt, Len(.Text & cr)) & sp & Int(Year(Date) / 100): cod = 0
           Else
             .Text = Left(dtt, Len(.Text & cr)) & sp: cod = 0
           End If
         Case 3
           If cr > "1" Then cod = 0
       End Select
     End With
     Application.CutCopyMode = True
    End Sub
    Public Sub alarme(f As UserForm, t As MSForms.TextBox, ByRef c As MSForms.ReturnBoolean)
       Dim debut As Double, Msg_date As String
       If t.Text <> "" And Len(t.Text) < 10 Then
         c = True
         With f.Msg_date
           .Move t.Left - 20, t.Top - 10, t.Width + 40, 60
           .ZOrder
           .Font.Name = "MS Sans Serif"
           .Font.Bold = True
           .Font.Size = 9
           .Caption = "la date doit être sous la forme jj/mm/aaaa avec un millésime sur 4 chiffres)"
           .BackColor = vbYellow
           .ForeColor = vbRed
           .TextAlign = fmTextAlignCenter
           .Visible = True
           debut = Timer
           Do While Timer < debut + 4
             DoEvents
           Loop
           .Visible = False
         End With
       Else
         If t.Text <> "" Then t.Tag = t.Text
       End If
    End Sub
    III/ Un TextBox en MAJUSCULES uniquement :
    Permet uniquement la saisie de caractères alphabétiques et du trait d'union. Pas d'espace, possibilité de supprimer.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        Private Sub TBxNomPropre_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
            Select Case KeyAscii
                Case 32 'espace
                    KeyAscii = 0
                Case 45  'trait d'union
                    If Len(TBxNomPropre.Text) = 0 Then KeyAscii = 0
                Case 65 To 90 'majuscules
                Case 97 To 122 'minuscules
                    KeyAscii = KeyAscii - 32
                Case Else
                    KeyAscii = 0
            End Select
        End Sub
    IV/ Un TextBox format Heures HH:MM :
    Il ne s'agit que d'un exemple. Si plusieurs TextBox heures dans l'userform, il faudrait créer une fonction VerifHeure...
    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 Enable_Events As Boolean
        Const SEP_TIME As String = ":"
     
        Private Sub cTBx_Change()
            'empêche la saisie d'heures farfelues exemple 45:89
            Select Case Len(cTBx)
                Case 1
                    If cTBx.Value > 2 Then cTBx.Text = ""
                Case 2
                    If cTBx.Value > 23 Then cTBx.Text = Left(cTBx, 1)
                Case 4
                    If Right(cTBx.Text, 1) > 5 Then cTBx.Text = Left(cTBx.Text, 3)
            End Select
            If Enable_Events Then Exit Sub
            If Len(cTBx) = 2 Then cTBx.Text = cTBx.Text & SEP_TIME
        End Sub
     
        Private Sub cTBx_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
            'flèche de suppression (retour arrière)
            If KeyCode = 8 Then Enable_Events = True: Exit Sub
            Enable_Events = False
            'Tabulation possible que si heure valide
            If KeyCode = 9 Then
                If Len(cTBx.Text) = 5 Then Exit Sub
            End If
            'si 5 caractères saisis, bloque la saisie
            If Len(cTBx) = 5 Then KeyCode = 0
            'n'accepte que les chiffres
            Select Case Shift
                Case 0
                    If KeyCode < 96 Or KeyCode > 105 Then KeyCode = 0
                Case 1
                    If KeyCode < 48 Or KeyCode > 57 Then KeyCode = 0
            End Select
        End Sub
    Seconde partie : cas des ListBox

    Les ListBox ne sont pas des contrôles de saisie, mais des listes de choix.

    La vérification que l'utilisateur a bel et bien fait un choix dans une listbox est délicat.
    Quand faire cette vérification?
    Ici tout dépend de "l'importance" de la(es) donnée(s).
    Si ce choix influe sur d'autres saisies, il faut en vérifier la "présence" en amont.
    Sinon, dans tous les cas, on pourra toujours effectuer cette vérification en fin de saisie...
    Sachant pertinemment que cette vérification est difficile à "anticiper" de par le fait que l'utilisateur est libre de cliquer ou bon lui semble (mais là tant pis pour lui).

    Pour l'exemple, je contrôle la sélection dans ma listbox1 ("unisélection"), lors de l'événement Enter du TextBox qui la suit dans l'ordre de tabulation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Private Sub TextBox6_Enter()
    If ListBox1.ListIndex = -1 Then
        MsgBox "Le choix dans la liste est obligatoire"
        ListBox1.SetFocus
    End If
    End Sub
    Cela ne garantissant pas à 100% une sélection, il convient de refaire ce test lors de la validation globale de l'UserForm.

    Cas d'une ListBox MultiSelect avec deux choix obligatoires :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Private Sub TextBox6_Enter()
        VerifListeMulti
    End Sub
     
    Private Sub VerifListeMulti()
        Dim i As Integer, Cpt As Byte, Flag As Boolean
     
        For i = 0 To ListBox1.ListCount - 1
            If ListBox1.Selected(i) = True Then Cpt = Cpt + 1
            If Cpt = 2 Then Flag = True: Exit For
        Next i
        If Flag = False Then MsgBox "Vous devez faire deux choix dans la liste": ListBox1.SetFocus
    End Sub
    Chip Pearson (cité plus haut) a également écrit un module standard complet de fonctions utiles aux ListBox.
    Je ne fait pas le copié/collé, il est disponible ICI.
    Au programme :
    1. Fonction qui retourne le nombre d'items sélectionnés,
    2. Fonction qui retourne dans un Array les numéros d'index des items sélectionnés,
    3. Fonction qui inverse deux Items d'une listbox,
    4. Fonction qui "bouge" l'item sélectionné en premier,
    5. etc...


    Troisième partie : cas des ComboBox

    Les ComboBox sont un mix entre le textbox et la listbox.
    Il s'agit de liste de choix qui possèdent la possibilité d'accueillir une saisie utilisateur.
    Les événements associés à ce contrôle sont les mêmes que ceux associés aux TextBox.

    Les contrôles de saisie ou de choix vont donc être les mêmes que pour les textbox ou les listbox.

    A noter la propriété Style qui peut accepter deux valeurs :
    fmStyleDropDownCombo : permet la saisie utilisateur (par défaut) de valeurs autres que celles de la liste
    fmStyleDropDownList : empêche la saisie utilisateur de valeurs autres que celles de la liste. Toute saisie de l'utilisateur sélectionne progressivement l'item correspondant au mieux à la saisie.

    Pour finir :
    On pourrait maintenant en rajouter toute une tartine, en citant notamment les OptionButton et autres CheckBox.
    Je vais les laisser découvrir à l'ami JahExodus. Il y a, entres autres, déjà beaucoup d'infos : par ICI.

    Et puisque JahExodus est déjà au fait de la programmation (C#, php...), je l'invite à lire cette contribution, globalement inutile, mais pas nécessairement inintéressante...

    Bonne journée à tous
    Cordialement,
    Franck

  15. #15
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 66
    Points : 48
    Points
    48
    Par défaut
    Merci à tous pour vos contributions !
    Je pense maintenant avoir assez de ressources pour gérer mes quelques contrôles pour l'insertion dans la BDD et dans mes collections d'objets.

    Bonne journée à vous

  16. #16
    Membre émérite
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 814
    Points : 2 949
    Points
    2 949
    Billets dans le blog
    10
    Par défaut
    Bonjour,

    J'ai lu dans un autre sujet que tu utilises des modules de classe.
    Bien.
    Maintenant, il te faut savoir que certains événements ne sont pas disponibles dans les Classes de contrôles, sauf contournement.
    A++
    Cordialement,
    Franck

  17. #17
    Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    66
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 66
    Points : 48
    Points
    48
    Par défaut
    Bonjour,
    Pouvez-vous préciser ?
    j'utilise les modules de classe pour alimenter mes objets et pour mes objets de connexion, ainsi que les collections d'objets.
    Je pensais ecrire le code pour les controles de saisie directement dans mes UserForm
    Cdt

  18. #18
    Membre émérite
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 814
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 814
    Points : 2 949
    Points
    2 949
    Billets dans le blog
    10
    Par défaut
    Dans ma longue réponse, pour finir, je t'ai mis un lien vers une contribution.
    Elle en parle justement et implémente une solution.

    Sinon, les événements non gérés sont faciles à "lister".
    Il te suffit de :
    1. ouvrir un nouveau classeur et aller sous VBE (Alt+F11)
    2. insérer un userform (inutile mais ça active la référence à MsForms)
    3. insérer un module de classe, y placer ce code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Public WithEvents TBX As MSForms.TextBox
    Dans le menu déroulant "général" sélectionner TBX,
    les événements disponibles sont dans le menu déroulant "Déclarations".

    Même chose pour les autres types de contrôles.
    Il te suffit de changer MSForms.TextBox par MSForms.ComboBox par exemple...
    Cordialement,
    Franck

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 08/01/2016, 10h35
  2. Bonnes pratiques de protections individuelles
    Par Community Management dans le forum Sécurité
    Réponses: 22
    Dernier message: 05/04/2013, 11h47
  3. Réponses: 12
    Dernier message: 21/11/2010, 14h44
  4. Réponses: 7
    Dernier message: 23/03/2009, 22h38
  5. [Article]Les bonnes pratiques projet, demande d'aide
    Par elitost dans le forum Contribuez
    Réponses: 2
    Dernier message: 05/02/2008, 14h34

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo