Pour partager cette vidéo sur les réseaux sociaux ou sur un site, voici son url :
Sujets que vous pourriez aussi aimer :Parcourir les enregistrements d'une table
Avec cette nouvelle
astuce VBA Access, nous allons découvrir une technique intéressante et efficace pour
parcourir toutes les données d'une table. Ici, il n'est pas question d'exercer une requête pour accéder aux informations. De plus, nous allons voir comment
parcourir ces enregistrements en
sens inverse, soit du dernier au premier.
Sur l'exemple illustré par la capture, l'utilisateur clique sur un bouton placé à droite d'une zone de texte multiligne. Dès lors, les
enregistrements de la
table Parc sont restitués progressivement les uns en dessous des autres. C'est la
fonction VBA Timer qui gère ces
intervalles de temps pour bien rendre compte du processus permettant de
parcourir les enregistrements un à un et pour chacun, de récolter les informations de tous les champs.
Base de données Access à télécharger
Pour la mise en place de cette
astuce Access, nous proposons d'appuyer l'étude sur une
base de données offrant déjà ce
formulaire.
- Télécharger le fichier compressé parcourir-enregistrements-vba.rar en cliquant sur ce lien,
- Puis, le décompresser dans le dossier de votre choix,
- Dès lors, double cliquer sur le fichier résultant pour l'ouvrir dans Access,
- Cliquer sur le bouton Activer le contenu du bandeau de sécurité,
- Puis, dans le volet de navigation sur la gauche, double cliquer sur le formulaire fParcourir,
Ainsi, nous l'affichons en mode exécution. La zone de texte et le bouton sont bien présents. Mais à ce stade bien sûr, si vous cliquez sur le bouton, rien ne se produit encore.
Associer un code au clic sur le bouton
Nous devons donc commencer par déclencher une
procédure VBA lorsque l'utilisateur clique sur le
bouton Récupérer. Et pour cela, nous allons exploiter la feuille de propriétés.
- A gauche du ruban Accueil, cliquer sur la flèche du bouton Affichage,
- Dans les propositions, choisir le mode Création,
Dans cette vue en conception du formulaire, si la
feuille de propriétés n'est pas visible dans votre environnement, sachez que vous pouvez l'afficher en cliquant sur le
bouton Feuille de propriétés du
ruban Conception de formulaires ou
Création selon les versions.
- Cliquer sur le bouton Récupérer pour le sélectionner,
- Cliquer sur l'onglet Evénement de sa feuille de propriétés,
- Cliquer sur le petit bouton à trois points (...) de son événement Au clic,
- Dans la boîte de dialogue qui suit, choisir le Générateur de code et valider par Ok,
Nous basculons ainsi dans l'
éditeur Visual Basic Access entre les bornes de la
procédure événementielle recuperer_Click. Son code se déclenchera au clic sur le bouton.
Déclarer et affecter les variables
Nous avons besoin de variables pour piloter la base de données et ses enregistrements, mais pas seulement.
- Dans les bornes de la procédure, ajouter les déclarations et affectations suivantes :
...
On Error Resume Next
Dim base As Database: Dim enr As Recordset
Dim delai: Dim debut
delai = 0.5
donnees.Value = ""
...
Avant même la déclaration des variables, nous engageons une instruction pour
intercepter les erreurs (On Error Resume Next). En effet, nous engagerons une
boucle pour
parcourir tous les enregistrements du dernier au premier. Mais une fois le premier atteint, lorsqu'elle tentera d'accéder à celui du dessus, elle échouera. Nous lui demandons d'ignorer cet état de fait pour ne pas compromettre la suite du traitement. Ensuite, nous déclarons une
variable base pour prendre possession de la
base de données en cours et une
variable pour piloter ses
enregistrements. Il va bien falloir parcourir ceux de la
table Parc en effet. Les
variables delai et
debut ne sont pas typées. Nous les utiliserons pour les incréments de temps. Nous fixons le délai d'affichage sur une demi seconde (delai = 0.5) et nous réinitialisons la zone de texte multiligne (donnees.Value = "") si d'aventure plusieurs extractions étaient entreprises dans l'enchaînement.
Les objets de base de données
Désormais, nous avons besoin d'initialiser les
objets de base de données pour prendre possession de la
base de données en cours et de ses
enregistrements.
- A la suite du code de la procédure, ajouter les affectations suivantes :
...
Set base = CurrentDb()
Set enr = base.OpenRecordset("Parc")
...
La
fonction CurrentDb pointe sur la
base de données en cours. De fait, elle confère à l'
objet base toutes les
propriétés et méthodes pour la piloter. Dès lors, nous exploitons sa
méthode OpenRecordset pour pointer sur la
table Parc. Et c'est désormais la
variable objet enr qui dirige ses enregistrements.
Optimiser le code VBA
Pour
parcourir les enregistrements et récolter les informations inhérentes, nous allons devoir exploiter l'
objet de type Recordset des enregistrements à de multiples reprises. Il est donc de bon ton d'optimiser le code avec une
instruction de branchement with.
- A la suite du code VBA, ajouter le bloc with comme suit :
...
With enr
End With
...
Ainsi et pour agir, nous n'aurons plus qu'à énumérer ses propriétés et méthodes préfixées d'un point (.) pour les appeler.
Placer le pointeur sur le dernier enregistrement
Pour
parcourir les enregistrements de la table du dernier au premier, nous devons commencer par placer le pointeur de lecture sur le
dernier de ces enregistrements. Et pour cela, l'
objet enr propose la
méthode MoveLast.
- Dans les bornes du bloc with, ajouter les instructions VBA Access suivantes :
...
With enr
If .RecordCount <> 0 Then
.MoveLast
End If
End With
...
Tout d'abord nous exploitons la
propriété RecordCount de l'
objet de type RecordSet pour vérifier qu'il existe bien des
enregistrements dans cette
table Parc. Si c'est le cas, nous exploitons la
méthode MoveLast pour placer le pointeur de lecture sur le tout dernier d'entre eux.
Parcourir les enregistrements du dernier au premier
Maintenant, nous avons besoin d'une
boucle partant de ce
dernier enregistrement pour les parcourir tous en remontant jusqu'au premier. Nous connaissions la
propriété VBA EOF (End Of File) pour atteindre la fin de la liste. Nous allons découvrir son homologue
BOF (Begin Of File) pour atteindre le début de la liste.
- A la suite du code du bloc With, ajouter la boucle suivante :
...
With enr
If .RecordCount <> 0 Then
.MoveLast
Do
.MovePrevious
Loop While Not .BOF
End If
End With
...
A chaque passage, cette boucle place le pointeur de lecture sur l'enregistrement précédent grâce à la
méthode MovePrevious de l'
objet enr. Et elle fait cela, tant que le début des enregistrements n'est pas atteint (While Not .BOF).
Récolter les valeurs des champs des enregistrements
Mais avant de poursuivre son processus de lecture, pour chaque enregistrement en cours d'analyse, cette
boucle doit restituer les informations de l'enregistrement en cours. Et pour cela, un
objet de type RecordSet propose la
propriété Fields qui permet d'accéder au contenu de chacun de ses champs en précisant le nom de ce dernier en paramètre.
- Dans les bornes de la boucle, avant la méthode, ajouter l'instruction VBA suivante :
...
If .RecordCount <> 0 Then
.MoveLast
Do
donnees.Value = donnees.Value & .Fields("Marque").Value & " " & .Fields("Modèle").Value & " - " & .Fields("chevaux").Value & "<br />"
.MovePrevious
Loop While Not .BOF
...
Dans la
zone de texte multiligne nommée
donnees, nous concaténons les informations des champs pour l'enregistrement en cours avec les précédents (donnees.Value = donnees.Value & ...). Et pour cela, nous exploitons la
propriété Fields de l'
objet Recordset en lui passant à chaque reprise le
nom du champ dont nous souhaitons récupérer le contenu grâce à sa
propriété Value. Notez l'usage de la
balise Html <br /> pour passer à la ligne. En effet, la
propriété Format du texte de ce contrôle est réglée sur
Texte enrichi. Vous pouvez le constater en sélectionnant cette zone sur le formulaire et en consultant cet attribut dans l'
onglet Données de sa
feuille de propriétés. Dans ces circonstances, ce sont en effet des balises Html qui régissent les attributs de mise en forme et les actions au clavier.
Fermer les objets de base de données
Une fois que les objets de base de données ont été utilisés, ils doivent être fermés et vidés pour libérer les ressources.
- En conséquence, après le bloc With, ajouter les instructions VBA suivantes :
...
End With
enr.Close
base.Close
Set enr = Nothing
Set base = Nothing
...
Grâce à la
méthode Close nous fermons l'objet des enregistrements et celui de la base de données. Puis, nous les détruisons en les réaffectant Ã
Nothing pour les vider complètement de la mémoire.
Nous pouvons maintenant tester le programme pour voir si la récolte est bonne.
- Enregistrer les modifications (CTRL + S) et basculer sur le formulaire (ALT + Tab),
- L'enregistrer à son tour (CTRL +S) pour mettre à jour la liaison avec la macro,
- Puis, l'exécuter avec la touche F5 du clavier,
- Dès lors, cliquer sur le bouton Récupérer,
Comme vous pouvez l'apprécier, toutes les informations de chaque enregistrement sont récupérées et consolidées ligne à ligne et ce, en partant du dernier pour rejoindre le premier.
Récupérer les enregistrements progressivement
Pour parachever la solution et suivre le processus se dérouler visuellement, nous proposons de marquer un
temps d'arrêt entre chaque enregistrement réceptionné. Et pour cela, nous avons besoin de la
fonction VBA Timer que nous avions démontrée à l'occasion de la
formation VBA Access pour archiver les données.
- Revenir dans le code de la procédure VBA, plus précisément dans les bornes de la boucle Do,
- Au début de la boucle, ajouter les instructions VBA suivantes :
...
Do
debut = Timer
Do While Timer < debut + delai
DoEvents
Loop
donnees.Value = donnees.Value & .Fields("Marque").Value &" " & .Fields("Modèle").Value & " - "& .Fields("chevaux").Value & "<br />"
.MovePrevious
Loop While Not .BOF
...
Grâce à la
fonction Timer, nous initialisons la
variable debut non typée sur le temps qu'il est précisément à la seconde près. Dès lors, nous entreprenons une
boucle qui tourne dans le vide tant que le temps qui court n'a pas dépassé l'ancien d'une demi-seconde. Et nous exploitons la
fonction DoEvents pour rendre la main à l'utilisateur et au processeur. C'est ainsi que les actions peuvent se dérouler chronologiquement et visuellement sur le formulaire. A chaque passage, lorsque la
boucle de temps est dépassée, les informations de l'enregistrement suivant sont ainsi prélevées.
Désormais, si vous enregistrez les modifications et que vous cliquez sur le
bouton Récupérer, vous voyez apparaître les enregistrements tour à tour, en respectant un délai d'intervention imposé par la
fonction Timer. Et si toutefois vous doutiez du bon fonctionnement du processus, pour pouvez ouvrir la
table Parc pour vérifier que les données sont bien récoltées en sens inverse, à partir du dernier enregistrement jusqu'au premier. A l'issue, les
objets de base de données sont détruits comme nous l'avons programmé, pour un code optimisé et peu gourmand.
Le
code VBA Access que nous avons construit est le suivant :
...
Private Sub recuperer_Click()
On Error Resume Next
Dim base As Database: Dim enr As Recordset
Dim compteur As Integer
Dim delai: Dim debut
compteur = 1: delai = 0.5
donnees.Value = ""
Set base = CurrentDb()
Set enr = base.OpenRecordset("Parc")
With enr
If .RecordCount <> 0 Then
.MoveLast
Do
debut = Timer
Do While Timer < debut + delai
DoEvents
Loop
donnees.Value = donnees.Value & .Fields("Marque").Value & " " & .Fields("Modèle").Value & " - " & .Fields("chevaux").Value & "<br />"
.MovePrevious
Loop While Not .BOF
End If
End With
enr.Close
base.Close
Set enr = Nothing
Set base = Nothing
End Sub
...