FAQ MS-Access
FAQ MS-AccessConsultez toutes les FAQ
Nombre d'auteurs : 140, nombre de questions : 926, dernière mise à jour : 15 juin 2021
- Comment exécuter/utiliser du SQL dans VBA ?
- Comment créer un jeu de données (Recordset) ?
- Comment parcourir un jeu d'enregistrements (Recordset) ?
- Pourquoi une erreur d'exécution '13' « Incompatiblité de type » ?
- Comment utiliser les méthodes FindFirst/FindLast/FindNext/FindPrevious ou la méthode Seek ou la méthode Find avec un Recordset ?
- Comment supprimer des enregistrements lorsque l'intégrité référentielle est activée ?
- Je n'arrive pas à supprimer ma table. Pourquoi ?
- Comment effacer toutes les données de la base ?
- Comment exécuter une requête action (ajout, suppression ou mise à jour) ?
- Comment supprimer les messages d'alertes ?
- Pourquoi les messages d'avertissement n'apparaissent-ils pas lorsque j'exécute mes requêtes action en VBA ?
- Comment insérer dans une table une chaîne de caractères contenant des quotes ?
- Comment tester l'existence d'une requête en VBA et la supprimer ?
- Pourquoi ma requête ne fonctionne-t-elle pas selon le type des variables qu'elle utilise ?
- Comment insérer des enregistrements de la table1 dans la table2, puis effacer ces enregistrements de la table1 ?
- Comment faire une requête qui recherche les doublons dans une table ?
- Comment se connecter en ADO à une base de données pour exécuter une requête action ?
- Est-il plus performant de faire appel à une requête enregistrée (OpenQuery) ou bien de l'écrire dans le code (VBA) et de l'exécuter avec DoCmd.RunSql ?
- Est-il possible de créer une requête paramétrée dont la valeur du paramètre proviendrait d'une variable ?
- Comment définir en VBA le SQL d'une requête existante ?
- Comment personnaliser le message d'erreur d'Access lors de doublons ?
- Comment chercher les enregistrements contenant une certaine chaîne (like) ?
- Pour insérer des données, vaut-il mieux passer par un Recordset ou par une requête de type INSERT ?
- Comment supprimer l'apparition des messages d'avertissement pour toute l'application ?
- Comment récupérer le résultat de ma requête en VBA ?
Voici deux liens.
Le premier vous amènera aux Recordsets, qui servent à exploiter les requêtes de sélection (SELECT).
Le second vous expliquera comment exécuter des requêtes d'action (INSERT [insertion], UPDATE [mise à jour], ...).
Lien : Comment créer un jeu de données (Recordset) ?
Lien : Comment exécuter une requête action (ajout, suppression ou mise à jour) ?
DAO
Sub
DAOOpenRecordset (
)
Dim
db As
DAO.Database
, rst As
DAO.Recordset
, fld As
DAO.Field
Dim
sSQL As
String
' Ouverture de la base de données
Set
db =
DBEngine.OpenDatabase
(
".\Comptoir.mdb"
)
sSQL =
"Select * From CLIENTS Where Région= \'WA\'"
' Ouverture du Recordset
Set
rst =
db.OpenRecordset
(
sSQL, dbOpenForwardOnly, dbReadOnly)
' Fermeture du Recordset
rst.Close
End
Sub
Notes
-> Il est important d'écrire "DAO." lors de la déclaration.
-> Pensez également à cocher la référence Microsoft DAO 3.6 Object Library (dans un module faites Outils / références).
ADO
Sub
ADOOpenRecordset (
)
Dim
cnn As
New
ADODB.connection
, rst As
New
ADODB.Recordset
, fld As
ADODB.Field
' Ouverture de la connexion
cnn.Open
"Provider=Microsoft.Jet.OLEDB.4.0;"
&
"Data Source=.\Comptoir.mdb;"
' Ouverture du Recordset en défilement en avant, et en lecture seule
rst.Open
"SELECT * FROM Clients WHERE Région =\'WA\'"
, cnn, adOpenForwardOnly
, adLockReadOnly
' Fermeture du Recordset
rst.Close
End
Sub
Lien : Définition et manipulation de données avec DAO par Tofalu
Lien : Comment déclarer une référence dans MS Access ?
Pour exécuter ce code, il faut activer la référence : Microsoft DAO 3.x Object Library.
Ces exemples permettent de parcourir un Recordset
If
Not
oRecordset.EOF
Then
Rst.MoveFirst
While
Not
rst.Eof
' Code
rst.MoveNext
Wend
else
Msgbox
"Le jeu d'enregistrements est vide"
End
if
Ou
Do
Until
rst.Eof
' Code
rst.MoveNext
Loop
Lien : Définition et manipulation de données avec DAO par Tofalu
Lien : Comment déclarer une référence dans MS Access ?
Modifiez la déclaration du Recordset :
Dim
Rst as
DAO.RecordSet
Nous rajoutons le DAO devant RecordSet afin d'éviter les conflits entre bibliothèques ayant certains objets portant le même nom.
En effet ici, les bibliothèques DAO et ADODB possèdent chacune un objet nommé "RecordSet". Ainsi, en écrivant DAO.RecordSet nous savons à quelle bibliothèque nous faisons appel.
Lorsque la bibliothèque n'est pas précisée, le type choisi par défaut correspond à celui de la première bibliothèque compatible référencée dans le projet VBA (en partant du haut).
Pour exécuter ce code, il faut activer la référence : Microsoft DAO 3.x Object Library.
Lien : Pourquoi une erreur de compilation : « Type défini par l'utilisateur non défini » ?
Lien : Définition et manipulation de données avec DAO par Tofalu
Lien : Comment déclarer une référence dans MS Access ?
Pour un DAO.Recordset
Pour exécuter ce code, il faut activer la référence : Microsoft DAO 3.x Object Library.
- Si le Recordset est de type Table (dbOpenTable) : utilisez la méthode Seek.
Celle-ci requiert l'utilisation d'une table indexée (voir l'aide pour plus d'infos).
Lorsque vous utilisez la méthode OpenRecordset, si vous ne précisez pas l'argument type, VBA créera par défaut un Recordset de type Table si celui-ci est basé sur une table.
- Pour les autres types de Recordset : utilisez les méthodes FindFirst / FindLast / FindNext / FindPrevious.
Pour un ADODB.Recordset
Pour exécuter ce code, il faut activer les références : Microsot ADO Ext 2.X for dll and security et Microsof ActiveX Data Object 2.X Library.
Utilisez la méthode Find.
Lien : Définition et manipulation de données avec DAO par Tofalu
Lien : Comment déclarer une référence dans MS Access ?
On ne peut effacer la clé primaire sans effacer les clés étrangères correspondantes.
L'intégrité référentielle est un mécanisme de vérification qui s'assure à chaque ajout, modification ou suppression d'une clé (étrangère ou primaire) qu'il y aura toujours la clé primaire correspondant à la clé étrangère.
Cependant il est parfaitement possible de supprimer des clés étrangères.
Vous essayez de supprimer une table sans succès en utilisant une requête de type "DROP TABLE" ou en utilisant la commande DeleteObject.
Cela provient certainement d'un Recordset chargé avec les données de la table. Cette dernière est alors considérée comme "verrouillée" et donc impossible à supprimer.
Il suffit de fermer le Recordset pour déverrouiller la table :
MonRecordSet.Close
Cette ligne doit bien sûr être placée avant la suppression.
Voici comment effacer le contenu d'une table :
dim
SQL as
string
SQL =
"Delete * From TABLE"
Docmd.RunSQL
SQL
Il suffit de réitérer l'action pour chaque table.
On peut aussi imaginer récupérer le nom de toutes les tables dans un tableau, et pour chaque table exécuter la suppression.
DAO
Pour exécuter ce code, il faut activer la référence : Microsoft DAO 3.x Object Library.
Sub
DAOExecuteBulkOpQuery
(
)
Dim
db As
DAO.Database
Set
db =
DBEngine.OpenDatabase
(
".\Comptoir.mdb"
)
' Exécution de la requête
db.Execute
"Update CLIENTS Set PAYS = \'États-Unis\' Where PAYS = \'USA\'"
Debug.Print
"Records Affected = "
&
db.RecordsAffected
db.Close
End
Sub
ADO
Pour exécuter ce code, il faut activer les références : Microsot ADO Ext 2.X for dll and security et Microsof ActiveX Data Object 2.X Library.
Sub
ADOExecuteBulkOpQuery
(
)
Dim
cnn As
New
ADODB.connection
, iAffected As
Integer
Dim
sSQL As
String
cnn.Open
"Provider=Microsoft.Jet.OLEDB.4.0;"
&
"Data Source=.\Comptoir.mdb;"
sSQL =
"Update CLIENTS Set PAYS = \'États-Unis\' Where PAYS = \'USA\'"
' Exécution de la requête
cnn.Execute
sSQL, iAffected, adExecuteNoRecords
Debug.Print
"Records Affected = "
&
iAffected
cnn.Close
End
Sub
Lien : Définition et manipulation de données avec DAO par Tofalu
Lien : Comment déclarer une référence dans MS Access ?
En VBA, placez ce code avant la requête d'insertion/de modification :
DoCmd.SetWarnings
False
Macro : Avertissements=Non.
Pensez à rétablir les messages après la requête :
DoCmd.SetWarnings
True
Macro : Avertissements=Oui.
Lien : Comment supprimer l'apparition des messages d'avertissement pour toute l'application ?
Tout d'abord, vérifiez que l'option d'avertissement n'est pas désélectionnée dans Access :
Menu Outils, Options, Modifier/Rechercher, Confirmer => Requête Action = Oui.
Ensuite, si vous utilisez la méthode Docmd.SetWarnings, assurez-vous que le dernier appel avant l'exécution de votre requête active les messages.
Enfin vous devez utiliser la méthode Docmd.RunSql car la méthode Execute d'un objet Database ne déclenche jamais les messages d'avertissement Access.
Docmd.SetWarnings
True
Docmd.RunSql
""
Update MATABLE Set
MATABLE.
[MONCHAMP] =
""
DVP.COM
""
;"
Il faut faire ceci :
Dim
val As
String
val =
"l\'exemple"
CurrentDb.Execute
"Insert Into TEST Values("""
&
val &
""")"
Voici une solution :
Pour exécuter ce code, il faut activer la référence : Microsoft DAO 3.x Object Library.
Sub
supp
(
)
' Pour fonctionner ce code nécessite la référence
' - Microsoft DAO X Object Library
Dim
oDb As
DAO.Database
Dim
oQdf As
DAO.QueryDef
Dim
strReqName As
String
'Nom de la requête à supprimer
' Accède à la base de données courante
Set
oDb =
CurrentDb
strReqName =
"R1"
' Parcourt toutes les requêtes jusqu'à la suppression
For
Each
oQdf In
oDb.QueryDefs
With
oQdf
If
.Name
=
strReqName Then
' Une requête porte le nom recherché, donc nous la supprimons
oDb.QueryDefs.Delete
strReqName
' Quitte la boucle
Exit
For
End
If
End
With
Next
oQdf
End
Sub
Le même code avec une gestion d'erreur :
Sub
supp
(
)
' Pour fonctionner ce code nécessite la référence
' - Microsoft DAO X Object Library
' Gestion d'erreur
On
Error
GoTo
err
Dim
oDb As
DAO.Database
Dim
oQdf As
DAO.QueryDef
Dim
strReqName As
String
'Nom de la requête à supprimer
' Accède à la base de données courante
Set
oDb =
CurrentDb
strReqName =
"R2"
' Tente la suppression
oDb.QueryDefs.Delete
strReqName
' Affiche un message
MsgBox
"La requête "
&
strReqName &
" a été supprimée"
fin
:
' Libère l'objet oDb
Set
oDb =
Nothing
Exit
Sub
err
:
' Affiche un message suivant l'erreur
Select
Case
err
.Number
Case
3265
: MsgBox
"La requête n'existe pas"
Case
Else
: MsgBox
"Erreur critique inconnue"
End
Select
' Termine le programme
Resume
fin
End
Sub
Lien : Comment savoir si une table existe ?
Lien : Comment supprimer une table si elle existe ?
Lien : Définition et manipulation de données avec DAO par Tofalu
Lien : Comment déclarer une référence dans MS Access ?
Il faut utiliser des marqueurs différents selon le type de valeur :
Numérique (aucun délimiteur)
SQL &
"And roulage!numéro = "
&
Me.cmbRechNumero
Texte ( Chr(34) crée des ")
SQL =
SQL &
"And roulage!repère = "
&
chr
(
34
) &
Me.cmbRechRepere
&
chr
(
34
)
Date (Délimiteur # et format mm/dd/yyyy)
SQL &
"And roulage!LADATE= #"
&
format
(
Me.txtRechDateDebut
,"mm/dd/yyyy"
) &
"#"
Testé sous Access 2000 :
Sub
Sauvegarder
(
)
' Création des deux Recordsets
Dim
myRS1 As
New
ADODB.Recordset
Dim
myRS2 As
New
ADODB.Recordset
myRS1.Open
"Table1"
, CurrentProject.Connection
, adOpenDynamic
, adLockOptimistic
myRS2.Open
"Table2"
, CurrentProject.Connection
, adOpenDynamic
, adLockOptimistic
' Parcours du RS pour ajouter à table1 tout en supprimant de table2
Do
Until
myRS2.EOF
With
myRS1
.AddNew
Array
(
"Champ1"
, "Champ2"
, "Champ3"
), _
Array
(
myRS2
(
"Alpha"
), myRS2
(
"Beta"
), myRS2
(
"Gamma"
))
.Update
End
With
myRS2.Delete
myRS2.MoveNext
Loop
' Fermeture des Recordsets
myRS1.Close
myRS2.Close
Set
myRS1 =
Nothing
Set
myRS2 =
Nothing
End
Sub
Select
TABLE.CHAMP1
, Sum
(
TABLE.CHAMP2
) AS
CHAMP2 Into NOUVELLETABLE
From TABLE
Group By TABLE.CHAMP1
,
Order By TABLE.CHAMP1
,
Où Champ1 est le champ comportant les doublons à supprimer.
Dim
cn as
ADODB.Connection
Dim
cmd as
ADODB.Command
Dim
insQuery as
String
Set
cn =
New
ADODB.Connection
Set
cmd =
New
ADODB.Command
cn.ConnectionString
=
"Provider=Microsoft.Jet.OLEDB.4.0;"
&
_
"Data Source=D:\CS527\P1\bd1_archive.mdb;Persist Security Info=False;"
&
_
"Jet OLEDB:System database=c:\LePath\LeFichier.mdw"
insQuery =
"INSERT INTO purchasearchive VALUES ("
&
Chr
(
34
) _
&
PUID &
Chr
(
34
) &
","
&
Chr
(
34
) _
&
cardNum &
Chr
(
34
) &
","
&
Chr
(
34
) _
&
cardType &
Chr
(
34
) &
","
&
Chr
(
34
) _
&
productID &
Chr
(
34
) &
",#"
_
&
date
&
"#,"
_
&
number &
");"
cn.Open
cmd.ActiveConnection
=
cn
cmd.CommandText
=
insQuery
cmd.Execute
Pour se connecter à une base de données sécurisée au niveau utilisateur : dans la chaîne de connexion, ajoute ceci :
Password=
LeMotDePasse;User ID=
LeUser
en mettant le bon mot de passe et le bon User.
Si la requête utilise des critères basés sur des champs indexés, il est alors préférable de passer par une requête et OpenQuery.
Docmd.Runsql ne fait qu'exécuter une instruction SQL, tandis que OpenQuery exécute une requête enregistrée (bénéficiant de la technologie Rushmore).
Cette technologie est notamment basée sur l'usage des index pour la recherche d'un enregistrement.
Ceux-ci sont stockés dans une structure cachée.
Si les critères sont posés sur des champs indexés, lorsque la requête s'exécute, elle peut être optimisée car la recherche se fait sur la structure des index et non directement sur la table.
Nous avons une requête du type :
Parameters TON_PARAM Text;
Insert Into TABLE1 Select
CHAMP1 From TABLE2 Where CHAMP2 =
[TON_PARAM];
Voici un exemple de code :
Set
qdf=
CurrentDb.QueryDefs
(
"TAREQUETE"
)
With
qdf
.Parameters
(
"TON_PARAM"
) =
TaVariable
.Execute
End
With
Pour exécuter ce code, il faut activer la référence : Microsoft DAO 3.x Object Library.
Dim
qdf As
DAO.Querydef
Set
qdf =
Currentdb.Querydefs
!NomDeMaRequête
qdf.SQL
=
"Select * From MaTABLE"
Set
qdf =
Nothing
Lien : Définition et manipulation de données avec DAO par Tofalu
Lien : Comment déclarer une référence dans MS Access ?
Par exemple ici, on tente d'enregistrer dans une table un nom qui existe déjà. Or le champ Nom n'accepte pas les doublons.
Sub
Form_Error
(
DataErr As
Integer
, Response
As
Integer
)
' Si l'erreur est due à un doublon, la fonction affiche un message permettant d'annuler une commande.
Const
ERR_DOUBLON =
3022
' Erreur de doublon
' DataErr reçoit le code erreur de la part du moteur de la BDD ou de l'interface
Select
Case
DataErr
Case
ERR_DOUBLON
' Votre message...
MsgBox
"Ce nom existe déjà."
, vbExclamation
, "Attention"
' La zone à surveiller
[Client].SetFocus
' Demande à Access de continuer l'exécution sans afficher le message standard
Response
=
acDataErrContinue
End
Select
End
Sub
requete =
"Select * From carnet Where Prénom Like \'*"
&
prenom &
"*\'"
Dans ce cas, prénom est une variable ou un contrôle contenant la chaîne que nous cherchons.
L'utilisation d'un Recordset rend le traitement plus rapide.
Ce code vous permettra de constater vous-même la différence.
Pour exécuter ce code, il faut activer la référence : Microsoft DAO 3.x Object Library.
Function
BenchmarkIt
(
)
Dim
t0 As
Single
, t1 As
Single
Dim
rst As
DAO.Recordset
Dim
i As
Long
t0 =
Timer
For
i =
1
To
5000
CurrentDb.Execute
"INSERT INTO [tblINSERT] VALUES ("
&
Format
(
i, "000000"
) &
");"
Next
i
t1 =
Timer
Debug.Print
"Exécution par INSERT : "
&
Format
(
t1 -
t0, "0.000"
) &
" s"
t0 =
Timer
Set
rst =
CurrentDb.OpenRecordset
(
"tblRecordset"
)
For
i =
1
To
5000
rst.AddNew
rst!dum =
Format
(
i, "000000"
)
rst.Update
Next
i
rst.Close
set
rst =
Nothing
t1 =
Timer
Debug.Print
"Exécution par RECORDSET : "
&
Format
(
t1 -
t0, "0.000"
) &
" s"
End
Function
Ce code donne :
benchmarkit
Exécution par INSERT : 5,328 s
Exécution par RECORDSET : 0,141 s
Il est possible que la différence soit due au fait que le Recordset travaille avec la mémoire avant d'écrire sur le disque, alors que n requêtes provoquent n accès disque.
Lien : Définition et manipulation de données avec DAO par Tofalu
Lien : Comment déclarer une référence dans MS Access ?
Outils/Options, Modifier/Rechercher
Dans le cadre Confirmer décochez ce que bon vous semble.
Vous trouverez ci-dessous un lien vous indiquant où se trouve la réponse à votre question. Intéressez-vous plus particulièrement au Recordset.