4. DAO et la structure d'une base de données▲
4-1. Généralités▲
Nous abordons là un point fort de DAO à savoir la définition des données (DDL). En effet, l'objet Database donne accès à l'ensemble des tables, des requêtes et des relations d'une base de données Access. Non seulement il est possible de consulter les différents objets mais il est aussi possible de les modifier, d'en ajouter et d'en supprimer. Vous pouvez donc, via votre code VBA, travailler sur la structure de votre fichier comme vous le feriez en mode création dans l'application Access. L'intérêt est bien entendu de pouvoir modifier cette structure sans aucune intervention de l'utilisateur. (Laisser l'utilisateur agir sur les tables directement constitue un réel danger pour votre application). Pour cela, les autres SGBD utilisent généralement le langage SQL (avec des instructions Create, Alter, Drop …). Access ne dispose pas de tant de possibilités avec son langage SQL. Le recours à la programmation VBA devient donc impératif pour réaliser certaines opérations. Nous allons donc voir plus loin dans ce chapitre comment travailler sur les tables, les requêtes et les relations. Mais, dans un premier temps, nous allons aborder le thème des propriétés spécifiques.
4-2. Les propriétés spécifiques▲
4-2-1. Définitions▲
DAO est un modèle objet. Aussi chaque objet qui le compose possède une liste de propriétés dont chacune d'elles correspond à un objet Property. Vous vous demandez alors quel est l'intérêt de la collection Properties puisque ces propriétés sont disponibles sous VBA avec la syntaxe : Objet.Propriété. Certes Visual Basic liste certaines propriétés mais il ne les propose pas toutes. Ainsi par exemple, les objets TableDef possèdent une propriété Description qui correspond à la description de la table. Cette propriété n'est pas listée dans le récapitulatif des propriétés des objets TableDef, le seul moyen de l'atteindre est d'utiliser la collection TableDef.Properties.
Pourquoi certaines propriétés ne figurent que dans la collection properties ?
Tout d'abord, bon nombre de propriétés de la collection Properties ne sont pas créées jusqu'à ce qu'une valeur ne leur soit affectée. Ainsi, la propriété description de l'objet TableDef n'existe pas si vous n'avez pas encore saisi la description de la table sous Access.
De plus vous pouvez créer vos propres propriétés et les
ajouter à la collection Properties de l'objet de votre choix.
Il devient donc impossible de réaliser une liste exhaustive
de l'ensemble des propriétés d'un objet DAO.
4-2-2. Liste des propriétés d'un objet Property▲
Chaque objet Property possède lui aussi un ensemble de propriétés.
4-2-2-1. Inherited▲
Lecture seule.
Lorsque cette propriété est égale à True, cela signifie
que la propriété ne fait pas partie de l'objet même mais qu'elle
est héritée d'un autre objet.
Imaginons un objet QueryDef Q1 auquel nous ajoutons une propriété
personalisée P1. P1 a été créée pour Q1 donc, la propriété P1.Inherited est
égale à False. Si par la suite nous ouvrons un recordset R1 sur Q1, la propriété
P1 se retrouvera dans la collection Properties de R1. P1 sera alors héritée
et P1.Inherited sera égale à True.
Dans ce cas, ces deux expressions seront vérifiées :
Q1.Properties
(
"P1"
).Inherited
=
False
Et :
R1.Properties
(
"P1"
).Inherited
=
True
4-2-2-2. Name▲
Cette propriété correspond au nom de la propriété. Celui-ci doit être unique au sein de la collection Properties de l'objet concerné, sans quoi une erreur sera levée lorsque vous tenterez d'ajouter le nouvel objet Property à la collection Properties.
Utilisez des noms précis et en relation avec ce que la propriété modélise. De même éviter d'utiliser des mots réservés par Visual Basic. Ainsi, si la propriété représente une date de vérification, nommez la DateVerification et non pas simplement Date.
4-2-2-3. Type▲
Il s'agit du type de la propriété. Sa valeur doit être une des constantes suivantes :
Constante | Valeur | Type |
---|---|---|
dbBigInt | 16 | Numérique (haute précision) |
dbBinary | 9 | Binaire de longueur fixe (255 octets maxi) |
dbBoolean | 1 | Booléen |
dbByte | 2 | Octet |
dbChar | 18 | Chaîne de caractère de longueur fixe |
dbCurrency | 5 | Monétaire |
dbDate | 8 | Date/Heure |
dbDecimal | 20 | Décimal |
dbDouble | 7 | Double |
dbFloat | 21 | Réel à virgule flottante |
dbGUID | 15 | Identifiant GUID |
dbInteger | 3 | Entier |
dbLong | 4 | Entier long |
dbLongBinary | 11 | Binaire à longueur variable. (OLE) |
dbMemo | 12 | Mémo |
dbNumeric | 19 | Numérique |
dbSingle | 6 | Réel Simple |
dbText | 10 | Texte à longueur fixe |
dbTime | 22 | Heure |
dbTimeStamp | 23 | TimeStamp |
dbVarBinary | 17 | Binaire à longueur variable (255 octets maxi) |
4-2-2-4. Value▲
Cette propriété correspond à la valeur de l'objet Property. Cette valeur doit être compatible avec le type spécifié dans la propriété Type.
4-2-3. Accéder à une propriété▲
La collection Properties fonctionne comme toute autre collection DAO. Toutefois, ne connaissant pas le contenu de la collection, il paraît difficile d'accéder à un élément via son index dans la collection. Il nous faut donc spécifier le nom de l'élément à rechercher. Il se pose alors un autre problème qui est que nous ne savons pas si l'objet Property à rechercher existe. En effet, comme nous l'avons vu, par exemple plus haut avec la propriété description des objets Tabledef, celle-ci n'existe que si elle a été initialisée auparavant. Dés lors, nous devons vérifier l'existence de la propriété avant d'y accéder.
Deux méthodes peuvent alors être utilisées. La première consiste à parcourir chacun des objets Property de la collection est de retourner un booléen si l'élément a été trouvé.
Public
Function
ExistProperty
(
ColTProperties As
DAO.Properties
, _
strTNom As
String
) As
Boolean
Dim
oTmpPrp As
DAO.Property
For
Each
oTmpPrp In
ColTProperties
If
oTmpPrp.Name
=
strTNom Then
ExistProperty =
True
Exit
For
End
If
Next
oTmpPrp
End
Function
Exemple d'utilisation :
Dim
oDb As
DAO.Database
Dim
oTbl As
DAO.TableDef
Set
oDb =
CurrentDb
Set
oTbl =
oDb.TableDefs
(
"Commande"
)
MsgBox
ExistProperty
(
oTbl.Properties
, "description"
)
La seconde méthode consiste à tenter d'accéder à la propriété via son nom et de traiter l'erreur si celle-ci n'existe pas.
Public
Function
ExistProperty
(
ColTProperties As
DAO.Properties
, _
strTNom As
String
) As
Boolean
On
Error
GoTo
err
Dim
oTmpPrp As
DAO.Property
Set
oTmpPrp =
ColTProperties
(
strTNom)
ExistProperty =
True
err
:
End
Function
L'utilisation de la fonction reste la même que celle de la précédente. Toutefois, la seconde méthode est plus rapide du fait qu'elle n'utilise pas de boucle.
Dans le cas où vous n'utiliseriez pas une de ses fonctions et que la propriété n'est pas trouvée dans la collection Properties, l'erreur d'exécution 3270 (Propriété non trouvée) sera levée.
Une fois la propriété trouvée, il est possible de connaître sa valeur à l'aide de la propriété value.
Dim
oDb As
DAO.Database
Dim
oTbl As
DAO.TableDef
Set
oDb =
CurrentDb
Set
oTbl =
oDb.TableDefs
(
"Commande"
)
If
ExistProperty
(
oTbl.Properties
, "description"
) Then
MsgBox
oTbl.Properties
(
"description"
).Value
Else
MsgBox
"Cette propriété n'existe pas"
End
If
oDb.Close
Set
oDb=
Nothing
Set
oTbl=
Nothing
4-2-4. Modifier la valeur d'une propriété▲
Pour modifier la valeur d'un objet Property, il faut tout d'abord que celui ci existe. Nous pouvons donc réutiliser une des fonctions citées plus haut. Ensuite, il suffit de modifier la valeur de l'objet Property en utilisant la propriété Value. Cependant, certaines propriétés sont en lecture seule. Aussi, l'implémentation d'une gestion d'erreur devient impérative.
Voici un exemple de fonction utilisable pour modifier une propriété spécifique d'un objet DAO :
Public
Function
ModifProperty
(
colTProperties As
DAO.Properties
, _
strTNom As
String
, strTValeur As
Variant
) As
Boolean
On
Error
GoTo
err
Dim
oTmpPrp As
DAO.Property
'Recherche l'élément
Set
oTmpPrp =
colTProperties
(
strTNom)
'Modifie la valeur
oTmpPrp.Value
=
strTValeur
'Rafraichit la collection
colTProperties.Refresh
'L'opération est terminée, renvoyer True
ModifProperty =
True
Exit
Function
'Gestion des erreurs
err
:
Select
Case
err
.Number
Case
3270
MsgBox
"Propriété non trouvée"
Case
3421
MsgBox
"Type de propriété incompatible"
Case
Else
MsgBox
"La propriété est en lecture seule"
End
Select
End
Function
Utilisation :
Dim
oDb As
DAO.Database
Dim
oTbl As
DAO.TableDef
Set
oDb =
CurrentDb
Set
oTbl =
oDb.TableDefs
(
"Commande"
)
ModifProperty oTbl.Properties
, "description"
, "essai"
Quelques remarques sur cette fonction :
TValeur correspond à la nouvelle valeur de la propriété. Le type de cet argument est Variant, pour s'adapter à l'ensemble des types possibles. Toutefois, si vous ne souhaitez modifier des propriétés exclusivement de type String, vous pouvez remplacer le type Variant par String.
La méthode Refresh appliquée à la collection Properties permet de mettre à jour immédiatement la propriété. Si cette méthode n'est pas employée, les modifications ne seront effectives qu'après avoir redémarré votre application.
La fonction renvoie false en cas d'échec de la modification de la propriété.
Il est inutile d'utiliser cette fonction pour les propriétés non spécifiques. En effet, les propriétés proposées par l'explorateur d'objets (F2) sont des propriétés intégrées que vous pouvez modifier avec la syntaxe habituelle Objet.Propriété.
Exemple :
Dim
oDb As
DAO.Database
Dim
oTbl As
DAO.TableDef
Set
oDb =
CurrentDb
Set
oTbl =
oDb.TableDefs
(
"Commande"
)
oTbl.name
=
"essai"
4-2-5. Création d'une nouvelle propriété▲
Pour créer une nouvelle propriété, vous devez d'abord vérifier que celle-ci n'existe pas. Ensuite, il suffit d'appliquer la méthode CreateProperty de l'objet concerné pour instancier un nouvel objet Property. A ce stade, la propriété est seulement créée, elle n'est pas encore ajoutée à la liste des propriétés de l'objet. Pour l'ajouter, vous devez utilisez la méthode Append de la collection Properties.
Voici un exemple qui ajoute une propriété nommée "test" de type Integer à la table commande.
Sub
ajout
(
)
Dim
oDb As
DAO.Database
Dim
oTbl As
DAO.TableDef
Dim
oPrp As
DAO.Property
Set
oDb =
CurrentDb
Set
oTbl =
oDb.TableDefs
(
"Commande"
)
'verifie que la propriété n'existe pas
If
Not
ExistProperty
(
oTbl.Properties
, "test"
) Then
'Crée la nouvelle propriété
Set
oPrp =
oTbl.CreateProperty
(
"test"
, dbInteger, 0
)
'ajoute la propriété
oTbl.Properties.Append
oPrp
'Rafraichit la liste des propriétés
oTbl.Properties.Refresh
End
If
'Libération des objets
oDb.Close
Set
oTbl=
Nothing
Set
oDb=
Nothing
MsgBox
"Propriété ajoutée"
End
Sub
La méthode CreateProperty renvoyant un objet de type Property, ce code peut être simplifié par :
Sub
ajout
(
)
Dim
oDb As
DAO.Database
Dim
oTbl As
DAO.TableDef
Set
oDb =
CurrentDb
Set
oTbl =
Db.TableDefs
(
"Commande"
)
'Vérifie que la propriété n'existe pas
If
Not
ExistProperty
(
oTbl.Properties
, "Test"
) Then
'Crée et ajoute la nouvelle propriété
oTbl.Properties.Append
oTbl.CreateProperty
(
"test"
, dbInteger, 0
)
'Rafraîchit la liste des propriétés
oTbl.Properties.Refresh
End
If
'Libération des objets
oDb.Close
Set
oTbl=
Nothing
Set
oDb=
Nothing
MsgBox
"Propriété ajoutée"
End
Sub
De même, plutôt que de tester l'existence de la propriété, il est possible de tenter de l'ajouter et de gérer l'erreur si une autre propriété portant le même nom existe déjà.
Sub
ajout
(
)
On
Error
GoTo
err
Dim
oDb As
DAO.Database
Dim
oTbl As
DAO.TableDef
Set
oDb =
CurrentDb
Set
oTbl =
oDb.TableDefs
(
"Commande"
)
'Crée et ajoute la nouvelle propriété
oTbl.Properties.Append
oTbl.CreateProperty
(
"test"
, dbText, 0
)
'Rafraîchit la liste des propriétés
oTbl.Properties.Refresh
MsgBox
"Propriété ajoutée"
Exit
Sub
'Gère les erreurs
err
:
Select
Case
err
.Number
Case
3367
: MsgBox
"La propriété existe déjà"
Case
Else
: MsgBox
"Une erreur inconnue est survenue"
End
Select
End
Sub
4-3. L'objet TableDef▲
4-3-1. Définitions▲
La collection TableDefs de l'objet Database regroupe l'ensemble des tables de la base de données. Cette collection inclue aussi les tables systèmes et les tables liées. Chaque objet TableDef qui la compose possède une collection d'objets Field (Champ) et une autre d'objets Index. Ces deux autres types d'objet seront étudiés plus loin dans ce chapitre.
Tout comme c'est le cas en mode création dans l'application Access, il est impossible de modifier la structure d'une table liée en utilisant DAO.
4-3-2. Liste des propriétés▲
Ci-dessous figure la liste des propriétés appliquables aux objets TableDef.
Certaines de ces propriétés ne sont disponibles en écriture uniquement pour les objets qui n'ont pas encore été ajoutés à la collections Database.TableDefs.
4-3-2-1. Attributes▲
Type : Long
La propriété Attributes caractérise la table correspondante. Il s'agit d'une (ou une combinaison) des constantes suivantes :
Constante | Signification |
---|---|
dbAttachExclusive | Utilisable uniquement sur une table liée. Cette valeur indique que la table liée est ouverte en mode exclusif. |
dbAttachSavePWD | Utilisable uniquement sur une table liée. Avec cette constante, les informations de Login utilisées pour lier la table sont sauvegardées. |
dbSystemObject | Indique une table système. |
dbHiddenObject | Indique une table cachée. |
dbAttachedTable | Indique une table liée via le moteur Jet. |
dbAttachedODBC | Indique une table liée via ODBC. |
4-3-2-2. Connect▲
Type : String
Il s'agit de la chaîne de connexion utilisée pour une table liée. Sa valeur est nulle pour une table non liée. Cette chaine de connexion prend en compte plusieurs paramètres comme par exemple le nom de l'utilisateur, son mot de passe, etc ... Vous pouvez la consulter visualisant les propriétés de votre table en mode création.
Cette propriété est en lecture seule pour les objets TableDef présents dans la collection Database.TableDefs
4-3-2-3. DataCreated▲
Lecture seule.
Type : Date
La propriété DataCreated renvoie la date de création de la table.
4-3-2-4. Fields▲
Type : Collection
Cette collection regroupe l'ensemble des champs de la table. Vous pouvez les modifier, en ajouter et en supprimer.
4-3-2-5. Indexes▲
Type : Collection
Collection regroupant l'ensemble des index de la table. Vous pouvez les modifier, en ajouter et en supprimer.
4-3-2-6. LastUpdated▲
Lecture seule.
Type : Date
La propriété LastUpdated retourne la date et l'heure de la dernière modification apportée à la structure de la table concernée.
4-3-2-7. Name▲
Type : String
La prorpiété Name correspond au nom de la table. Ce nom doit être unique au sein de la collection TableDefs de l'objet Database.
Vous trouverez plus loin dans ce chapitre (section 4.3.4.2) un exemple montrant comment renommer une table dans une base de données.
4-3-2-8. Properties▲
Type : Collection
La prorpiété Properties est une collection qui regroupe l'ensemble des objets Property de l'objet TableDef.
4-3-2-9. RecordCount▲
Lecture seule.
Type : Long
La propriété RecordCount renvoie le nombre d'enregistrements de la table.
4-3-2-10. SourceTableName▲
Type : String
Il s'agit du nom d'origine de la table liée. Si l'objet TableDef n'est pas une table liée, cette propriété est en lecture seule et sa valeur est égale à "".
4-3-2-11. Updatable▲
Lecture seule.
Type : Boolean
La propriété de Updatable définit si les données provenant de la table peuvent être modifiées.
4-3-2-12. ValidationRule▲
Type : String
La propriété ValidationRule définit la règle de validation qui sera utilisée pour valider les données lors d'une mise à jour (Insert compris).
Ainsi, pour obliger l'utilisateur a remplir le champ MonChamp lorsque que le champ Booleen MaCase est coché, nous aurions la règle suivante :
(
[MonChamp] IS
NOT
NULL
AND
[MaCase]) OR
NOT
(
[MaCase])
4-3-2-13. ValidationText▲
Type : String
La propriété ValidationText correspond au message qui sera affiché lors d'une mise à jour si les données ne vérifient pas la règle spécifiée dans ValidationRule.
4-3-3. Liste des méthodes▲
4-3-3-1. CreateField▲
La méthode CreateField crée et retourne un nouvel objet Field qui sera à ajouter par la suite à la collection Database.Tabledefs.
Syntaxe :
Set
field =
TableDef.CreateField
(
name, type
, size)
Cette méthode sera traitée plus en détail dans la sous partie dédiée aux objets Field.
4-3-3-2. CreateIndex▲
La méthode CreateIndex crée un nouvel Index dans la table. Cet Index devra ensuite être ajouté à la collection Indexes de l'objet TableDef pour prendre effet.
Syntaxe :
Set
index =
tabledef.CreateIndex
(
name)
4-3-3-3. CreateProperty▲
La méthode CreateProperty crée et retourne un nouvel objet Property qu'il vous faudra ensuite ajouter à la collection Properties de l'objet TableDef.
La syntaxe de la méthode est celle illustrée dans la partie : Les propriétés spécifiques.
4-3-3-4. OpenRecordset▲
La méthode OpenRecordset ouvre un recordset contenant l'ensemble des enregistrements de la table.
Syntaxe :
Set
recordset =
object.OpenRecordset
(
type
, options, lockedits)
4-3-3-5. RefreshLink▲
La méthode RefreshLink n'est utilisable que sur des tables liées. Elle permet, aprés avoir modifié la propriété Connect, de rafraîchir les informations de connexion entre la table attachée et la source de données.
Syntaxe :
tabledef.RefreshLink
4-3-4. Opérations sur les tables d'une base de données▲
4-3-4-1. Lister les tables d'une base de données▲
Je vous propose quelques codes utiles pour lister l'ensemble des tables d'une base de données. Nous ferons la distinction entre les tables systèmes et les tables liées. En effet, la propriété Attributes est un masque binaire. L'opérateur AND entre une constante recherchée et la valeur de la propriété effectue une opération binaire renvoyant un nombre égal à 0 si la constante n'est pas utilisée dans la propriété. Ainsi, pour savoir si une table est une table système, il est possible d'utiliser :
If
monObjet.Attributes
AND
dbSystemObjet then
.....
Pour lister, l'ensemble des tables systèmes, il suffit donc de parcourir un à un les éléments de la collection TableDefs et de de vérifier si l'expression booléene est vraie ou non.
Sub
Lister
(
)
Dim
oDb As
DAO.Database
Dim
oTbl As
DAO.TableDef
Set
oDb =
CurrentDb
'Pour chaque table
For
Each
oTbl In
oDb.TableDefs
'Si la table est système alors afficher son nom
If
oTbl.Attributes
And
dbSystemObject Then
MsgBox
oTbl.Name
Next
oTbl
End
Sub
Si nous souhaitons lister les tables liées, nous aurons :
Sub
Lister
(
)
Dim
oDb As
DAO.Database
Dim
oTbl As
DAO.TableDef
Set
oDb =
CurrentDb
'Pour chaque table
For
Each
oTbl In
oDb.TableDefs
'Si la table est liée alors afficher son nom
If
oTbl.Attributes
And
dbAttachedTable Then
MsgBox
oTbl.Name
Next
oTbl
End
Sub
Pour réunir les deux listes, il suffit d'utiliser l'opérateur logique OR (Ou). Ainsi, le code suivant affichera les tables systèmes ainsi que les tables liées.
Sub
Lister
(
)
Dim
oDb As
DAO.Database
Dim
oTbl As
DAO.TableDef
Set
oDb =
CurrentDb
'Pour chaque table
For
Each
oTbl In
oDb.TableDefs
'Si la table est liée ou système alors afficher son nom
If
oTbl.Attributes
And
(
dbAttachedTable Or
dbSystemObject) Then
MsgBox
oTbl.Name
Next
oTbl
End
Sub
Ce code n'est pas à confondre avec :
Sub
Lister
(
)
Dim
oDb As
DAO.Database
Dim
oTbl As
DAO.TableDef
Set
oDb =
CurrentDb
'Pour chaque table
For
Each
oTbl In
oDb.TableDefs
'Si la table est liée et système alors afficher son nom
If
oTbl.Attributes
And
(
dbAttachedTable And
dbSystemObject) Then
MsgBox
oTbl.Name
Next
oTbl
End
Sub
En effet ce dernier liste les tables qui sont à la fois systèmes et liées.
4-3-4-2. Renommer une table▲
Renommer une table est une opération extrémement simple. Toutefois, il ne faut pas oublier que le nom de la table doit être unique. Aussi, il faudra implémenter une gestion d'erreur lors d'une telle opération.
Les objets Relations dépendants de la table renommées sont automatiquement mis à jour par le moteur Jet.
Private
Function
RenommerTable
(
oBaseDeDonnees As
DAO.Database
, strAncienNom As
String
, _
strNouveauNom As
String
) As
Boolean
On
Error
GoTo
err
Dim
oTbl As
DAO.TableDef
'Cherche la table à modifier
Set
oTbl =
oBaseDeDonnees.TableDefs
(
strAncienNom)
'Renomme la table
oTbl.Name
=
strNouveauNom
'Rafraîchit la collection
oBaseDeDonnees.TableDefs.Refresh
'Renvoie true
RenommerTable =
True
Exit
Function
err
:
Select
Case
err
.Number
Case
3265
: MsgBox
"Impossible de trouver la table à renommer"
Case
3010
: MsgBox
"La table "
&
strNouveauNom &
" existe déjà"
Case
Else
: MsgBox
"Une erreur inattendue est survenue"
End
Select
End
Function
Utilisation :
Dim
oDb As
DAO.Database
Dim
oTbl As
DAO.TableDef
Set
oDb =
CurrentDb
If
RenommerTable
(
oDb, "Commande"
, "Commande_Archive"
) Then
MsgBox
"Table renommée avec succès"
End
if
4-3-4-3. Supprimer une table▲
La suppression d'une table nécessite quelques précautions. Hormis le fait que la table doit exister pour être supprimer, il ne faut pas perdre de vue que la suppression d'une table engendre la suppression des relations qui en dépendent. Aussi dans le cas d'une mauvaise manipulation, vous risquez de supprimer des objets Relations sans vous en rendre compte. Dans ce cas, je préconise d'envoyer un message à l'utilisateur lui demandant confirmation. Il nous faut donc savoir si la table fait partie d'un objet relation ou non. Pour cela, nous utiliserons la fonction ExistRelation suivante :
Private
Function
ExistRelation
(
oBaseDeDonnees As
DAO.Database
, _
strNomTable As
String
) As
Integer
Dim
oRlt As
DAO.Relation
'Pour chaque objet relation
For
Each
oRlt In
oBaseDeDonnees.Relations
'Si la table est présente dans la relation
If
oRlt.Table
=
strNomTable Or
oRlt.ForeignTable
=
strNomTable Then
_
ExistRelation =
ExistRelation +
1
Next
oRlt
End
Function
Cette fonction renvoie le nombre de relations dépendantes de la table passée en paramètre.
Nous pouvons donc écrire la fonction de suppression de table suivante :
Private
Function
SupprimerTable
(
oBaseDeDonnee As
DAO.Database
, _
strNomTable As
String
)
On
Error
GoTo
err
Dim
intNbRlt As
Integer
'Compte le nombre de relations dépendantes
intNbRlt =
ExistRelation
(
oBaseDeDonnee, strNomTable)
'Si la table est présente dans au moins une relation
If
NbRlt <>
0
Then
'si l'utilisateur ne souhaite pas continuer, sortir de la fonction
If
MsgBox
(
"La table "
&
strNomTable &
" est utilisée dans "
&
_
intNbRlt &
" relation(s)."
&
vbCrLf
&
"La suppression de cette table entrainera la"
&
_
" suppression de cette(ces) relation(s)."
&
vbCrLf
&
vbCrLf
&
"Voulez vous continuer ?"
, _
vbQuestion
+
vbYesNo
, "Suppression de table"
) =
vbNo
Then
Exit
Function
End
If
'Supprime la table
oBaseDeDonnee.TableDefs.Delete
(
strNomTable)
'Rafraichit la collection
oBaseDeDonnee.TableDefs.Refresh
'Renvoie true
SupprimerTable =
True
Exit
Function
err
:
'Gére les erreurs
Select
Case
err
.Number
Case
3265
: MsgBox
"Impossible de trouver la table à supprimer"
Case
Else
: MsgBox
"Une erreur inattendue est survenue"
End
Select
End
Function
Utilisation :
Dim
oDb As
DAO.Database
Dim
oTbl As
DAO.TableDef
Set
oDb =
CurrentDb
If
SupprimerTable
(
oDb, "Commande"
) Then
MsgBox
"Table supprimée"
End
If
4-3-4-4. Créer une nouvelle table▲
La création d'une table n'ayant que peu d'intéret sans la création de champs, je vous propose d'aborder avant les parties concernant les champs et les index puis de revenir ensuite sur cet exemple.
Dans cet exemple, nous allons créer une table nommée Client possédant trois champs :
- IDClient Clé primaire. Type : Long, numéro automatique
- NomClient Type : Texte. Longueur : 15
- PrenomClient Type : Texte. Longueur : 25
Voici le code correspondant :
Sub
CreerTable
(
)
Dim
oDb As
DAO.Database
Dim
oNouvelleTable As
DAO.TableDef
Dim
oChamp As
DAO.Field
Dim
oIndex As
DAO.Index
'Instancie la base de données
Set
oDb =
CurrentDb
'Crée la nouvelle table
Set
oNouvelleTable =
oDb.CreateTableDef
(
"Clients"
)
'Crée le champ IDClient
Set
oChamp =
oNouvelleTable.CreateField
(
"IDClient"
, dbLong)
'Définit le champ en numero_auto
oChamp.Attributes
=
dbAutoIncrField
'Ajoute le champ à la table
oNouvelleTable.Fields.Append
oChamp
'Crée le champ nomClient et l'ajoute
oNouvelleTable.Fields.Append
oNouvelleTable.CreateField
(
"NomClient"
, _
dbText, 15
)
'Crée le champ PrenomClient et l'ajoute
oNouvelleTable.Fields.Append
oNouvelleTable.CreateField
(
"PrenomClient"
, _
dbText, 25
)
'définit la clé primaire sur l'IDClient
Set
oIndex =
oNouvelleTable.CreateIndex
(
"PK_IDClient"
)
oIndex.Primary
=
True
oIndex.Fields.Append
oIndex.CreateField
(
"IdClient"
)
'Ajoute l'index à la table
oNouvelleTable.Indexes.Append
oIndex
'Ajoute la table à la base de données
oDb.TableDefs.Append
oNouvelleTable
'Libère les variables
oDb.Close
Set
oIndex =
Nothing
Set
oChamp =
Nothing
Set
oNouvelleTable =
Nothing
Set
oDb =
Nothing
End
Sub
4-4. L'objet Field▲
4-4-1. Définition▲
Un objet Field représente un champ d'une table ou d'une requête dans une base de données. DAO offre de nombreuses possibilités concernant les objets Field. Il est ainsi possible de créer des champs, d'en supprimer et de les modifier aussi simplement que vous le feriez dans le mode création d'Access. En effet, il existe une réelle analogie entre la liste des propriétés des objets Field et la fenêtre de modification de la structure d'une table. Chaque zone de texte de cette fenêtre correspond à une propriété de l'objet Field.
Je vous propose tout d'abord d'effectuer un tour d'horizon de l'ensemble des propriétés et des méthodes de cet objet, avant de revenir sur des exemples plus spécifiques.
4-4-2. Liste des propriétés▲
Vous retrouverez ci-dessous l'ensemble des propriétés des objets Field dans la liste suivante.
Certaines de ces propriétés ne sont disponibles en écriture uniquement pour les objets qui n'ont pas encore été ajoutés à la collections TableDef.Fields.
4-4-2-1. AllowZeroLength▲
Type : Boolean
La propriété AllowZeroLength indique si un champ texte accepte les chaines vides. Si la valeur de cette propriété est égale à True, ces valeurs sont acceptées. Dans le cas échéant, une erreur sera levée lorsque que vous tenterez de mettre à jour les données.
4-4-2-2. Attributes▲
Type : Long
La propriété Attributes définit les options du champ. Il s'agit d'une une (ou une combinaison) des constantes suivantes :
Constante | Signification |
---|---|
dbAutoIncrField | Correspond à un champ de type Numéro Auto. A n'utiliser que sur les champs de type numérique. |
dbDescending | Dans le cas où le champ fait parti d'un index, cette valeur permet d'inverser l'ordre de tri. |
dbFixedField | Champ de taille fixe. Valeur par défaut des champs de type numérique. |
dbHyperlinkField | Gère les liens hypertext dans un champs mémo. |
dbSystemField | Le champ stocke des informations de duplication pour les duplicatas. Un tel champ ne peut être supprimé. |
dbUpdatableField | Le valeur du champ peut être modifiée. |
dbVariableField | Le champ peut être modifié. A n'utiliser que sur les champs de type texte. |
4-4-2-3. CollatingOrder▲
Type : Long
Il s'agit de la méthode utilisée par le moteur pour comparer les valeurs du champ si celui-ci est de type texte.
Les valeurs possibles sont :
Constante | Signification |
---|---|
dbSortGeneral | Général (Français, anglais ...) |
dbSortArabic | Arabe |
dbSortChineseSimplified | Chinois simplifié |
dbSortChineseTraditional | Chinois traditionnel |
dbSortCyrillic | Russe |
dbSortCzech | Tchèque |
dbSortDutch | Néerlandais |
dbSortGreek | Grec |
dbSortHebrew | Hébreu |
dbSortHungarian | Hongrois |
dbSortIcelandic | Islandais |
dbSortJapanese | Japonais |
dbSortKorean | Coréen |
dbSortNeutral | Neutre |
dbSortNorwDan | Norvégien et danois |
dbSortPDXIntl | Paradox International |
dbSortPDXNor | Paradox norvégien ou danois |
dbSortPDXSwe | Paradox suédois ou finnois |
dbSortPolish | Polonais |
dbSortSlovenian | Slovène |
dbSortSpanish | Espagnol |
dbSortSwedFin | Suédois ou finnois |
dbSortThai | Thaï |
dbSortTurkish | Turc |
dbSortUndefined | Indéfini |
4-4-2-4. DataUpdatable▲
Lecture seule.
Type : Boolean
Lorsque la propriété DataUpdatable est égale à False, il vous est impossible de modifier les valeurs de ce champ. C'est notamment le cas d'un champ auto-incrémenté.
4-4-2-5. DefaultValue▲
Type : Variant
Cette propriété correspond à la valeur par défaut du champ. Elle est en lecture/écriture pour les champs issus de TableDef et en lecture seule pour ceux issus de QueryDef et Recordset. Elle n'est pas prise en charge par les objets Fields des collections Database.Indexes et Database.Relations.
Pour un champ de type Long vous pouvez attribuer à cette propriété la valeur : GenUniqueID(). Ainsi à chaque nouvel enregistrement ajouté, le moteur Jet attribue une valeur unique et aléatoire au nouvel enregistrement. Cette valeur reproduit le comportement d'une numérotation automatique aléatoire.
4-4-2-6. FieldSize▲
Lecture seule.
Type : Long
La propriété FieldSize, correspond à la taille utilisée dans la base par un champ de type binaire ou mémo.
Cette valeur est exprimée en nombre de caractères pour un champ mémo et en nombre d'octet pour un champ de type binaire.
4-4-2-7. ForeignName▲
Type : String
La propriété ForeignName n'est à utiliser que pour les champs d'un objet de type Relation. Elle définit le nom du champ dans la table externe de la relation (clé étrangère). Cette propriété est en lecture/écriture dans le cas d'objets Relation non ajoutés à la collection Database.Relations et en lecture seule pour les objets déjà présents au sein de cette même collection.
4-4-2-8. Name▲
Type : String
Il s'agit du nom du champ. Le nom d'un champ doit être unique au sein d'une table.
4-4-2-9. OrdinalPosition▲
Type : Integer
La propriété OrdinalPosition permet de définir la position du champ dans la collection Fields de l'objet TableDef. Le premier élément possède
la position 0. Cette position conditionne l'ordre d'apparition des champs dans une requête SELECT * FROM ...
Notons que si deux champs possèdent la même valeur pour la propriété OrdinalPosition, ces champs sont alors classés par ordre alphabétique.
Cette propriété est en lecture seule pour les objets QueryDef.
4-4-2-10. Properties▲
Type : Collection
Collection regroupant l'ensemble des objets Property de l'objet Field.
4-4-2-11. Required▲
Type : Boolean
La propriété Required indique si le champs accepte les valeurs nulles. Si cette propriété est égale à True, une erreur sera levée si vous tentez d'affecter une valeur nulle à ce champ.
4-4-2-12. Size▲
Type : Integer
La propriété Size définit la taille du champ comme vous pouvez le faire en mode création. Cette propriété n'est en lecture écriture que pour les objets Field qui n'ont pas encore été ajoutés à la collection Fields.
4-4-2-13. SourceField▲
Lecture seule.
Type : String
Cette propriété en lecture seule indique dans un objet QueryDef le nom d'un champ et non son alias. Soit une requête nommée R01 :
SELECT NomClient as LeNom FROM Client
Le code suivant affichera LeNom :
Dim
oDb As
DAO.Database
Dim
oQR As
DAO.QueryDef
Set
oDb =
CurrentDb
Set
oQR =
oDb.QueryDefs
(
"R01"
)
MsgBox
oQR.Fields
(
0
).Name
Cet autre code affichera NomClient :
Dim
oDb As
DAO.Database
Dim
oQR As
DAO.QueryDef
Set
oDb =
CurrentDb
Set
oQR =
oDb.QueryDefs
(
"R01"
)
MsgBox
oQR.Fields
(
0
).SourceField
Nous pouvons donc écrire la fonction suivante qui retourne le nom d'un champ en fonction de son alias :
Function
NomChamp
(
oBaseDeDonnee As
DAO.Database
, strRequete As
String
, strAlias As
String
) As
String
On
Error
GoTo
err
Dim
Qdf As
DAO.QueryDef
Set
Qdf =
oBaseDeDonnee.QueryDefs
(
strRequete)
NomChamp =
Qdf.Fields
(
strAlias).SourceField
Exit
Function
'Gère les erreurs
err
:
Select
Case
err
.Number
Case
3265
'Si qdf est vide alors la requete n'existe pas
If
Qdf Is
Nothing
Then
MsgBox
"Impossible de trouver la requête "
&
strRequete
Else
MsgBox
"Impossible de trouver le champ "
&
strAlias &
" dans la requete "
&
_
strRequete
End
If
Case
Else
: MsgBox
"Une erreur inattendue est survenue"
End
Select
End
Function
Utilisation :
Dim
oDb As
DAO.Database
Set
oDb =
CurrentDb
MsgBox
NomChamp
(
oDb, "R01"
, "LeClient"
)
4-4-2-14. SourceTable▲
Lecture seule.
Type : String
Cette propriété repose sur le même principe que la précédente. Elle permet de savoir de quelle table provient un champ d'une requête.
Ainsi, avec l'exemple précédent, voici comment connaître la table d'origine du champ LeClient :
Dim
oDb As
DAO.Database
Dim
oQR As
DAO.QueryDef
Set
oDb =
CurrentDb
Set
oQR =
oDb.QueryDefs
(
"R01"
)
MsgBox
oQR.Fields
(
0
).SourceTable
4-4-2-15. Type▲
Type : Integer
Cette propriété définit le type du champ. Il s'agit d'une des constantes suivantes :
Constante | Valeur | Type |
---|---|---|
dbBigInt | 16 | Numérique (haute précision) |
dbBinary | 9 | Binaire de longueur fixe (255 octets maxi) |
dbBoolean | 1 | Booléen |
dbByte | 2 | Octet |
dbChar | 18 | Chaîne de caractère de longueur fixe |
dbCurrency | 5 | Monétaire |
dbDate | 8 | Date/Heure |
dbDecimal | 20 | Décimal |
dbDouble | 7 | Double |
dbFloat | 21 | Réel à virgule flottante |
dbGUID | 15 | Identifiant GUID |
dbInteger | 3 | Entier |
dbLong | 4 | Entier long |
dbLongBinary | 11 | Binaire à longueur variable. (OLE) |
dbMemo | 12 | Mémo |
dbNumeric | 19 | Numérique |
dbSingle | 6 | Réel Simple |
dbText | 10 | Texte à longueur fixe |
dbTime | 22 | Heure |
dbTimeStamp | 23 | TimeStamp |
dbVarBinary | 17 | Binaire à longueur variable (255 octets maxi) |
4-4-2-16. ValidationRule▲
Type : String
La propriété ValidationRule définit la règle de validation qui sera utilisée pour valider les données lors d'une mise à jour (Insert compris).
4-4-2-17. ValidationText▲
Type : String
La propriété ValidationText correspond au message qui sera affiché lors d'une mise à jour si les données ne vérifient pas la règle spécifiée dans ValidationRule.
4-4-2-18. Value▲
Type : Variant
Pour un objet Recordset, la propriété Value retourne la valeur du champ pour l'enregistrement courant.
4-4-2-19. VisibleValue▲
Type : Variant
Cette propriété est utilisable uniquement dans un environnement ODBCDirect. Elle renvoit la valeur actuelle d'un champ lors d'un traitement par lot. Cette valeur est donc plus récente que celle retournée par la propriété OriginalValue
4-4-3. Liste des méthodes▲
4-4-3-1. AppendChunk▲
La méthode AppendChuk permet d'ajouter des données à la fin d'un champ de type mémo ou binaire. (Collection Recordsets exclusivement) Elle évite notamment de lire le début du champ, de concaténer et de renvoyer la nouvelle valeur. En utilisant la méthode AppendChunk, vous limiter donc le traffic d'informations entre la base de données et le moteur Jet.
Syntaxe :
field.AppendChunk
source
L'argument source est de type Variant.
4-4-3-2. CreateProperty▲
La méthode CreateProperty crée et retourne un nouvel objet Property qu'il vous faudra ensuite ajouter à la collection Properties de l'objet Field.
La syntaxe de la méthode est celle illustrée dans la partie : Les propriétés spécifiques.
4-4-3-3. GetChunk▲
La méthode GetChunk s'applique aux champs des objets Recordset. Elle renvoie le contenu (ou une partie) d'un champ mémo ou binaire dans une variable de type String.
Syntaxe :
Set
variable =
field.GetChunk
(
offset, numbytes)
Le paramètre offset de type Long correspond à la position du caractère (ou de l'octet) à partir duquel doit commencer la lecture.
L'argument numbytes détermine le nombre de caractères (ou d'octet) à lire.
4-4-4. Opérations sur les champs d'un objet TableDef▲
Seul l'objet TableDef permet de modifier les éléments de sa collection Field. Je vous propose plusieurs exemples afin d'illustrer l'étendue des possibilités qu'offre DAO.
4-4-4-1. Renommer un champ▲
Tout comme c'était déjà le cas avec les tables, cette opération nécessite que le nouveau nom soit unique dans la collection Fields de l'objet TableDef.
Les objets Relation et Index utilisant ce champ sont automatiquement mis à jour par le moteur Jet.
Private
Function
RenommerChamp
(
oBaseDeDonnees As
DAO.Database
, strNomTable As
String
, _
strAncienNomChamp As
String
, strNouveauNomChamp As
String
) As
Boolean
On
Error
GoTo
err
Dim
Tbl As
DAO.TableDef
'Récupère la table
Set
Tbl =
oBaseDeDonnees.TableDefs
(
strNomTable)
'Renomme le champ
Tbl.Fields
(
strAncienNomChamp).Name
=
strNouveauNomChamp
'Renvoie True
RenommerChamp =
True
'Gère les erreurs
Exit
Function
err
:
Select
Case
err
.Number
'Si impossible de trouver l'élément dans la collection
Case
3265
'Si tbl=nothing alors tbl est la cause de l'erreur
If
Tbl Is
Nothing
Then
MsgBox
"Impossible de trouver la table : "
&
strNomTable
Else
MsgBox
"Impossible de trouver le champ : "
&
strAncienNomChamp
End
If
Case
3010
, 3191
: MsgBox
"Le champ "
&
strNouveauNomChamp &
" existe déjà"
Case
Else
: MsgBox
"Une erreur inattendue est survenue"
End
Select
End
Function
Utilisation :
Dim
oDb As
DAO.Database
Set
oDb =
CurrentDb
If
RenommerChamp (
oDb, "Commande"
, "Reference"
, "Nouvelle_Reference"
) then
msgbox
"Opération terminée"
End
if
4-4-4-2. Supprimer un champ▲
La suppression d'un champ est trés délicate. En effet, plusieurs erreurs peuvent être levées au cours de cette opération :
- 3265 : Le champ n'existe pas
- 3280 : Le champ est utilisé par un index
- 3303 : Le champ est utilisé dans une ou plusieurs relations
L'erreur 3303 est difficile à maitriser car même si l'erreur est levée, le champ est quand même supprimé. Toutefois les relations sont toujours présentes et si vous rajoutez par la suite le champ supprimé, la relation va "renaître", ce qui provoque un comportement inattendu.
Il nous faut donc savoir si le champ est l'objet de relations.
Private
Function
ChampDansRelation
(
oBaseDeDonnees As
DAO.Database
, _
strNomTable As
String
, strNomChamp As
String
) As
Integer
On
Error
GoTo
err
Dim
bolUtilise As
Boolean
Dim
oRlt As
DAO.Relation
Dim
oFld As
DAO.Field
'Parcours les relations
For
Each
oRlt In
oBaseDeDonnees.Relations
bolUtilise =
False
If
oRlt.Table
=
strNomTable Then
'Pour chaque champ, contrôle le nom du champ
For
Each
oFld In
oRlt.Fields
If
oFld.Name
=
strNomChamp Then
bolUtilise =
True
Next
oFld
ElseIf
oRlt.ForeignTable
=
strNomTable Then
'pour chaque champ, contrôle le nom étranger
For
Each
oFld In
oRlt.Fields
If
oFld.ForeignName
=
strNomChamp Then
bolUtilise =
True
Next
oFld
End
If
'Si la relation utilise le champ, on incremente le resultat
If
bolUtilise Then
ChampDansRelation =
ChampDansRelation +
1
Next
oRlt
Exit
Function
err
:
ChampDansRelation =
-
1
End
Function
Cette fonction renvoie le nombre de relations qui utilisent le champ passé en paramètre.
Utilisation :
Dim
oDb as
DAO.Database
Set
oDb=
CurrentDB
MsgBox
ChampDansRelation
(
oDb, "Commande"
, "Reference"
)
Cet exemple affichera le nombre de relations utilisant le champ Reference de la table Commande.
La fonction retourne -1 si une erreur est survenue.
Nous pouvons donc écrire la fonction de suppression suivante :
Private
Function
SupprimerChamp
(
oBaseDeDonnees As
DAO.Database
, strNomTable As
String
, _
strNomChampASupprimer As
String
) As
Boolean
On
Error
GoTo
err
Dim
oTbl As
DAO.TableDef
'Verifie que le champ ne fait pas partie d'une relation
If
ChampDansRelation
(
oBaseDeDonnees, strNomTable, strNomChampASupprimer) =
0
Then
'Récupère la table
Set
oTbl =
oBaseDeDonnees.TableDefs
(
strNomTable)
'Supprime le champ
oTbl.Fields.Delete
(
strNomChampASupprimer)
'Renvoie True
SupprimerChamp =
True
Else
MsgBox
"Impossible de supprimer le champ, il est utilisé par une ou plusieurs relations"
End
If
Exit
Function
err
:
Select
Case
err
.Number
'Si impossible de trouver l'élément dans la collection
Case
3265
'Si tbl=nothing alors tbl est la cause de l'erreur
If
Tbl Is
Nothing
Then
MsgBox
"Impossible de trouver la table : "
&
strNomTable
Else
MsgBox
"Impossible de trouver le champ : "
&
strNomChampASupprimer
End
If
Case
3280
: MsgBox
"Impossible de supprimer un champ utilisé par un index"
Case
Else
: MsgBox
"Une erreur inattendue est survenue"
End
Select
End
Function
Utilisation :
SupprimerChamp oDb, "Commande"
, "Reference"
4-4-4-3. Créer un champ▲
La création d'un champ se décompose en trois étapes :
Un exemple sera certainement plus parlant que de longues phrases, je vous propose de créer un champ AdresseClient dans une table nommée Client.
Ce champ aura pour cractéristiques :
- Type : Texte
- Longueur : 120 caractères
- Chaine vide autorisée : Non
- Null interdit : Oui
Dim
oDb As
DAO.Database
Dim
oTbl As
DAO.TableDef
Dim
oFld As
DAO.Field
Set
oDb =
CurrentDb
Set
oTbl =
oDb.TableDefs
(
"Client"
)
'Etape 1 : Créer le champ
Set
oFld =
oTbl.CreateField
(
"AdresseClient"
, dbText, 120
)
'Etape 2 : Définit les propriétés
oFld.AllowZeroLength
=
False
'Chaine vide autorisée : Non
oFld.Required
=
True
'Null interdit : Oui
'Etape 3 : Ajout du champ à la table
oTbl.Fields.Append
Fld
'Rafraichit la collection
oTbl.Fields.Refresh
Il est important de respecter l'ordre de chaque étape. Si vous ajouter le champ à la collection Fields avant de lui avoir affecter l'ensemble de ses propriétés, vous vous apercevrez que certaines de ces propriétés ne sont plus accessibles en écriture.
Nous n'avons pas traité ici la gestion d'erreur. Celle ci exactement la même que pour la fonction qui renomme un champ. En effet, le plus grand risque pour ce programme est d'utiliser un nom de champ qui existe déjà.
4-4-4-4. Dupliquer un champ▲
Je vous propose ici un code qui peut s'avérer utile lorsque vous souhaiter créer un champ identique à un autre. Le principe est simple, nous partons de deux objets Field. Le premier sera utilisé comme source du clonage. Nous allons donc parcourir chaque propriété (exceptée la propriété Name) du champ source et les réécrire dans le champ de destination.
Certaines de ces propriétés risquent d'être en lecture seule. Il nous faut donc déleguer la lecture et l'écriture des propriétés à une autre procédure afin de ne pas faire stopper le programme à la première erreur rencontrée.
Public
Sub
CloneChamp
(
oFldSource As
DAO.Field
, oTableDestination As
DAO.TableDef
, _
strNouveauNom As
String
)
On
Error
GoTo
err
Dim
oFld As
DAO.Field
Dim
oPrp As
DAO.Property
'Crée le champ
Set
oFld =
oTableDestination.CreateField
(
strNouveauNom)
'Pour chaque propriete
For
Each
oPrp In
oFldSource.Properties
'copier la propriété s'il ne s'agit pas du nom
If
oPrp.Name
<>
"Name"
Then
_
EcrirePropriete oPrp, oFld
Next
oPrp
'Ajoute le champ
oTableDestination.Fields.Append
oFld
Exit
Sub
err
:
Select
Case
err
.Number
Case
3010
, 3191
: MsgBox
"Le champ "
&
strNouveauNom &
" existe déjà"
Case
Else
: MsgBox
"Une erreur inattendue est survenue"
End
Select
End
Sub
Private
Sub
EcrirePropriete
(
oPropriete As
DAO.Property
, _
oChampDestination As
DAO.Field
)
On
Error
GoTo
err
'Copie la propriété
With
oChampDestination.Properties
.Item
(
oPropriete.Name
) =
oPropriete.Value
.Refresh
End
With
'On ne traite pas les erreurs
err
:
End
Sub
Pour dupliquer le champ AdresseClient de la table Client dans la table SauvegardeClient nous utiliserons :
Dim
oDb As
DAO.Database
Dim
oTblSource As
DAO.TableDef
, oTblDestination As
DAO.TableDef
Dim
oFld As
DAO.Field
Set
oDb =
CurrentDb
'Stocke les deux tables
Set
oTblSource =
oDb.TableDefs
(
"Client"
)
Set
oTblDestination =
oDb.TableDefs
(
"SauvegardeClient"
)
'Stocke le champ
Set
oFld =
oTblSource.Fields
(
"AdresseClient"
)
'Clone le champ
CloneChamp oFld, oTblDestination, "AdresseClient2"
4-5. L'objet Index▲
4-5-1. Définitions▲
Nous n'allons pas reprendre ici la définition d'un index. Je vous renvoie pour cela vers d'autres tutoriels de ce site. Toutefois, rappelons sommairement qu'un index permet de faciliter l'accès aux données dans une table lors d'une recherche et qu'il permet aussi de poser des contraintes sur les données (Notion de clé primaire et de doublons).
Un index peut être composé d'un ou plusieurs champs, il possède donc une collection Fields recensant ces champs.
4-5-2. Liste des propriétés▲
4-5-2-1. DistinctCount▲
Lecture seule.
Type : Long
La propriété DistinctCount renvoie le nombre de valeurs uniques présentes dans la table. Dans le cas d'un index mono-champ, il s'agit du nombre de valeurs distinctes dans ce champ (équivalent d'une requête SELECT DISTINCT MonChamp ...). Dans le cas d'un index composé de plusieurs champs, cette valeur correspond au nombre de combinaisons distinctes des valeurs de ces champs au sein de la table (équivalent d'une requête SELECT DISTINCT MonChamp1,MonChamp2 ...).
4-5-2-2. Fields▲
Type : Collection
Cette collection regroupe l'ensemble des champs composant l'index. Chaque objet Field de cette collection doit posséder le même nom qu'un objet Field de la table concernée.
4-5-2-3. Foreign▲
Lecture seule.
Type : Boolean
Lorsque la propriété Foreign d'un index est égale à True, cela signifie que l'index est une clé étrangère. C'est notamment le cas pour les index ajoutés automatiquement par Access lorsque vous créez des relations entre les tables.
4-5-2-4. IgnoreNulls▲
Type : Boolean
Si vous définissez la propriété IgnoreNulls à True, les valeurs nulles ne seront pas indéxées. Cela peut être utile si vous prévoyer d'enregistrer un grand nombre de valeur nulles.
4-5-2-5. Name▲
Type : String
Cette propriété correspond au nom de l'index. Ce nom doit être unique dans la collection Indexes de l'objet TableDef correspondant.
Prévoyez des noms d'index aussi clairs que possible. Aussi certains préfixent le nom de leurs index par les initiales de leur rôle. Ainsi, une clé primaire sera notée PK_MonChamp (PK = Primary Key).
4-5-2-6. Properties▲
Type : Collection
Collection regroupant l'ensemble des objets Property de l'objet Index.
4-5-2-7. Required▲
Type : Boolean
Si la propriété Required est égale à True, cela signifie que les champs de l'index doivent tous recevoir une valeur, sans quoi, lors des mises à jour, une erreur sera levée.
4-5-2-8. Unique▲
Type : Boolean
Lorsque la propriété Unique est égale à True, les doublons sont interdits dans les champs de l'index.
Dans un index multi-colonnes, les valeurs A A et A B ne sont pas des doublons.
4-5-3. Liste des méthodes▲
Comme vous allez le remarquer, l'objet Index dispose de trés peu de méthodes. Qui plus est, ces méthodes ont déjà été traitées plus haut.
4-5-3-1. CreateField▲
Cette méthode est la même que celle appliquée aux objets TableDef, à la différence prés quelle ne propose qu'un seul paramètre : le nom du champ. Ce nom doit être identique à celui du champ de la table sur lequel repose l'index.
Syntaxe :
Set
field =
index.CreateField
(
name)
4-5-3-2. CreateProperty▲
Cette méthode n'est plus à présenter, et pour cause, nous la retrouvons à chaque chapitre de ce tutoriel. Aussi, je vous renvoie vers le chapitre des 4.2.5 Propriétés spécifiques.
4-5-4. Opérations sur les Index▲
Je vous propose deux petits exemples afin de mettre en pratique les notions abordées dans cette partie.
4-5-4-1. Créer un index▲
Soit une table Client possédant plusieurs champs dont NumeroClient. Nous allons créer une clé primaire sur ce champ.
Dim
oDb As
DAO.Database
Dim
oTbl As
DAO.TableDef
Dim
oFld As
DAO.Field
Dim
oInd As
DAO.Index
'Instancie la base
Set
oDb =
CurrentDb
'Instancie la table
Set
oTbl =
oDb.TableDefs
(
"Client"
)
'Crée l'index en le nommant PK_Client
Set
oInd =
oTbl.CreateIndex
(
"PK_Client"
)
'Cree le champs dans l'index
Set
oFld =
oInd.CreateField
(
"NumeroClient"
)
'Ajoute le champ à la collection Fields
oInd.Fields.Append
oFld
'Définit la clé primaire
oInd.Primary
=
True
'Ajoute l'index à la table
oTbl.Indexes.Append
oInd
'Rafraichit la collection
oTbl.Indexes.Refresh
4-5-4-2. Supprimer une clé primaire▲
Afin d'illustrer la suppression d'un index je vous propose de traiter le cas, où nous souhaitons supprimer la clé primaire de la table. Il nous faut donc parcourir l'ensemble des index de l'objet TableDef et les supprimer si leur propriété Primary est égale à True.
Private
Sub
SupprimerClePrimaire
(
oTbl As
DAO.TableDef
)
On
Error
GoTo
err
Dim
oInd As
DAO.Index
'Parcours les index
For
Each
oInd In
oTbl.Indexes
'S'il s'agit d'une clé primaire, alors le supprimer
If
oInd.Primary
Then
oTbl.Indexes.Delete
(
oInd.Name
)
End
If
Next
oInd
Exit
Sub
err
:
MsgBox
"Une erreur inattendue est survenue"
End
Sub
Utilisation :
Dim
oDb As
DAO.Database
Dim
oTbl As
DAO.TableDef
'Instancie la base
Set
oDb =
CurrentDb
'Instancie la table
Set
oTbl =
oDb.TableDefs
(
"Client"
)
'Supprime la clé primaire
SupprimerClePrimaire oTbl
4-6. L'objet Relation▲
4-6-1. Définitions▲
Certaines applications sont jugées sur leur performance ou leur ergonomie. Lorsqu'il s'agit d'une base de données, les critères de sélection ne sont plus les mêmes. Le rôle principal d'un SGBD est de stocker des données et ce stockage doit être réalisé dans les meilleures conditions. Il serait dramatique que certaines données soient perdues fréquemment. Une application Access doit donc garantir la cohérence et l'intégrité des données. Imaginons une table Commande et une table Client, il serait illogique d'affecter une commande à un client non recensé dans la table Client. Afin d'éviter ce risque , le moteur Jet permet de créer des contraintes d'intégrités par le biais de ses objets Relations qui obligeront à saisir un client valide dans la table des commandes.
4-6-2. Liste des propriétés▲
4-6-2-1. Attributes▲
Type : Long
La propriété Attributes correspond au type de la contrainte représentée par l'objet Relation. La valeur de cette propriété doit être une (ou une combinaison) des constantes suivantes :
Constante | Signification |
---|---|
dbRelationUnique | Relation de type un à un. |
dbRelationDontEnforce | L'intégrité référentielle n'est pas appliquée. |
dbRelationUpdateCascade | Les mises à jours sont répercutées en cascade. |
dbRelationDeleteCascade | Les suppressions sont répercutées en cascade. |
dbRelationLeft | Les jointures seront de type Left par défaut. |
dbRelationRight | Les jointures seront de type Rigth par défaut. |
4-6-2-2. Fields▲
Type : Collection
Cette collection regroupe l'ensemble des champs utilisés par la relation. Vous devez utiliser la méthode Relation.CreateField pour créer de nouveaux champs dans la relation et les ajouter à la collection Fields à l'aide de la méthode Append.
Chaque objet Field de la relation doit posséder le nom du champ concerné dans la table spécifiée dans la propriété Table. Ce champ aura comme propriété ForeignName, le nom d'un champ de la table spécifiée dans la propriété ForeignTable.
4-6-2-3. ForeignTable▲
Type : String
La propriété ForeignTable correspond au nom de la table externe de la relation. Ce nom doit être celui d'un objet TableDef présent dans la collection TableDefs de l'objet Database.
4-6-2-4. Name▲
Type : String
La propriété Name représente le nom de la relation. Il doit être unique au sein de la collection Database.Relations.
L'utilisation de nom précis facilitera les opérations de maintenance sur la base de données. Ainsi, une relation entre une table commande et une table client sera nommée Rlt_CommandeClient. Evitez d'appeler vos objets Relation1, Table1, Requete1...
4-6-2-6. Properties▲
Type : Collection
La collection Properties regroupe l'ensemble des propriétés de l'objet Relation.
4-6-2-7. Table▲
Type : String
La propriété Table correspond au nom de la table principale sur laquelle porte la relation. Il s'agit de la table possédant la clé primaire utilisée dans la relation. A contrario, la propriété ForeignName correspond à la table possédant la clé étrangère de la relation.
4-6-3. Liste des méthodes▲
Les objets de type Relation ne possède qu'une seule méthode : CreateField. Celle ci permet de créer un champ à ajouter à la relation.
Syntaxe :
Set
field =
relation.CreateField
(
name)
Name correspond au nom du champ de la clé primaire utilisée dans la relation.
4-6-4. Exemple de définition des propriétés▲
Considérons deux tables et la relation suivante :
Paramètres de la relation :
Les propriétés d'une telle relation seront définies ainsi :
- Attributes : dbRelationUpdateCascade
- Fields : Un objet Field nommé "NumClient" et ayant comme propriété ForeignName : "IDClient"
- ForeignTable : "Commande"
- Name : "Rlt_CommandeClient"
- PartialReplica : False (Non utilisé)
- Table : "Client"
4-6-5. Opérations sur les relations▲
Je vous propose une suite de quelques exemples de code VBA afin de manipuler les objets Relations
4-6-5-1. Créer une relation▲
Reprenons l'exemple ci-dessus. Je vous livre le code correspondant à une telle relation.
La première méthode consiste à créer la relation et affecter à chacune des propriétés sa valeur correspondante.
Dim
oDb As
DAO.Database
Dim
oRlt As
DAO.Relation
Dim
oFld As
DAO.Field
Set
oDb =
CurrentDb
'Crée la relation
Set
oRlt =
oDb.CreateRelation
'Définit les propriétés
oRlt.Attributes
=
dbRelationUpdateCascade
oRlt.ForeignTable
=
"Commande"
oRlt.Name
=
"Rlt_CommandeClient"
oRlt.Table
=
"Client"
'Crée le champ dans la relation
Set
oFld =
oRlt.CreateField
(
"NumClient"
)
'Définit le nom de la clé externe
oFld.ForeignName
=
"IDClient"
'Ajoute le champ
oRlt.Fields.Append
oFld
'Rafraîhit la collection Relations
oDb.Relations.Refresh
'Ajoute la relation
oDb.Relations.Append
oRlt
'Rafraîhit la collection Relations
oDb.Relations.Refresh
'Ferme la base de données
oDb.Close
Set
oDb =
Nothing
La seconde méthode consite à utiliser l'ensemble des arguments de la méthode CreateProperty. En effet celle-ci permet d'initialiser le nom de la relation, de la table, de la table externe ainsi que les attributs.
Syntaxe :
Set
relation =
database.CreateRelation
(
name, table, foreigntable, attributes)
Notre code devient alors :
Dim
oDb As
DAO.Database
Dim
oRlt As
DAO.Relation
Dim
oFld As
DAO.Field
Set
oDb =
CurrentDb
'Crée la relation
Set
oRlt =
oDb.CreateRelation
(
"Rlt_CommandeClient"
, "Client"
, _
"Commande"
, dbRelationUpdateCascade)
'Crée le champ
Set
oFld =
oRlt.CreateField
(
"NumClient"
)
'Définit le nom de la clé externe
oFld.ForeignName
=
"IDClient"
'Ajoute le champ
oRlt.Fields.Append
oFld
'Rafraîhit la collection Relations
oDb.Relations.Refresh
'Ajoute la relation
oDb.Relations.Append
oRlt
'Rafraîhit la collection Relations
oDb.Relations.Refresh
'Ferme la base de données
oDb.Close
Set
oDb =
Nothing
4-6-5-2. Compter les relations utilisant un champ donné▲
Cette fonction a déjà été utilisé lors de l'opération qui consistait à supprimer un champ dans un objet TableDef.
Le principe est simple, un champ est utilisé par une relation si :
- La table dont il provient est présent dans la propriété Table de la relation et que le nom d'un champ de la relation est égal au nom de ce champ.
- La table dont il provient est présent dans la propriété ForeignTable de la relation et qu'au moins un champ de cette relation possède une propriété ForeignName égale au nom de ce champ.
Il nous suffit donc de boucler sur l'ensemble des objets Relation de la base de données.
Private
Function
ChampDansRelation
(
oBaseDeDonnees As
DAO.Database
, _
strNomTable As
String
, strNomChamp As
String
) As
Integer
On
Error
GoTo
err
Dim
bolUtilise As
Boolean
Dim
oRlt As
DAO.Relation
Dim
oFld As
DAO.Field
'Parcours les relations
For
Each
oRlt In
oBaseDeDonnees.Relations
bolUtilise =
False
If
oRlt.Table
=
strNomTable Then
'Pour chaque champ, contrôle le nom du champ
For
Each
oFld In
oRlt.Fields
If
oFld.Name
=
strNomChamp Then
bolUtilise =
True
Next
oFld
ElseIf
oRlt.ForeignTable
=
strNomTable Then
'pour chaque champ, contrôle le nom étranger
For
Each
oFld In
oRlt.Fields
If
oFld.ForeignName
=
strNomChamp Then
bolUtilise =
True
Next
oFld
End
If
'Si la relation utilise le champ, on incremente le resultat
If
bolUtilise Then
ChampDansRelation =
ChampDansRelation +
1
Next
oRlt
Exit
Function
err
:
ChampDansRelation =
-
1
End
Function
Il devient alors possible de connaître le nombre de relations utilisant le champ NumClient de la table Client.
Utilisation :
Dim
oDb as
DAO.Database
Set
oDb=
CurrentDB
MsgBox
ChampDansRelation
(
oDb, "Client"
, "NumClient"
)
4-6-5-3. Supprimer les relations autour d'une table▲
Il peut s'avérer par fois utile de supprimer les relations portant sur une table avant de pouvoir modifier la structure de la table. Cette opération peut s'avérer fastidieuse et je vous suggère de créer une fonction automatisant cette tâche.
Public
Function
SupprimerRelationTable
(
oBaseDeDonnees As
_
DAO.Database
, strNomTable As
String
) As
Integer
Dim
oRlt As
DAO.Relation
'Pour chaque relation,
For
Each
oRlt In
oBaseDeDonnees.Relations
'si la table est utilisée
If
oRlt.Table
=
strNomTable Or
oRlt.ForeignTable
=
strNomTable Then
'Supprime la relation
oBaseDeDonnees.Relations.Delete
oRlt.Name
oBaseDeDonnees.Relations.Refresh
'Incrémente le compteur
SupprimerRelationTable =
SupprimerRelationTable +
1
End
If
Next
oRlt
End
Function
La fonction SupprimerRelationTable retourne le nombre de relations supprimées.
Utilisation :
Dim
oDb As
DAO.Database
Dim
oRlt As
DAO.Relation
Set
oDb =
CurrentDb
'Supprime les relations de la table Client
MsgBox
SupprimerRelationTable
(
oDb, "Client"
)
4-7. L'objet QueryDef▲
Nous sommes sur le point d'aborder le dernier objet de la partie DDL du modèle DAO. Cette partie commencera par une rapide présentation de l'objet, suivie de la liste des propriétés et des méthodes puis enfin, quelques exemples d'utilisation en VBA.
4-7-1. Définitions▲
Access est un des rares SGBDR permettant de stocker des requêtes SQL dans la base de données sans qu'il ne s'agissent de vues. Certes, une vue est le résultat de cette requête mais son contenu est statique. Pour visualiser les modifications intervenues dans le jeu d'enregistrements entre deux instants, il est nécessaire de recréer la vue. Une requête stockée dans une base de données Access est dynamique. Elle est réexecutée à chaque fois que vous la réouvrez. De telles requêtes sont modélisées par l'objet QueryDef dans DAO.
Ces requêtes peuvent être de plusieurs types : sélection, union, insertion, mise à jour, suppression, analyse croisée ...
Requêtes paramétrées :
DAO propose de gérer les paramètres des requêtes via la collection Parameters de l'objet QueryDef. Ces requêtes sont trop souvent oubliées dans Microsoft Access et remplacées par des requêtes SQL codées directement dans VBA. Pourtant, la manipulation de ces requêtes est trés simple :
PARAMETERS Param_Num Text ( 10 );
SELECT *
FROM Client
WHERE NumClient=Param_Num;
La clause PARAMETERS liste l'ensemble des paramètres avec leur type et (optionnellement) leur taille. La seconde partie de la requête, est celle que vous auriez écrit sans paramètre.
Ainsi, pour ouvrir un Recordset sur le client possédant le numéro AF36, le code VBA serait :
Dim
oDb As
DAO.Database
Dim
oQdf As
DAO.QueryDef
Dim
oRst As
DAO.Recordset
Set
oDb =
CurrentDb
Set
oQdf =
oDb.QueryDefs
(
"R01"
)
oQdf.Parameters
(
"Num"
).Value
=
"AF36"
Set
oRst =
oQdf.OpenRecordset
Afin de comparer, voici le même code sans utiliser les requêtes paramétrées :
Dim
oDb As
DAO.Database
Dim
oSQL As
String
Dim
oRst As
DAO.Recordset
Dim
StrSQL As
String
Set
oDb =
CurrentDb
StrSQL =
"SELECT * FROM Client "
&
_
"WHERE NumClient="
&
Chr
(
34
) &
"AF36"
&
Chr
(
34
)
Set
oRst =
oDb.OpenRecordset
(
StrSQL)
L'utilisation des requêtes paramétrées apparait donc plus intuitive et évite de manipuler des fonctions de conversion de chaîne. De plus, si demain, nous souhaitons modifier notre requête pour y ajouter une jointure, il nous suffit de modifier le code SQL correspondant dans la requête paramétrée. Si au contraire nous n'utilisons pas ces requêtes, il nous faut alors modifier notre code VBA aux différents endroit où la "requête" est mentionnée.
Si vous ouvrez un objet Database Db2 depuis la base de données Db1 et que vous éxecutez un objet QueryDef de Db2, les données seront prélevées depuis Db2 et non dans Db1. Chaque objet QueryDef travaille sur les données de l'objet Database qui le contient.
4-7-2. Liste des propriétés▲
Vous trouverez ci-dessous la liste des propriétés disponibles pour les objets QueryDef.
La propriété Prepare n'est pas documentée dans ce tutoriel.
4-7-2-1. Connect▲
Lecture seule.
Type : String
La propriété Connect renvoie la chaine de connexion utilisée par la requête lorsque celle ci provient d'une autre base de données.
4-7-2-2. DateCreated▲
Lecture seule.
Type : Date
Cette propriété renvoie la date à laquelle a été créé la requête.
4-7-2-3. Fields▲
Lecture seule.
Type : Collection
Une nouvelle fois, nous rencontrons cette collection qui regroupe l'ensemble des champs retournés par la requête.
Notez que vous pouvez différencier le nom d'un champ et son alias en utilisant la propriété SourceField de l'objet Field.
4-7-2-4. LastUpdated▲
Lecture seule.
Type : Date
Cette propriété renvoie la date à laquelle a été modifiée la requête pour la dernière fois.
4-7-2-5. MaxRecords▲
Type : Long
La propriété MaxRecords correspond au nombre d'enregistrements à renvoyer au maximum. Cette propriété peut être utilisée lorsque le poste client ne dispose pas de ressources suffisantes afin de traiter l'ensemble des données.
Cette propriété est disponible uniquement pour les requêtes utilisant une source de données ODBC.
4-7-2-6. Name▲
Type : String
La propriété Name représente le nom de la requête. Il doit être unique au sein de la collection Database.QueryDefs.
Lorsque vous utilisez la méthode CreateQueryDef et que vous ne spécifiez pas l'argument Name, la requête n'est pas sauvegardée dans la base de données à la fin du traitement.
4-7-2-7. Parameters▲
Type : Collection
Cette collection regroupe l'ensemble des paramètres d'un objet QueryDef. Il est impossible d'ajouter ou de supprimer des éléments de cette collection.
Un exemple d'utilisation de requête paramétrée est disponible dans les définitions des QueryDefs ci-dessus.
4-7-2-8. Properties▲
Type : Collection
La collection Properties regroupe l'ensemble des propriétés de l'objet QueryDef.
4-7-2-9. RecordsAffected▲
Lecture seule.
Type : Long
Dans le cas d'une requête action (Insert,Update,Delete), la propriété RecordsAffected retourne le nombre d'enregistrements affectés par l'ordre SQL.
4-7-2-10. ReturnsRecords▲
Type : Boolean
Cette propriété définit ou renvoie une valeur indiquant si une requête retourne des enregistrements.
La propriété ReturnsRecords est disponible uniquement pour les requêtes SQL directes.
4-7-2-11. SQL▲
Type : String
La propriété SQL correspond au code SQL de la requête.
Cette propriété correspond à l'argument SQL de la méthode Database.CreateQueryDef.
4-7-2-12. Type▲
Type : Long
La propriété Type renvoie le type de la requête. Cette propriété est définie automatiquement lorsque vous créez l'objet QueryDef. Toutefois, elle peut vous permettre de recenser les objets QueryDef suivant leur rôle.
Les valeurs possibles sont :
Constante | Signification |
---|---|
dbQAction | Action |
dbQAppend | Ajout |
dbQCompound | Non documentée |
dbQCrosstab | Analyse croisée |
dbQDDL | Définition de données |
dbQDelete | Suppression |
dbQMakeTable | CreateTable |
dbQProcedure | Procédure stockée |
dbQSelect | Sélection |
dbQSetOperation | Union |
dbQSPTBulk | Requête ne renvoyant pas d'enregistrement |
dbQSQLPassThrough | Requête SQL Directe |
dbQUpdate | Mise à jour |
4-7-2-13. Updatable▲
Lecture seule.
Type : Boolean
Cette propriété renvoie True si les données de la requête ne peuvent être modifiées.
4-7-3. Liste des méthodes▲
4-7-3-1. CreateProperty▲
La méthode CreateProperty crée un nouvel objet Property. Plus de détails sont disponibles dans le chapitre 4.2.5 Propriétés spécifiques.
4-7-3-2. Execute▲
La méthode Execute éxecute une requête Action. Une erreur sera levée si vous tentez d'exécuter une requête de sélection.
Syntaxe :
querydef.Execute
options
L'argument options doit être une (ou une combinaison) des constantes suivantes :
Constante | Signification |
---|---|
dbDenyWrite | Interdit l'accés en écriture pour les autres utilisateurs |
dbInconsistent | (Valeur par défaut) Exécute des mises à jour sans vérifier la cohérence (intégrité réferentielle) |
dbConsistent | Exécute des mises à jour en vérifiant la cohérence |
dbSQLPassThrough | Exécute une requête SQL Direct |
dbFailOnError | En cas d'erreur, les mises à jour sont annulées |
dbSeeChanges | Génère une erreur d'exécution si un autre utilisateur modifie les données que vous êtes en train de modifier |
Vous pouvez utiliser la propriété RecordsAffected pour connaître le nombre d'enregistrements modifiés.
4-7-3-3. OpenRecordset▲
La méthode OpenRecordset ouvre un jeu d'enregistrements sur le résultat de la requête.
Syntaxe :
Set
recordset =
object.OpenRecordset
(
type
, options, lockedits)
Cette méthode sera largement abordée dans le chapitre suivant.
4-7-4. Opérations sur les requêtes▲
4-7-4-1. Création d'une requête▲
Dans notre exemple nous allons créer une requête de sélection complète de la table clients. Il s'agit d'une requête simple et la méthode à appliquer est la même pour tout type de requête.
Sub
CreerRequete
(
)
On
Error
GoTo
Err
Dim
oDb As
DAO.Database
Dim
strCodeSql As
String
'Instancie l'objet database
Set
oDb =
CurrentDb
'Stocke le code SQL dans une variable
strCodeSql =
"SELECT * FROM Client"
'Crée la requête
oDb.CreateQueryDef
"R01_SelectionClient"
, strCodeSql
Finally
:
oDb.Close
Set
oDb =
Nothing
Err
:
'Gére les erreurs
Select
Case
Err
.Number
Case
3012
: MsgBox
"La requête existe déjà"
Case
Else
: MsgBox
"Une erreur inconue est survenue"
End
Select
Resume
Finally
End
Sub
4-7-4-2. Modifier le code d'une requête▲
Afin de modifier le code SQL, il faut procéder en deux étapes :
- Récuperer l'objet QueryDef correspondant (S'il existe).
- Modifier la propriété SQL de l'objet.
Public
Function
ModifierSQL
(
oBaseDeDonnees As
DAO.Database
, _
strNomRequete As
String
, strCodeSQL As
String
) As
Boolean
On
Error
GoTo
Err
Dim
oQdf As
DAO.QueryDef
'Instancie l'objet QueryDef
Set
oQdf =
oBaseDeDonnees.QueryDefs
(
strNomRequete)
'Modifie le code SQL
oQdf.SQL
=
strCodeSQL
'Renvoie True
ModifierSQL =
True
Exit
Function
Err
:
'Gere les erreurs
Select
Case
Err
.Number
Case
3265
: MsgBox
"Impossible de trouver la requête à modifier"
Case
Else
: MsgBox
"Une erreur inattendue est survenue"
End
Select
End
Function
Utilisation :
Dim
oDb As
DAO.Database
Set
oDb =
CurrentDb
If
ModifierSQL
(
oDb, "R01_SelectionClient"
, "SELECT NumClient FROM Client"
) Then
MsgBox
"Le code SQL de la requête a été modifié avec succés"
End
If
4-7-4-3. Lister les requêtes▲
La propriété Type retourne le type d'un objet QueryDef. Il est donc possible de lister l'ensemble des requêtes de sélection.
Dim
oDb As
DAO.Database
Dim
oQdf As
DAO.QueryDef
'Instancie l'objet Database
Set
oDb =
CurrentDb
'Boucle sur les objets QueryDef
For
Each
oQdf In
oDb.QueryDefs
'S'il s'agit d'une requête de sélection, alors afficher son nom
If
oQdf.Type
=
dbQSelect Then
MsgBox
oQdf.Name
, , "Sélection"
Next
oQdf