Valider un champ de saisie

Comment contrôler la saisie d’un champ en VBA, et faire en sorte que l’utilisateur reste sur ce champ si sa saisie est incorrecte ?
(si vous débutez sur Access, cet article sera l’occasion de tester les événements BeforeUpdate qui font partie des plus importants…)

Avant de commencer…

Il y a plein de manières de contrôler qu’une saisie est correcte ; cet article concerne uniquement la validation au niveau Formulaires. Rappelons que, comme toujours dans Access, plus vous intervenez tôt, mieux ça vaut ! Ce qui veut dire que vous devriez déjà avoir défini des contraintes dans vos tables. En vrac :

  • vos tables ont toutes une clef primaire (ce qui est une contrainte en soi) ;
  • les champs obligatoires sont marqués Null interdit = Oui (et sans doute Chaîne vide autorisée = Non) ;
  • les champs qui doivent suivre des règles particulières ont leurs propriétés Valide si et Message si erreur de renseignées ;
  • idem pour les tables, si des règles particulières doivent comparer plusieurs champs ;
  • les champs dont les valeurs doivent être uniques (hors clef primaire) ont un index sans doublons ;

Dans cet article, je suppose que tout ça est déjà en place. On va surtout s’intéresser à la validation d’un champ unique, au niveau du formulaire, qui complète ce qui précède en permettant :

  • d’effectuer des validations plus complexes que de simples comparaisons ;
  • d’afficher des messages personnalisés ;
  • de bien gérer le comportement de l’interface en fonction des erreurs (doit-on rester sur le champ ? doit-on ouvrir un autre formulaire ? etc.)

On reprend !

Le scénario est donc le suivant :

  • Vous avez un formulaire quelconque.
  • L’un des champs de saisie s’appelle txtValeur, et doit recevoir une valeur entre 0 et 100.
  • Si l’utilisateur tape une valeur incorrecte, il doit rester sur ce champ txtValeur, et ne pas pouvoir se déplacer ailleurs.

Mise en place

  1. Ouvrez votre formulaire en mode Création.
  2. Faites apparaître les propriétés du champ (clic du bouton droit, puis Propriétés).
  3. Activez l’onglet Evénement.
  4. Cliquez dans l’événement appelé Avant MAJ. Une liste déroulante apparaît : sélectionnez [Procédure événementielle].
  5. Cliquez ensuite sur les points de suspension à droite de l’événement. Vous accédez à l’événement Visual Basic.
  6. Recopiez le code ci-dessous, pour l’exemple :

Le premier test vérifie si la saisie est bien numérique, et le second vérifie qu’on ne dépasse pas 100… Pour tester :

  1. Passez en mode Formulaire.
  2. Tapez un texte ou un nombre dans le champ.
  3. Essayez de changer de champ.

Comment ça marche ?

  1. Quand l’utilisateur sort du champ, la nouvelle saisie doit être validée. Avant qu’elle ne soit transférée définitivement dans le champ, Access – VBA en fait – déclenche l’événement BeforeUpdate (Avant Mise à jour).
  2. Access transmet à l’événement une variable Cancel, préréglée sur False (Annuler = Faux ; traduire par : « ne pas interrompre la suite des événements »).
    Pour l’anecdote, cette variable est passée par référence. En d’autres termes : si vous la modifiez dans votre code, c’est l’original transmis par Access qui est modifié (et c’est là l’intérêt de la chose !).
  3. Une fois que tout le code VBA placé dans BeforeUpdate est terminé, Access reprend la main et récupère la variable Cancel.
    Si celle-ci a gardé sa valeur False, la suite des opérations continue (ce qui veut dire : transférer la saisie dans le champ).
    Par contre, si Cancel vaut True (Annuler = Vrai), le train d’opérations s’arrête (le champ reste invalidé, et aucun déplacement n’est autorisé).

Et pour ceux qui préfèrent les schémas avec plein de couleurs et de flèches dans tous les sens 🙂 :

Info
Et pourquoi Cancel est-il de type Integer, et pas Boolean ?
Pour chipoter, c’est vrai qu’une valeur True/False devrait être booléenne. L’Integer qui traîne ici est un héritage des vieilles versions d’Access 🙂 …

Et si on écrivait autrement ?

Quand on débute, on est souvent tenté d’écrire cette variante, où les Cancel = True ont été remplacés par des Exit Sub :

Si vous avez suivi, les Exit Sub forcent la sortie du bloc de code, mais ne modifient pas la variable Cancel, qui vaut donc toujours False. Par conséquent, la suite standard des opérations s’enchaîne : le champ est validé et on passe au champ suivant. Et ce n’est pas du tout ce qu’on souhaite ici !

Rien n’empêche par contre d’écrire ce qui suit, qui est une combinaison des 2, et qui allègera le code si vous avez beaucoup de tests à faire. Dans ce bout de code, on force une sortie à chaque fois qu’une condition n’est pas respectée (tout en modifiant l’état de la variable Cancel bien sûr).

Défauts de cette approche

Cette approche de validation peut servir dans de nombreux cas, mais elle a quand même un défaut majeur, à bien prendre en compte : la validation n’est déclenchée que si :

  • l’utilisateur passe sur le champ ;
  • l’utilisateur effectue une mise à jour du champ.

Ce qui est logique : l’événement BeforeUpdate n’a pas de raison d’être déclenché… s’il n’y a pas eu mise à jour du champ !

Et pour contrôler plusieurs champs ?

Le formulaire lui-même
dispose d’un événement Avant MAJ. Celui-ci est déclenché avant que tous les champs ne soient transférés dans la base.  C’est d’ailleurs un meilleur endroit pour programmer ce type de validation parce que :

  • L’événement se produit systématiquement dès qu’il y a eu modification des données (peu importe le champ modifié).
  • Il vaut mieux avoir un traitement global et centralisé des erreurs de saisie, plutôt que des bouts de code attachés à chaque champ.
  • L’ergonomie est meilleure pour l’utilisateur, parce qu’il reçoit un message seulement en fin de validation, et non pas à chaque déplacement.

Vous aimerez aussi...

11 réponses

  1. pascale dit :

    bonjour
    Je veux construire une BDD avec un champ dans une table qui s’intitule date et cette date doit être de moins de 5 ans au moment ou je la rentre dedans
    je n’arrive pas à faire ma contrainte
    merci de votre aide

  2. bobe48000 dit :

    bonjour et merci
    je veut une methode pour videz le champ si la saisie n est pas valide
    j’essai de faire champ= » » apres le cancel et aussi avant le cancel ds le sub l’evenement avant maj mais tjs rien a passe

    • Hervé Inisan dit :

      Ceci devrait marcher, dans l’événement « Après MAJ » :

      • bobe48000 dit :

        bonjour oui ça c’est fait avant mais le problème comment reste dans le champ sans sortir au champ suivant
        pas de solutrion je pense

        • bobe48000 dit :

          un autre question svp porquoi le end sub malgre le cancel fait son role je pense quand on a deux condition a teste ness pas ??????

          • Hervé Inisan dit :

            C’est expliqué dans l’article : le Cancel n’arrête pas l’exécution en lui-même (on ne fait que renseigner une variable). Donc si on veut sortir de la procédure avant la fin, on a besoin du Exit Sub.

        • Hervé Inisan dit :

          En fait, c’est l’un ou l’autre des choix :

          • Si la validation doit se faire sans sortir de la zone de saisie, ce sera un BeforeUpdate, avec un Cancel = True pour l’annuler. Mais dans ce cas, on ne peut pas remodifier la saisie, puisqu’on est en train de la valider.
          • Si la validation doit se faire après être sorti, c’est un AfterUpdate. A ce niveau, la zone de texte peut être remodifiée, mais on en est sorti.
  3. Hervé Inisan dit :

    pierre > En allant à l’essentiel, il faut déjà tester les paragraphes « On reprend ! » et « Mise en place« . Si ces 2 points fonctionnent, la partie technique est ok, c’est déjà un bon point.

    Le reste n’est que du clapotis 🙂 (des explications détaillées sur quelque chose qui n’est pas si simple effectivement, et qui se comprend mieux avec une petite expérience de VBA).

  4. pierre dit :

    rien compris !!!!

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *