Vous êtes sur la page 1sur 9

FORMATION VB ACCESS Dr YAHI MOHAMMED

Utilisation des Recordset VBA ACCESS


Généralités sur les Recordset
Toutes les recherches d'enregistrements et les accès aux données passent par
OpenRecordet (il n'y a pas de CreateRecordSet). Voici un exemple type de préparation à
l'accès aux données :

Dim MaTable As Recordset


Set MaTable =
DBEngine.Workspaces(0).Databases(0).OpenRecordset("T_Clie
nt")

Il existe 3 sortes de Recordset :

Dynaset Le plus souple. Permet des modifications sur des requêtes, mais c'est
le plus lent. N'accepte pas la méthode Seek

Table Le plus rapide, mais les Recordset de type table ne permettent pas les
requêtes. Ce genre de RecordSet permet la méthode Seek, la plus
rapide

Snapshot Photo du RecordSet à un moment donné. On ne peut ni ajouter, ni


modifier, ni supprimer un enregistrement dans un SnapShot.

Attention donc, lorsqu'on crée un RecordSet sans préciser si c'est un Dynaset, un Snapshot
ou un Table, Jet choisit le type qu'il pense le plus approprié. Mais comme toutes les
méthodes ne sont pas applicables sur tous les types de RecordSet, mieux vaut les déclarer
explicitement.

RecordSetClone
RecordSetClone est une instruction qui permet d'obtenir rapidement la copie conforme d'un
formulaire que l'on peut ensuite utiliser comme en DAO

L'exemple suivant reprend exactement ce qui se passe quand on demande une liste
déroulante avec l'assistant, et qu'on veut que le résultat du choix de cette liste cherche un
enregistrement dans ce même formulaire :

Dim CeFormulaire As Recordset, entI As Integer


Set CeFormulaire = Me.RecordsetClone
CeFormulaire.MoveFirst
MsgBox CeFormulaire("NomFruit")
CeFormulaire.Close

Move[X|Next|Last|Previous|First]
Cet exemple se positionne :

Sur le premier enregistrement


Sur le deuxième enregistrement
Sur le dernier enregistrement
Sur l'avant-dernier enregistrement
FORMATION VB ACCESS Dr YAHI MOHAMMED

De la table T_Client, et affiche le prénom de chacun.

Dim Enr As Recordset


Set Enr = CurrentDb.OpenRecordset("T_Client")
Enr.MoveFirst
MsgBox Enr("Prenom")
Enr.MoveNext
MsgBox Enr("Prenom")
Enr.MoveLast
MsgBox Enr("Prenom")
Enr.MovePrevious
MsgBox Enr("Prenom")

Atteinte des limites du RecordSet avec MoveXXX


Dim Enr As Recordset
Set Enr = CurrentDb.OpenRecordset("T_Client")
Enr.MoveLast ' Se positionne sur le dernier
enregistrement
MsgBox Enr.EOF ' Renvoie FAUX
Enr.MoveNext ' Ne crée pas d'erreur
MsgBox Enr.EOF ' Renvoie Vrai
MsgBox Enr("Prenom") ' Renvoie l'erreur "Pas
d'enregistrement courant"
Enr.MoveFirst ' Se positionne sur le premier
enregistrement
MsgBox Enr.BOF ' Renvoie FAUX
Enr.MovePrevious ' Ne crée pas d'erreur
MsgBox Enr.BOF ' Renvoie Vrai
MsgBox Enr("Prenom") ' Renvoie l'erreur "Pas
d'enregistrement courant"

Enr.MoveP
revious '
Renvoie
immédiate
ment une
erreur
puisque
nous
sommes
déjà
avant le
premier
enregistr
ement

Dans le cas ou le RecordSet ne contient aucun enregistrement, les méthodes MoveXXX


renvoient toutes une erreur. Les propriétés BOF et EOF sont toutes les deux vraies en même
temps.

Move X
Il est possible de se déplacer en avant comme en arrière de X enregistrement avec cette
méthode
FORMATION VB ACCESS Dr YAHI MOHAMMED

Cet exemple positionne le pointeur d'abord sur le premier enregistrement avec MoveFirst,
ensuite il avance de 3 enregistrements et revient en arrière de deux. Attention à ne pas
oublier de placer l'Index correctement pour ne pas avoir des surprises.

NomPersonne Prenom

defawes michel

pochon pierre

rivares maria

allen woody

Dim Enr As Recordset


Set Enr = CurrentDb.OpenRecordset("T_Personne")
Enr.MoveFirst
MsgBox Enr("NomPersonne") Affiche defawes
Enr.Move 3 Pointe sur allen
Enr.Move -1 Pointe sur rivares
MsgBox Enr("NomPersonne") affiche rivares

Dans le cas ou on essaie de se déplacer manifestement en dehors de la table par de trop


grandes valeurs de Move, pas d'erreur n'est générée si on ne demande pas le contenu. On
peut toujours tester si on seors de la table avec BOF et EOF

Utilisation des Index avec les MoveXXX


Soit la table T_Personne :

NomPersonne Prenom

de funès Louis

allen woody

delon alain

lhermitte thierry

Nous allons maintenant utiliser la méthode MoveFirst, mais avec des Index différents. La
table doit avoir ses deux champs indexés (NomPersonne et Prenom).

Dans ce premier cas, le MoveFirst nous envoie sur le premier enregistrement alphabétique
NomPersonne, càd ALLEN (Woody)

Dim rec As Recordset


Set rec = CurrentDb.OpenRecordset("T_Personne")
rec.Index = "NomPersonne"
rec.MoveFirst
MsgBox rec("Prenom") & " " & rec("NomPersonne")
FORMATION VB ACCESS Dr YAHI MOHAMMED

Dans ce deuxième cas, par contre, comme l'index est défini comme étant Prenom, le
MoveFirst nous renvoie sur le premier enregistrement du RecordSet, mais en prenant comme
base alphabétique Prenom, et c'est donc ALAIN (Delon) qui va sortir.

rec.Index = "Prenom"
rec.MoveFirst
MsgBox rec("Prenom") & " " & rec("NomPersonne")

Modifier les enregistrements


EOF, MoveNext, Edit, Update

Dans cet exemple, on ouvre la base de données test.mdb, on ouvre la table des fournisseurs,
on recherche les fournisseurs dont le nom est Kuhn, et on les remplace par Rivares. Ensuite,
on ferme la base de données.

Dim MaTable As Recordset


Set MaTable = CurrentDB.OpenRecordset("T_Client")
Do Until MaTable.EOF = True
If MaTable("NomClient") = "Kuhn" Then
MaTable.Edit
MaTable("NomClient") = "Rivares"
MaTable.UPDATE
End If
MaTable.MoveNext
Loop
MaTable.Close

Mise à jour : Update, CancelUpDate


Admettons que nous sommes dans un formulaire en mode continu, et que nous voyons
l'ensemble de tous nos enregistrements sur le même écran. Si on est dans un enregistrement
quelconque, et qu'on modifie par DAO la valeur d'un champ du premier enregistrement, tout
se passe bien, mais nous n'avons de preuve visuelle que lorsque nous cliquons sur un
champ appartement au premier enregistrement. Afin d'apporter immédiatement la preuve
visuelle, il faut appliquer la méthode Requery, comme dans l'exemple qui suit.

Dim Enr As Recordset


Set Enr = CurrentDb.OpenRecordset("T_Client")
Enr.MoveFirst
Enr.Edit
Enr("NomClient") = "POUPONNOT"
Enr.Update
' Et si on avait fait Enr.CancelUpdate, l'enregistrement
n'aurait pas été modifié
Enr.Close
Me.Requery

Date de création d'une table : DateCreated


Attention : DateCreated ne peut s'utiliser que sur des objets de type Table

Set TableFruit = CurrentDb.OpenRecordset("T_Fruit",


dbOpenTable)
Set TableFruit = CurrentDb.OpenRecordset("T_Fruit",
dbOpenDynaset) ' N'aurait pas permis DateCreated
MsgBox TableFruit.DateCreated
FORMATION VB ACCESS Dr YAHI MOHAMMED

A quelle position sommes nous ? AbsolutePosition


Il est possible de savoir au combientième enregistrement nous nous trouvons. Par exemple :

Dim TableFruit As Recordset


Set TableFruit = CurrentDb.OpenRecordset("T_Fruit",
dbOpenDynaset)
TableFruit.MoveFirst
MsgBox TableFruit.AbsolutePosition
' Absolute position = 0
TableFruit.MoveNext
MsgBox TableFruit.AbsolutePosition
' Absolute position = 1
TableFruit.MoveLast
' Absolute position = le nombre d'enregistrements moins 1
MsgBox TableFruit.AbsolutePosition
TableFruit.Close

Récupérer des enregistrements en tableau avec


GetRows
Il est possible de récupérer des enregistrement dans un tableau à l'aide de GetRows
(NombreDEnregistrements). Dans cet exemple, nous prenons cette table dont la propriété
Index est à NomPersonne. Nous imaginons également que nous sommes positionné sur le
premier enregistrement (woody allen), car nous pourrions être ailleurs avec la méthode
MoveXXX par exemple, auquel cas la récupération des données en tableau commencerait à
la position courante

IDPersonne NomPersonne Prenom Age

allen (1,0) woody (2,0)

defawes (1,1) michel (2,1)

delon (1,2) alain (2,2)

Dim enr As Recordset

Dim Contenu As Variant


Set enr = CurrentDb.OpenRecordset("Personne")
enr.Index = "NomPersonne"
Contenu = enr.GetRows(2) ' 2 est le nombre
d'enregistrements, numérotés de 0 à 1
MsgBox Contenu(0, 0) ' 4 (1er champ, 1er enregistrement)
MsgBox Contenu(0, 1) ' 1 (1er champ, 2ème enregistrement)
MsgBox Contenu(1, 0) ' Allen (2ème champ, 1er
enregistrement)
MsgBox Contenu(2, 0) ' Woody (3ème champ, 1er
enregistrement)
MsgBox Contenu(3, 0) ' 50 (4ème champ, 1er
enregistrement)
' Voici le dernier champ du dernier enregistrement
possible :
FORMATION VB ACCESS Dr YAHI MOHAMMED

MsgBox Contenu(3, 1) ' 32 (4ème champ, 2ème


enregistrement)
' MsgBox (4,0) engendre une erreur car ce serait le 5ème
champ (inexistant)
' MsgBox (0,2) engendre une erreur car le GetRows prévoit
le stockage des 2 premiers enregistrements rencontrés
numérotés de 0 à 1

Index
ATTENTION :

On crée T_Client
On y installe un champ DateNaissance
On l'indexe
On sauve la table
On renomme DateNaissance en DateDeNaissance

Le nom de l'index n'a pas changé : CurrentDB.TableDefs("T_Client").Indexes(0).Name


est toujours DateNaissance

Recherche d'enregistrements sur la base d'un index


Seek, NoMatch, Index, Edit, Update

Cet exemple montre comment on recherche dans une table tous les enregistrement dont
l’âge est égal à 7 pour les remplacer par 8 et de recommencer l’opération jusqu'à ce qu’il
ne reste plus d’enregistrements correspondants Attention cet exemple ne marche qu’avec
des tables, et le champ recherché par seek doit avoir la proprété indexé à oui. Bien entenu, la
méthode seek est bien plus rapide que la méthode find

Dim MaBD As Database, MaTable As Recordset


Set MaBD = DBEngine.Workspaces(0).Databases(0)
Set MaTable = MaBD.OpenRecordset("T_Client",
DB_OPEN_TABLE)
MaTable.Index = "Age"
Do Until MaTable.NoMatch
MaTable.Seek
If Not MaTable.NoMatch Then
MaTable.Edit
MaTable("Age") = 28
MaTable.Update
End If
Loop
MaTable.Close

Attention : La méthode Seek nous renvoie sur un des enregistrements correspondants, s'il en
existe, mais on ne pru pas faire

MsgBox Enr("NomClient")

Ca renvoie une erreur

Recherche d'un enregistrement avec


Find[First¦Next¦Last¦Previous]
FORMATION VB ACCESS Dr YAHI MOHAMMED

FindFirst

Dim Enr As Recordset


Set Enr = CurrentDb.OpenRecordset("Personne",
dbOpenDynaset)
Enr.FindFirst "Prenom = 'Pierre'"
MsgBox Enr("NomPersonne")
Enr.Close

FindFirst recherche le premier enregistrement correpondant aux critères paramétrés. Quand


FindFirst ne trouve aucun enregistrement correspondant, il se place sur le premier
enregistrement de la table (et encore, c'est pas sûr que ce soit le premier)

Attention _ J'ai testé la méthode FindFirst sur une base de données externe, et ça ne marche
que si le nom de la table ne contient pas de trait de soulignement.

Attention : Si on recherche un texte contenant une apostrophe, il faut la doubler pour que pas
d'erreur ne soir générée, comme ceci :

MonGroupe.FindFirst "Prenom = 'D''Artagnan'"

Il faut donc doubler automatiquement l'apostrophe, grâce à la fonction maison :

' Cette fonction double les apostrophes éventuels de la


chaîne de caractères
' Mot. Ensuite, elle ajoute une apostrophe devant et
derrière Mot.
Function Apostrophe(ByVal Mot As String) As String
If InStr(Mot, "'") > 0 Then
Mot = Left$(Mot, InStr(Mot, "'") - 1) & "''" & Right$(Mot, Len(Mot) -
InStr(Mot, "'"))
End If
Apostrophe = "'" & Mot & "'"
End Function

On pourra alors chercher correctement dans la table, comme ceci (Attention : Je constate que
si on omet la propriété Text de la zone d'édition de recherche, ça ne fonctionne plus.

MonGroupe.FindFirst "Prenom = " &


Desapostrophe(Me![edicherche].Text)

FindNext, FindLast, FindPrevious


Il est possible que plusieurs enregistrements correspondent aux critères de FindFirst. C'est
pourquoi existent les autres Find.

NomPersonne Prenom

defawes michel

pochon pierre

rivares maria

rochat pierre
FORMATION VB ACCESS Dr YAHI MOHAMMED

Dans cet exemple, on va rechercher la première occurence de Pierre, puis une deuxième,
puis une éventuelle 3ème. Mais comme cette troisième occurence n'existe pas, la propriété
NoMatch est mise à Vraie, et le pointeur d'enregistrement reste planté sur la dernière
occurence trouvée, sans faire d'erreur.

Dim Enr As Recordset


Set Enr = CurrentDb.OpenRecordset("Personne",
dbOpenSnapshot)
Enr.FindFirst "Prenom = 'pierre'" ' Se positionne sur
pierre pochon
' (Enr.FindNext "Prenom = 'pierre'" aurait aussi
fonctionné, j'ai testé)
MsgBox Enr.NoMatch ' FAUX
MsgBox Enr("NomPersonne") ' pochon
Enr.FindNext "Prenom = 'pierre'" ' Se positionne sur
pierre rochat
MsgBox Enr.NoMatch ' FAUX
MsgBox Enr("NomPersonne") ' rochat
Enr.FindNext "Prenom = 'pierre'" ' Reste simplement sur
pierre rochat
MsgBox Enr.NoMatch ' VRAI
MsgBox Enr("NomPersonne") ' rochat
Enr.Close

Effacer un enregistrement
Delete

Dans cet exemple, on efface le premier enregistrement dont le prénom est Pierre. Attention :
Il faut que ce soit un Dynaset ou un Table

Dim Enr As Recordset


Set Enr = CurrentDb.OpenRecordset("Personne",
dbOpenDynaset)
Enr.FindFirst "Prenom = 'pierre'"
Enr.Delete
Enr.Close

Baser un RecordSet sur une requête


Il est possible de soit baser un RecordSet sur une requête existante, ou directement en
écrivant le code SQL en guise de requête.

Dim Enr As Recordset


Set Enr = CurrentDb.OpenRecordset("R_Fournisseur")
MsgBox Enr("NomFournisseur")

Est équivalent à :

Dim Enr As Recordset


Set Enr = CurrentDb.OpenRecordset("SELECT * FROM
T_Fournisseur")
MsgBox Enr("NomFournisseur")

Voici un autre exemple ou, cette fois, la requête est paramétrée sur un formulaire de façon à
ce qu'elle extraie l'ensemble des enregistrements du sous-formulaire VenteDetail du
formulaire Vente. Il est a noter qu'il n'est pas possible de baser un RecordSet sur une requete
FORMATION VB ACCESS Dr YAHI MOHAMMED

parametree, car on dirait bien qu'Access refuse d'aller extraire un parametre (par exemple
dans un formulaire) au moment ou on le definit comme un Recordset. La seule solution reste
la chaine SQL comme dans l'exemple suivant :

Set RequeteListeDetailCetteVente =
CurrentDb.OpenRecordset("SELECT * FROM T_VenteDetail
Where IDVente = " & Me![IDVente])

Ajouter un nouvel enregistrement à une table avec


AddNew
AddNew, Update

Dim MaTable As Recordset


Set MaTable = CurrentDB.OpenRecordset("T_Client",
DB_OPEN_TABLE)
MaTable.AddNew
MaTable("NomClient") = "Dupont"
MaTable.Update
MaTable.Close

La même chose en utilisant With :

With

Dim MaBase As DATABASE, rst As Recordset


Set MaBase = CurrentDb
Set JeuEnregistrement = MaBase.OpenRecordset("T_Client")
With JeuEnregistrement
.AddNew
![NomClient] = "Russell"
![Prenom] = "Peter"
.UPDATE
End With
MaBase.Clos

Vous aimerez peut-être aussi