formateur informatique

Sélections aléatoires d'enregistrements de tables Access

Accueil  >  Bureautique  >  Access  >  Access VBA  >  Sélections aléatoires d'enregistrements de tables Access
Livres à télécharger


Pour partager cette vidéo sur les réseaux sociaux ou sur un site, voici son url :


Inscription Newsletter    Inscription Newsletter
Sujets que vous pourriez aussi aimer :


Jeu aléatoire d'enregistrements

Savoir générer un jeu d'enregistrements aléatoires n'est pas du tout futile contrairement à ce que l'on pourrait croire. Dans le cas d'une application d'évaluation par QCM, il est intéressant de pouvoir proposer un groupe de questions toujours différent. C'est ainsi qu'une évaluation n'est jamais la même, y compris pour un même candidat, d'un test à un autre. Cette nouvelle astuce VBA Access démontre comment choisir des questions au hasard.

Générer des questions aléatoirement en VBA Access

Dans l'exemple illustré par la capture, l'utilisateur choisit un thème d'évaluation à l'aide d'une liste déroulante. Chaque thème proposé correspond au nom d'une table. Et lorsque l'utilisateur clique sur le bouton Générer, ce sont dix questions qui sont extraites aléatoirement de la table ainsi désignée. A chaque nouveau clic, les questions changent complètement et bien sûr, aucun doublon n'est proposé dans un même jeu.

Base de données Access à télécharger
Pour la découverte de cette technique, nous suggérons d'appuyer l'étude sur une base de données offrant ces questionnaires. Bien qu'anciens, ils feront l'affaire. Le volet de navigation, sur la gauche de l'écran, présente les sept tables des questionnaires et le formulaire nommé fQuestions.

Si vous double cliquez sur l'une ou l'autre table, vous remarquez qu'elles ont toutes la même architecture. Les questions sont toutes énumérées dans un champ nommé QUESTION.
  • Dans le volet de navigation, double cliquer sur le formulaire fQuestions,
  • Dès lors, déployer la liste déroulante sur la gauche et choisir un thème,
Comme vous le constatez, ces thèmes sont issus des noms des tables.

Choisir un questionnaire de nom de table avec une liste déroulante sur un formulaire Access

Bien sûr et fort logiquement à ce stade, si vous cliquez sur le bouton Générer, aucun jeu d'enregistrements aléatoires n'est encore produit.

Liste déroulante des noms de tables
Mais comme vous avez pu le constater, la liste est automatiquement chargée des noms des tables, donc des intitulés des questionnaires. Et tout cela se produit au chargement du formulaire par un code VBA offert.
  • A gauche du ruban Accueil, cliquer sur la flèche du bouton Affichage,
  • Dans la liste des propositions, choisir le mode Création,
  • Dès lors, cliquer sur le carré grisé en haut à gauche, à l'intersection des règles,
Sélectionner le formulaire Access pour le personnaliser

De cette manière, nous désignons le formulaire parent explicitement.
  • Activer l'onglet Evénement de sa feuille de propriétés,
Vous remarquez la présence d'une procédure événementielle attachée à son événement Sur activation. Ce code se déclenche notamment à chaque chargement du formulaire et il concerne la liste déroulante.
  • Cliquer sur le petit bouton situé à l'extrémité droite de cet évenement,
De cette manière, nous basculons dans l'éditeur VBA Access entre les bornes de la procédure événementielle Form_Current :

Private Sub Form_Current()
Dim base As Database
Dim table As TableDef

Set base = CurrentDb()

For Each table In base.TableDefs
If Left(table.Name, 4) <> "MSys" Then
Questionnaire.AddItem table.Name
End If
Next table

base.Close
Set table = Nothing
Set base = Nothing
End Sub


Il s'agit d'un code VBA Access que nous avons conçu à l'occasion de la précédente astuce. Il parcourt toutes les tables de la base de données pour charger leurs noms (Méthode AddItem) dans la liste déroulante.



Générer au clic
Désormais, nous devons créer la procédure de code qui doit se déclencher au clic sur le bouton pour générer des questionnaires aléatoires.
  • Revenir sur le formulaire en conception,
  • Cliquer sur le bouton Générer pour le sélectionner,
  • Dans sa feuille de propriétés, cliquer sur le petit bouton associé à son événement Au clic,
Nous revenons ainsi dans l'éditeur VBA Access, mais cette fois entre les bornes de la procédure generer_Click. Son code se déclenchera naturellement au clic sur ce bouton.

Private Sub generer_Click()

End Sub


Son code est naturellement vide pour l'instant. C'est forcément lui que nous devons implémenter pour générer ces questionnaires aléatoires sur ordre.

Les objets de base de données
Ensuite et pour pouvoir accéder aux enregistrements des tables, nous devons déclarer des objets permettant de piloter cette base de données. Il s'agit de déclarations et affectations de variables que nous maîtrisons bien désormais.
  • Dans les bornes de la procédure, ajouter les déclarations suivantes :
...
Dim base As Database: Dim enr As Recordset
Dim nomTable As String: Dim compteur As Byte
Dim nbEnr As Integer: Dim numEnr As Integer
Dim mem As String
...


Nous déclarons un objet de type Database pour piloter la base de données en cours et un objet de type Recordset pour manipuler les enregistrements des tables de cette base. Les déclarations qui suivent sont plus classiques. Nous mémoriserons le choix du questionnaire dans la variable nomTable, typée comme un texte. La variable compteur doit compter les enregistrements restitués pour limiter la sélection à dix questions. Nous stockerons le nombre total d'enregistrements de la table dans la variable nbEnr. Nous génèrerons les numéros à atteindre dans la variable numEnr. Enfin, la variable mem, typée comme un texte, est destinée à mémoriser tous les numéros d'enregistrements générés aléatoirement pour ne pas les reproposer. Et nous verrons bientôt comment nous allons nous y prendre.

Vérifier le choix du questionnaire
Avant de poursuivre, nous devons nous assurer que l'utilisateur a bien choisi un questionnaire, donc une table. C'est seulement si la liste déroulante de choix porte une valeur que la suite du traitement VBA peut être entreprise.
  • Après la déclaration des variables, ajouter les instructions VBA suivantes :
...
If (Questionnaire.Value <> "") Then
mem = "-": Randomize
compteur = 0: nomTable = Questionnaire.Value

Set base = CurrentDb()
Set enr = base.OpenRecordset(nomTable)
End If
...


L'instruction conditionnelle permet de tester le contenu de la liste déroulante nommée Questionnaire. Si elle porte bien une valeur (<>""), alors (Then) nous engageons le traitement. Et pour cela, nous entamons l'initialisation des variables. Nous inscrivons un tiret dans la variable mem. Nous allons effectivement mémoriser les numéros générés, séparés par des tirets pour éviter toute confusion. En vue de la génération aléatoire à venir, nous appelons la fonction VBA Randomize. Elle permet d'initialiser le processus sur l'horloge système afin d'assurer de vraies générations au hasard. Nous prélevons ensuite le choix du questionnaire dans la variable nomTable. Puis, nous nous occupons des variables de BDD. Grâce à la fonction CurrentDb, nous initialisons la variable base qui de fait, hérite des propriétés et méthodes pour piloter la base de données en cours. Et pour preuve dans l'enchaînement, nous initialisons la variable enr grâce à sa méthode OpenRecordset ainsi héritée. En lui passant le nom de la table choisie par l'utilisateur, elle fournit à la variable enr, les enregistrements à manipuler.



Compter les enregistrements de la table
Avant de chercher à manipuler les enregistrements, nous devons déjà nous assurer qu'ils existent. Et pour cela, nous pouvons exploiter la propriété RecordCount d'un objet de type Recorset. Nous aurons ainsi la borne supérieure absolument essentielle pour entreprendre une génération aléatoire de numéros à tirer au sort.
  • A la suite, mais toujours dans le bloc du If, ajouter les instructions VBA suivantes :
...
Set base = CurrentDb()
Set enr = base.OpenRecordset(nomTable)

If enr.RecordCount <> 0 Then
nbEnr = enr.RecordCount
lesQuestions.Value = "<u><strong>10 questions aléatoires:</strong></u><br />"
End If

End If
...


Si la table choisie offre bien des enregistrements (enr.RecordCount <> 0), alors nous mémorisons ce nombre dans la variable nbEnr. Puis, nous initialisons le titre de la zone de texte multiligne avec des attributs de mise en forme grâce à des balises Html.

Boucle de génération aléatoire
Maintenant que la borne supérieure est connue, nous devons engager le traitement dans une boucle. Son rôle est de produire dix numéros d'enregistrements au hasard et tous différents les uns des autres. C'est la variable compteur qui doit servir de test. Tant que les dix nombres n'ont pas été produits, le traitement doit recommencer.
  • A la suite de cette seconde instruction conditionnelle, ajouter les lignes VBA suivantes :
...
Set enr = base.OpenRecordset(nomTable)

If enr.RecordCount <> 0 Then
nbEnr = enr.RecordCount
lesQuestions.Value = "<u><strong>10 questions aléatoires:</strong></u><br />"

While compteur < 10
With enr

End With
compteur = compteur + 1
Wend

End If
End If
...


Tant que les dix nombres ne sont pas générés (While compteur < 10), nous poursuivons le traitement. Celui-ci va bien sûr consister à tirer au sort des numéros d'enregistrements de la table pour en restituer aléatoirement les questions. Dans cette boucle et à des fins d'optimisation de code, nous créons un bloc With sur la variable enr. En effet, nous allons appeler quelques propriétés et méthodes de cet objet. Autant les regrouper pour ne pas répéter à chaque occasion le nom de cet objet. Enfin, nous n'oublions pas d'incrémenter la variable de boucle (compteur = compteur + 1).



Numéros aléatoires d'enregistrements
Nous atteignons désormais l'étape cruciale. C'est maintenant que nous devons générer dix numéros aléatoires d'enregistrements, tous différents les uns des autres. Et pour cela, nous allons stocker chaque nombre produit dans la variable mem. Ainsi à chaque nouvelle génération, nous vérifierons si le numéro produit n'est pas déjà inscrit dans cette variable.
  • Dans le bloc With, ajouter les instructions VBA suivantes :
...
With enr
refaire:
numEnr = Int((nbEnr) * Rnd) + 1
If (InStr(1, mem, "-" & numEnr & "-") <> 0) Then
GoTo refaire
Else
mem = mem & numEnr & "-"
End If

End With
...


Nous créons tout d'abord une étiquette nommée refaire. Elle fait figure de point de référence. Nous y renverrons le code VBA tant que le numéro généré a déjà été proposé. C'est une sorte de boucle, aux bornes aléatoires, à l'intérieur même de la boucle While. Nous générons ensuite le numéro aléatoire entre le premier et le dernier enregistrement selon cette formule : Int((borneSup -borneInf + 1) * Rnd + borneInf). Grâce à la fonction Instr, nous vérifions sa présence encadrée de tirets dans la variable mem. Si cette fonction renvoie une position (<>0), cela signifie que le numéro a déjà été proposé. Nous renvoyons donc le code à l'étiquette (GoTo refaire) pour recommencer la génération. Dans le cas contraire (else), nous mémorisons ce numéro à la suite des autres et suffixé d'un tiret.



Déplacer le curseur sur l'enregistrement aléatoire
Désormais à chaque passage dans cette boucle While et pour chaque nouveau numéro généré, nous devons nous déplacer sur l'enregistrement correspondant dans la table. C'est ainsi que nous pourrons prélever ses informations, en l'occurrence ici, il s'agit de ponctionner la question du champ QUESTION.
  • A la suite du bloc With, ajouter les trois instructions VBA suivantes :
...
With enr
refaire:
numEnr = Int((nbEnr) * Rnd) + 1
If (InStr(1, mem, "-" & numEnr & "-") <> 0) Then
GoTo refaire
Else
mem = mem & numEnr & "-"
End If
.MoveFirst
.Move numEnr - 1
lesQuestions.Value = lesQuestions.Value & "<br />" & compteur + 1 & "/ Num : " & numEnr & " : " & .Fields("QUESTION")

End With
...


Nous plaçons tout d'abord le pointeur de lecture sur le tout premier enregistrement de la table grâce à la méthode MoveFirst de l'objet enr. C'est ainsi que nous pouvons entreprendre un déplacement vers le bas jusqu'au numéro généré grâce à la méthode Move de ce même objet. Nous enlevons une unité à ce score (-1) puisque le pointeur est déjà placé sur le premier enregistrement, donc déjà décompté. Ensuite, nous concaténons simplement les informations récoltées les unes en dessous des autres (<br />) dans la zone de texte multiligne (lesQuestions). Et c'est la propriété Fields de l'objet enr qui permet de pointer sur le champ par son nom.

Nous n'en avons pas tout à fait terminé. Comme vous le savez, les objets de base de données, quand ils ne sont plus utilisés, doivent être fermés et détruits. C'est ainsi que nous libérons les ressources.
  • A la toute fin du code avant le End Sub, ajouter les quatre instructions VBA suivantes :
...
Wend
End If
End If

enr.Close
base.Close
Set base = Nothing
Set enr = Nothing


End Sub
...


Simplement, nous fermons la connexion aux enregistrements et à la base de données grâce à la méthode Close des objets respectifs. Puis, nous les détruisons de la mémoire en les réinitialisant (Set) sur la valeur Nothing.
  • Enregistrer les modifications (CTRL + S) et basculer sur le formulaire (ALT + Tab),
  • L'enregistrer à son tour et l'exécuter avec la touche F5 du clavier,
  • Choisir un questionnaire avec la liste déroulante et cliquer sur le bouton Générer,
Générer des questions aléatoirement en VBA Access

Comme vous pouvez l'apprécier à chaque clic, c'est un lot de dix nouvelles questions aléatoires qui est proposé.

 
Sur Facebook
Sur Youtube
Les livres
Contact
Mentions légales



Abonnement à la chaîne Youtube
Partager la formation
Partager sur Facebook
Partager sur Twitter
Partager sur LinkedIn