Pour partager cette vidéo sur les réseaux sociaux ou sur un site, voici son url :
Sujets que vous pourriez aussi aimer : 
Formulaire d'identification en VBA Excel 
Dans cette 
formation VBA Excel , nous poursuivons la réalisation de l'
application pour évaluer les candidats , grâce à des 
QCM  archivés dans une 
base de données  externe.
A l'ouverture du 
classeur Excel , le 
formulaire d'identification  se charge automatiquement, prenant le contrôle de l'application. Le candidat doit saisir son identifiant pour pouvoir participer. S'il est reconnu comme inscrit, la liste déroulante du dessous se charge des thèmes sur lesquels il peut s'évaluer.
Sources et présentation de la problématique 
Nous proposons de récupérer les travaux là où nous les avions laissés lors des trois formations précédentes.
Comme vous le constatez, le 
formulaire d'identification  se charge en effet automatiquement. Il est accompagné de petites animations aiguillant le candidat sur les informations à renseigner avant de débuter. Il s'agit du développement que nous avons réalisé lors de la première de ces formations.
Cliquer sur le lien Jamais Inscrit ?  situé en dessous de la première zone de texte, 
Cette action a pour effet de commander l'affichage du 
formulaire d'inscription  aux dépens du 
formulaire d'identification . Des contrôles de saisie ont été mis en place lors de la deuxième formation. Ils permettent d'alerter le candidat sur les zones requises et non conformes.
Une fois le formulaire complètement renseigné, le candidat clique sur le 
bouton Valider . Un 
code VBA Excel , développé lors de la troisième formation, se charge d'inscrire l'utilisateur en 
base de données Access . Ainsi, il pourra désormais s'identifier pour participer à un test.
Cliquer sur le bouton Annuler  du formulaire d'inscription , 
Nous réalisons ainsi la bascule inverse. Cette fois, c'est le 
formulaire d'identification  qui s'affiche aux dépens du 
formulaire d'inscription .
Désormais donc, au clic sur le 
bouton Ok , l'
identifiant  saisi doit être cherché en 
base de données  par le 
code VBA . Ce dernier doit exécuter une 
requête SQL sélection avec clause WHERE  pour effectuer la correspondance entre l'identifiant cherché et l'identifiant inscrit. S'il est trouvé, l'ensemble des questionnaires doit être chargé dans la liste déroulante. Ainsi, le candidat identifié peut faire son choix pour participer à l'évaluation souhaitée.
A la racine du dossier de décompression, double cliquer sur le fichier questionnaires-evaluations.accdb  pour l'ouvrir dans Access , 
Cliquer sur le bouton Activer le contenu du bandeau de sécurité, 
Dans le volet des objets Access sur la gauche de l'écran, double cliquer sur la table msy_inscrits  pour l'afficher en mode feuille de données , 
Comme l'illustre la capture ci-dessus, cette table archive tous les 
candidats inscrits . A l'identifiant sont attachées les informations sur son nom, son prénom et son mail. Il s'agit précisément des données à renseigner depuis le 
formulaire d'inscription . Dans le 
volet des objets Access , sur la gauche de l'écran, vous notez la présence de nombreuses 
tables . Pour la plupart il s'agit des questionnaires permettant de dérouler une évaluation. A chaque question sont associées les quatre propositions ainsi que le numéro de la bonne réponse. L'
objet ListeTables  est particulier. Nous allons devoir l'exploiter. Elle énumère simplement l'ensemble des questionnaires disponibles, reconnus par leur nom de table.
Charger une liste déroulante en VBA Excel 
Nous proposons de créer une procédure indépendante pour débuter. Celle-ci doit permettre de récupérer la liste des questionnaires, issus de cette 
table ListeTables . Ces noms de tests devront être chargés dans la liste déroulante du 
formulaire . Ainsi, lorsque l'identification sera un succès, cette procédure pourra être appelée au clic sur le bouton Ok.
Fermer la base de données Access et revenir sur le classeur Excel, 
Fermer le formulaire d'identification en cliquant sur la croix de sa fenêtre, 
Basculer dans l'éditeur de code VBA Excel  à l'aide du raccourci clavier ALT + F11 , 
Vous y notez la présence des développements VBA réalisés lors des précédentes formations. Pour charger cette liste déroulante nommée 
Sujet , le 
code VBA  doit se connecter à la 
base de données Access . Pour manipuler une 
base de données Access , une référence doit être ajoutée au projet.
En haut de l'éditeur VBA, cliquer sur le menu Outils , 
Dans la liste, choisir Références , 
La 
librairie Microsoft Office Access database engine  a déjà été référencée. C'est elle qui permet de déclarer les objets de bases de données instanciant cette classe externe.
Cliquer sur le bouton Ok pour fermer la boîte de dialogue des références, Dans l'explorateur de projet sur la gauche, double cliquer sur le formulaire Connexion  pour l'afficher à l'écran, Puis, double cliquer sur un emplacement vide du formulaire pour basculer dans sa feuille de code qui lui est attachée, 
Nous y trouvons le 
code VBA  que nous avions développé lors de la première de ces formations. Il permet de produire ces petits effets d'animations en exploitant la 
fonction VBA Timer  notamment.
Sous la procédure Valider_Click , créer la procédure charge_liste , comme suit : Private Sub charge_liste() 
Des variables sont nécessaires pour désigner la 
base de données Access  et la manipuler par le 
code VBA .
Dans les bornes de la procédure, ajouter les déclarations et affectations suivantes : Dim chemin_bd As String 
La 
variable chemin_bd  est déclarée comme un texte (String). Elle doit mémoriser le chemin d'accès complet à la 
base de données  à manipuler. Les deux déclarations suivantes sont rendues possibles grâce à l'ajout de la référence précédemment citée. La 
variable enr  déclarée comme un 
objet de type Recordset , doit permettre de manipuler les enregistrements de la base de données. C'est pourquoi nous déclarons la 
variable base  comme un 
objet de base de données  (Database).
Ensuite, nous exploitons la 
propriété Path  de l'
objet VBA Excel ThisWorkbook . Ce dernier désigne le classeur actif. Avec cette propriété, nous récupérons le chemin d'accès au classeur. Comme la 
base de données Access  est placée dans le même dossier, il ne reste plus qu'à concaténer avec le nom du fichier. Enfin, nous exploitons la 
méthode Clear  du 
ComboBox Sujet . Elle permet simplement de vider la liste déroulante avant d'ajouter les nouvelles valeurs.
Il s'agit maintenant d'instancier la classe permettant aux 
objets de base de données  d'hériter des méthodes nécessaires pour la manipuler.
A la suite du code VBA, ajouter les deux affectations suivantes : Set base = DBEngine.OpenDatabase(chemin_bd) 
La 
méthode OpenDatabase  de l'
objet DBEngine  permet de pointer sur la 
base de données Access  dont le chemin d'accès lui est passé en paramètre (chemin_bd). De fait, l'
objet base  hérite des propriétés et méthodes de la classe. Dès lors, sa 
méthode OpenRecordset  permet de manipuler les enregistrements de la base selon la 
syntaxe SQL  qui lui est passée en premier paramètre. Nous sélectionnons tous les champs (SELECT *) de la 
table ListeTables  (FROM ListeTables), en les triant croissant sur le nom du questionnaire (ORDER BY Questionnaire). L'
attribut dbOpenDynaset  passé en second paramètre de la méthode indique un accès en mode dynamique pour manipuler ces données. C'est l'
objet enr  qui est désormais affecté à ce jeu d'enregistrements restitués par la 
requête SQL  exécutée sur la 
base de données Access .
C'est pourquoi nous devons l'exploiter pour récupérer toutes des valeurs à l'aide d'une 
boucle de traitement  parcourant l'ensemble des enregistrements.
A la suite du code, ajouter les instructions VBA suivantes : If (enr.RecordCount > 0) Then 
Par mesure de précaution, nous utilisons tout d'abord la 
propriété RecordCount  de l'
objet Recordset . Cette dernière retourne le nombre d'enregistrements sélectionnés par la 
requête SQL  exécutée sur la 
base de données . Si ce nombre n'est pas nul, nous plaçons le pointeur de lecture sur le premier d'entre eux grâce à la 
méthode MoveFirst  de l'
objet Recordset . Puis, nous initialisons une 
boucle Do  afin de les passer tous en revue. C'est la 
propriété EOF  de l'
objet Recordset  qui indique, tant qu'elle ne vaut pas True, que le dernier enregistrement n'est pas atteint. A chaque passage dans cette boucle, donc pour l'enregistrement en cours, nous récupérons la valeur du champ grâce à la 
propriété Fields  de l'
objet Recordset . Pour ce faire, nous lui passons en paramètre le nom du champ à interroger. C'est alors sa 
propriété Value  qui accède à son contenu pour l'ajouter dans la liste déroulante (AddItem). Bien sûr, nous exploitons la 
méthode MoveNext  pour déplacer le pointeur de lecture sur l'enregistrement suivant, à chaque passage dans la boucle.
A ce stade, nous sommes censés avoir récupéré tous les noms des questionnaires. Mais avant de tester, nous devons fermer les connexions ouvertes.
Après la boucle Do et l'instruction If, ajouter les lignes VBA suivantes : enr.Close 
La 
méthode Close  des objets de base de données ferme les connexions. Ensuite, l'affectation des objets à 
Nothing  permet de les détruire pour libérer les ressources en mémoire. Enfin, nous rendons disponible la liste déroulante Sujet, grâce à sa 
propriété Enabled  fixée à 
True . Ainsi le candidat peut désormais cliquer dessus pour déployer son contenu.
Pour être exécutée, cette procédure doit être appelée.
Dans la procédure Valider_Click , avant l'instruction composante = 0 , ajouter l'appel comme suit : charge_liste , 
Enregistrer les modifications et afficher le formulaire Connexion  en conception, 
Enfoncer la touche F5 du clavier  pour l'exécuter, 
Après les animations, taper un identifiant, par exemple : 123456 et cliquer sur Ok, 
Une petite animation en dégradé de couleurs se déclenche sur la liste déroulante pour aiguiller le candidat. Cette dernière est désormais active.
Cliquer sur la flèche de la liste déroulante pour déployer son contenu, 
Comme vous le constatez, tous les noms des questionnaires ont parfaitement été chargés, qui plus est, triés croissant (ORDER BY). Le candidat pourra donc émettre son choix avant de participer.
Le code complet de la procédure charge_liste est le suivant :
Private Sub charge_liste() 
Validité de l'identification 
A ce stade, quel que soit l'identifiant saisi, le 
code VBA  se déclenche et la liste déroulante se charge. Ce traitement doit intervenir au clic sur le 
bouton Ok  uniquement si le candidat est reconnu. Nous allons donc devoir ajouter du 
code VBA  dans la 
procédure Valider_Click . Ce développement consiste à questionner la 
table msy_inscrits  de la 
base Access  à la recherche de l'identifiant tapé. Les mêmes techniques de 
connexion  doivent être employées pour exécuter une 
requête SQL  de sélection.
Fermer le formulaire et revenir dans l'éditeur de code VBA Excel , 
Afficher le formulaire Connexion , 
Double cliquer sur le bouton Ok  pour afficher sa procédure Valider_Click , 
Ajouter les déclarations de variables affichées en gras dans les instructions ci-dessous : Dim lid As String: Dim chemin_bd As String Dim test As Boolean 
Les 
variables composante et debut  existaient déjà afin de produire l'effet d'animation. Les 
variables chemin_bd, enr et base  doivent permettre d'accéder à la 
base de données . La première doit mémoriser son chemin d'accès complet. La deuxième doit servir à manipuler ses enregistrements. La troisième doit instancier la classe permettant de la désigner et manipuler. La 
variable lid , déclarée comme un 
String  servira à mémoriser l'identifiant à trouver dans la table des inscrits. Enfin, la 
variable test  est déclarée comme un 
booléen . Lorsqu'elle vaudra 
True , elle indiquera que le candidat s'est correctement identifié.
L'accès à la 
base de données  ne doit pas être initié tant que nous n'avons pas la certitude que le candidat a bien saisi son identifiant. Donc un test préalable s'impose.
Sous la partie déclarative, ajouter les instructions VBA  suivantes : lid = identifiant.Value 
Nous stockons l'information encryptée saisie par l'utilisateur dans la 
variable lid . Grâce à l'
instruction conditionnelle If , nous vérifions que l'identifiant tapé n'est pas vide. S'il n'est pas renseigné, nous informons le candidat de le faire (MsgBox). Puis nous mettons fin au traitement (Exit Sub). Ainsi les 
connexions à la base de données  ne sont pas amorcées. De fait, les ressources ne sont pas engorgées inutilement.
Lorsque l'identifiant est renseigné, nous poursuivons. Nous initialisons le test d'identification à 
False . Jusqu'à preuve du contraire, le candidat n'est pas reconnu. Puis, nous mémorisons le chemin d'accès à la base de données comme nous l'avons fait jusqu'à présent.
Il s'agit ensuite d'établir la 
connexion  afin d'accéder à la 
table msy_inscrits  pour valider l'existence de l'identifiant. Nous devons donc construire une 
requête SQL de sélection avec clause WHERE  sur le champ correspondant.
A la suite du code VBA , ajouter les deux affectations suivantes : Set base = DBEngine.OpenDatabase(chemin_bd) 
Il s'agit de techniques classiques désormais. Nous instancions la classe ajoutée en référence du projet. De fait, l'
objet base  hérite des méthodes permettant de manipuler la 
base de données  désignée par son chemin d'accès (chemin_bd). Dès lors, sa 
méthode OpenRecordset  permet d'initialiser la 
variable enr  pour qu'elle puisse manipuler les enregistrements, en fonction de la 
syntaxe SQL  passée en argument. Cette syntaxe consiste à récupérer tous les champs (SELECT *) à partir de la table msy_inscrits (FROM msy_inscrits), pour lesquels l'identifiant coïncide avec celui tapé par le candidat (WHERE inscrit_identifiant='" & lid & "'"). Il faut bien prendre soin d'encadrer la valeur dynamique (lid) entre simples côtes (') elles-mêmes délimitées par des doubles côtes (").
Si le candidat est reconnu, la 
requête SQL  doit retourner des informations. De fait, la 
propriété RecordCount  de l'
objet enr  ne doit pas renvoyer une valeur nulle. Nous devons alors récupérer les valeurs de champs pour les inscrire dans la 
feuille Session . L'objectif est de mémoriser les données qui permettront de mettre à jour les scores à l'issue de l'évaluation.
A la suite du code VBA , ajouter les instructions suivantes : If (enr.RecordCount = 0) Then 
Lorsqu'aucun enregistrement n'est retourné (enr.RecordCount = 0), nous en informons le candidat. Dans le cas contraire, nous plaçons le pointeur de lecture sur l'enregistrement résultant (enr.MoveFirst). Et grâce à la 
propriété Fields  de l'
objet Recordset  (enr), nous accédons aux données de chacun des champs. Nous affectons leurs valeurs (Value) aux cellules de la feuille Session (Sheets("Session")) prévues à cet effet. Nous n'oublions pas de basculer le 
booléen  à 
True . Pour les traitements à suivre, il confirmera que l'
identification  a réussi.
Comme toujours, nous devons fermer les connexions et vider les objets de base de données.
Après l'instruction conditionnelle (End If), ajouter les lignes VBA suivantes : enr.Close  charge_liste
La 
méthode Close  des 
objets de base de données  ferme les connexions. Leur réaffectation à 
Nothing  permet de les vider de la mémoire. Notez enfin que l'appel à la 
procédure charge_liste  est désormais inclus dans une instruction conditionnelle. La liste déroulante ne doit être chargée que si l'
authentification  est un succès. Et c'est notre fameuse variable 
booléenne  qui en atteste.
Enregistrer les modifications et afficher le formulaire Connexion , 
Enfoncer la touche F5 du clavier  pour l'exécuter, 
Taper un identifiant non reconnu, par exemple : bbbbbb , 
Puis, cliquer sur le bouton Ok pour établir la connexion à la base de données, 
Comme vous le constatez, le candidat est refoulé. Son identifiant n'existant pas, il n'est pas reconnu. Une boîte de dialogue l'en informe. De fait, la liste déroulante n'est ni libérée, ni chargée.
Nous devons désormais simuler un test concluant.
Taper un identifiant archivé, par exemple : abcdef , 
Cette fois la liste déroulante est libérée et chargée. Elle propose aux candidats tous les questionnaires disponibles. Si vous affichez la feuille Session, vous constatez que les données du candidat ont en effet été archivées. Seules les informations sur le questionnaire et la date sont obsolètes. Elles devront être actualisées au démarrage de l'évaluation, après le choix du questionnaire par le candidat.
Quoiqu'il en soit, notre 
formulaire d'identification  est tout à fait opérationnel. Le 
code VBA  complet de la 
procédure Valider_Click  est le suivant :
Private Sub Valider_Click() 
Initialiser une évaluation 
Au choix d'un thème, le 
bouton Démarrer  doit être actif pour permettre de débuter l'évaluation, soit au changement de valeur dans la liste déroulante. Il s'agit d'un évènement naturellement associé à l'
objet Sujet .
Fermer le formulaire d'identification  en cliquant sur la croix de sa fenêtre, 
Dans l'éditeur VBA , afficher le formulaire Connexion  en conception, 
Double cliquer sur la liste déroulante  pour basculer entre les bornes de sa procédure évéènementielle : Sujet_Change , 
Ajouter le code VBA  suivant entre ses bornes : Sheets("Session").Range("C5").Value = Sujet.Value 
Nous commençons par actualiser le nom du questionnaire choisi dans la cellule de la 
feuille Session . C'est la 
propriété Value  d'un 
contrôle Combobox  qui retourne la valeur sélectionnée. Puis, nous basculons la 
propriété Enabled  du 
bouton Demarrer  à 
True . De fait, il devient cliquable et l'évaluation peut débuter.
Au clic sur le 
bouton Démarrer , une première question doit être générée aléatoirement à partir du thème choisi. La question et ses quatre propositions doivent être archivées dans la 
feuille Mémoire , à partir de la ligne 5 comme l'illustre la capture ci-dessous.
Nous devons donc développer le code qui se déclenche au clic sur ce bouton.
Afficher le formulaire Connexion  en conception, 
Double cliquer sur le bouton Demarrer  pour générer sa procédure événementielle : Demarrer_Click , 
Ajouter les déclarations et affectations suivantes : Dim requete As String: Dim chemin_bd As String 
Hormis la 
variable requete , les autres variables sont habituelles. Cette 
variable requete  doit mémoriser la 
syntaxe SQL  permettant de générer une question aléatoire selon le thème choisi. Grâce à la 
fonction VBA Date , nous actualisons l'information correspondante dans la 
feuille Session . La partie a en effet débuté. Nous reconstruisons le chemin d'accès à la base de données (chemin_bd). Nous appelons la procédure 
purger  mais la conservons en commentaire à ce stade. En effet elle n'existe pas encore. Nous anticipons. Dans le prochain volet, elle permettra de nettoyer le tableau servant à mémoriser toutes les questions passées. Nous masquons le 
formulaire Connexion  grâce à sa 
méthode Hide . Puis, nous affichons la 
feuille Evaluations . C'est elle qui a la main désormais. Elle doit permettre de dérouler l'évaluation sur les 20 questions.
Nous devons maintenant exécuter la requête permettant de prélever une question aléatoirement. Pour cela, nous devons initialiser nos objets de base de données, comme nous le faisons habituellement.
A la suite du code VBA , ajouter les deux affectations suivantes : Set base = DBEngine.OpenDatabase(chemin_bd) 
Dans la 
clause ORDER BY  de la 
requête SQL , c'est la 
fonction RND  appliquée sur le 
champ de la clé primaire  (N°) qui permet de sélectionner un seul enregistrement (TOP 1) 
aléatoirement . De cet enregistrement, nous prélevons l'information de tous les champs (*). Il s'agit des champs issus de la table sélectionnée par le candidat dans la liste déroulante (FROM [" & Sujet.Value & "]). Vous notez l'emploi des crochets pour délimiter le nom de la table et éviter toute confusion. Certains questionnaires proposent en effet des espaces dans l'énumération.
Il s'agit désormais de pointer sur l'enregistrement résultant (méthode MoveFirst) pour prélever l'information de tous les champs (Propriété Fields) afin de l'inscrire dans la cellule dédiée de la 
feuille Mémoire .
A la suite du code VBA, ajouter les instructions suivantes : If (enr.RecordCount > 0) Then 
Nous restituons les données dans l'ordre logique, à partir de la ligne 5 pour toutes les colonnes comprises entre B et H. Cette inscription s'effectue toujours dans la mesure où la requête produit bien un résultat (enr.RecordCount > 0). En colonne H, vous notez l'insertion de l'information sur la bonne réponse à fournir. Elle servira de comparaison pendant le test. Cette feuille devra donc être masquée et protégée à l'issue.
Il ne nous reste plus qu'à fermer les connexions et vider les objets de base de données.
A la suite du code VBA, ajouter les instructions suivantes : enr.Close 
Comme précédemment, vous notez l'appel d'une procédure par anticipation. Cette 
procédure depart , placée en commentaire, servira à restituer les informations de la première question sur la 
feuille Evaluations . Nous la développerons dans la formation suivante.
Enregistrer les modifications et afficher le formulaire Connexion , 
L'exécuter en enfonçant la touche F5 du clavier , 
Saisir un identifiant valide, par exemple : 999999 , 
Cliquer sur le bouton Ok  pour procéder à l'identification, 
Dans la liste déroulante, choisir un thème, par exemple : Anglais Niveau 1 , 
Puis, cliquer sur le bouton Démarrer  désormais rendu disponible, 
Le code stoppant son exécution, le focus est rendu à l'
éditeur VBA . Il n'en serait rien avec une simulation complète consistant à exploiter le formulaire à l'ouverture du classeur. Nous sommes en effet toujours en phase de développement.
Si vous affichez la 
feuille Mémoire , vous notez l'inscription de la première question générée aléatoirement associée à toutes ses données. Si vous simulez une nouvelle 
connexion  en choisissant le même questionnaire, la question de départ change à nouveau. Si vous affichez la feuille Session, vous remarquez que toutes les informations du candidat sont archivées.
Dans la prochaine formation, nous devons développer le code permettant au candidat de s'évaluer sur les 20 questions générées aléatoirement. Il s'agira de comparer sa proposition avec le numéro archivé de la bonne réponse.
Le 
code VBA  complet de la 
procédure Demarrer_Click  est le suivant :
Private Sub Demarrer_Click()