IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Comprendre les Recordset ADO

Comprendre les Recordset ADO


précédentsommairesuivant

VI. L'objet Recordset

Avant de nous lancer dans des exemples concrets, nous allons voir quelques propriétés, méthodes et événement intéressant de l'objet Recordset. Je vais faire assez bref, et nous verrons les concepts intéressants plus en détail dans la troisième partie de cet article.

VI-A. Propriétés

Je ne vais pas reprendre celles qui définissent le curseur.

VI-A-1. AbsolutePosition

Renvoie ou définit la position de l'enregistrement courant dans le Recordset. Toujours disponible avec les curseurs non en avant seulement.

VI-A-2. Bookmark

Permet d'utiliser des signets pour marquer les enregistrements. Toujours disponible avec les curseurs non en avant seulement.

VI-A-3. CacheSize

Renvoie ou définit le nombre d'enregistrements qui vont être stockée dans le cache.

VI-A-4. EditMode

Indique le statut de modification de l'enregistrement en cours.

Peut prendre les valeurs adEditNone, adEditInProgress, adEditAdd, adEditDelete

Très utile pour savoir si des actions sont en cours sur le recordset, ce qui permet le cas échéant d'annuler ou de valider ces modifications.

VI-A-5. Filter

Permet de filtrer les enregistrements d'un recordset selon les critères spécifiés. Le Recordset filtré se comporte comme un nouvel objet recordset. En général cette propriété ne s'utilise pas sur les recordset côté serveur car elle tend à faire s'effondrer les performances. Par contre on l'utilise beaucoup lors des traitements par lot des curseurs clients. Le filtre peut être de deux sortes :

Filtre SQL : il s'utilise comme une clause WHERE sans le WHERE.

Une des valeurs prédéfinies

Constante Valeur Description
AdFilterAffectedRecords 2 Filtre les enregistrements affectés par le dernier appel d'une méthode Delete, Resync, UpdateBatch ou CancelBatch.
AdFilterConflictingRecords 5 Filtre les enregistrements n'ayant pas pu être modifiés lors de la dernière mise à jour
AdFilterFetchedRecords 3 Filtre les enregistrements présents dans le cache
adFilterNone 0 Enlève le Filtre ce qui rétabli le recordset d'origine
AdFilterPendingRecords 1 Filtre les enregistrements en attente de mise à jour. Applicable uniquement pour les traitements par lot.

VI-A-6. Index

Définit l'index en cours dans le recordset. Uniquement utilisé avec la méthode Seek.

VI-A-7. MarshalOptions

Définit le mode de mise à jour lors de la reconnexion d'un recordset déconnecté. Peut prendre les valeurs

AdMarshalAll, adMarshalModifiedOnly.

Clients

VI-A-8. MaxRecords

Permet de définir un nombre maximum d'enregistrements que la requête peut renvoyer.

VI-A-9. RecordCount

Renvoie le nombre d'enregistrements disponible dans le recordset. Toujours disponible avec les curseurs qui ne sont pas de type "en avant seulement".

VI-A-10. Sort

S'utilise avec une chaîne contenant le(s) nom(s) de(s) champ(s) suivi de ASC ou DESC, chaque champ étant séparé par une virgule. Préférez toujours un tri par le SQL qui est beaucoup plus performant sur les recordset côté serveur.

VI-A-11. Source

Renvoie la source des données d'un recordset. Lorsqu'il s'agit d'un objet Command, renvoie la propriété CommandText de celui ci.

VI-A-12. State

Renvoie toujours l'état du recordset (fermé / ouvert). Dans le cas d'une connection asynchrone peut prendre les valeurs adStateConnecting, adStateExecuting, adStateFetching. Presque uniquement utilisé dans les cas asynchrones

VI-A-13. Status

Cette propriété est très importante, nous la reverrons d'ailleurs plus loin dans cet article. Elle indique l'état de l'enregistrement en cours lors d'une opération globale (ex : mise à jour par lot). Peut prendre une ou plusieurs des valeurs suivantes :

Constante Valeur Description
adRecOK 0 Mise à jour de l'enregistrement réussie
adRecNew 1 L'enregistrement est nouveau
adRecModified 2 L'enregistrement a été modifié
adRecDeleted 4 L'enregistrement a été supprimé
adRecUnmodified 8 L'enregistrement n'a pas été modifié
adRecInvalid 16 L'enregistrement n'a pas été sauvegardé parce que son signet n'est pas valide
adRecMultipleChanges 64 L'enregistrement n'a pas été sauvegardé parce que cela aurait affecté plusieurs enregistrements
adRecPendingChanges 128 L'enregistrement n'a pas été sauvegardé parce qu'il renvoie à une insertion en attente
adRecCanceled 256 L'enregistrement n'a pas été sauvegardé parce que l'opération a été annulée
adRecCantRelease 1024 Le nouvel enregistrement n'a pas été sauvegardé à cause du verrouillage d'enregistrements existants
adRecConcurrencyViolation 2048 L'enregistrement n'a pas été sauvegardé à cause d'un accès concurrentiel optimiste
adRecIntegrityViolation 4096 L'enregistrement n'a pas été sauvegardé parce que l'utilisateur n'a pas respecté les contraintes d'intégrité
adRecMaxChangesExceeded 8192 L'enregistrement n'a pas été sauvegardé parce qu'il y avait trop de modifications en attente

Dans le cas d'un traitement par lot il est indispensable d'aller lire cette propriété pour les enregistrements n'ayant pu être mis à jour.

VI-B. Propriétés dynamiques

On utilise ces propriétés en passant par la collection Properties de l'objet recordset. Elles dépendent principalement du fournisseur. Il en existe beaucoup ; je vous en cite quelques-unes que nous utiliserons dans des exemples. Les propriétés dynamiques se valorisent en générales après la définition du fournisseur pour l'objet, dans certains cas, après l'ouverture de l'objet.

VI-B-1. IrowsetIdentity

Permet d'implémenter l'interface Rowset OLEDB sur les curseurs serveurs. Certains contrôles ont besoin de cette interface pour afficher les données. Attends une valeur booléenne.

Exemple d'utilisation

Serveurs

VI-B-2. Optimize

Permet de créer un index sur un champ (objet Field) d'un recordset côté client. Cet index n'existe que dans le jeu d'enregistrement, mais n'est pas créé dans la base de données sous-jacente. L'ajout d'un index peut permettre un accroissement important des performances sur l'utilisation des recherches ou des filtres. Dans l'exemple suivant j'ajoute un index au champ "Author" avant d'exécuter le filtre :

 
Sélectionnez
Set Cnn1 = New ADODB.Connection
Cnn1.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:\biblio.mdb ;User Id=Admin; Password=" 
Set MonRs = New ADODB.Recordset
With MonRs
    .CursorLocation = adUseClient
    .ActiveConnection = Cnn1
    .Open "SELECT * FROM Authors", , adOpenStatic, adLockOptimistic, adCmdText
    .Fields("Author").Properties("Optimize") = True
    .Filter = "[ Author] like '*a'"
End With

Clients

VI-B-3. Resync Command

Permet de synchroniser un recordset créé à partir d'une jointure, lors de la modification ou de l'ajout de la clé étrangère d'une des tables. S'utilise toujours en conjonction avec la propriété dynamique "Unique Table". Attends une chaîne SQL étant la commande de synchronisation.

 

Evidemment; on peu se passer de cette propriété en ré exécutant les requêtes plutôt que de les synchroniser. Il ne faut toutefois pas perdre de vue que le coût d'exécution n'est pas le même.

Comme vous devez spécifier la table qui subira les modifications, vous devez aussi préciser la clé primaire de celle-ci à l'aide du marqueur (?).

Reprenons l'exemple ébauché dans la discussion sur les curseurs, nous allons donc utiliser une requête similaire à :

 
Sélectionnez
SELECT * FROM Publishers, Titles WHERE Publishers.PubID = Titles.PubID

Sous la forme simplifiée à des fins de lisibilité :

 
Sélectionnez
SELECT Publishers.PubID, Publishers.Name, Titles.Title, Titles.ISBN, Titles.PubID
FROM Publishers , Titles 
WHERE Publishers.PubID = Titles.PubID

Le but étant toujours de corriger le titre en changeant l'éditeur.

Nous allons utiliser le code suivant :

 
Sélectionnez
Dim Cnn1 As ADODB.Connection, MonRs As ADODB.Recordset

Set Cnn1 = New ADODB.Connection
Cnn1.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:\biblio.mdb ;User Id=Admin; Password="
Set MonRs = New ADODB.Recordset
With MonRs
    .CursorLocation = adUseClient
    .ActiveConnection = Cnn1
    .Open "SELECT Publishers.PubID, Publishers.Name, Titles.Title, Titles.ISBN, Titles.PubID FROM Publishers, Titles WHERE Publishers.PubID = Titles.PubID", _
		 , adOpenStatic, adLockOptimistic, adCmdText
    .Properties("Unique Table") = "Titles"
    'car les modifications réelles des données ne porteront que sur cette table
    .Properties("Resync Command") = "SELECT Publishers.PubID, Publishers.Name, Titles.Title, Titles.ISBN, Titles.PubID FROM Publishers, _ 
		 Titles WHERE Publishers.PubID = Titles.PubID AND Titles.ISBN=?"
    ' où Titles.ISBN=? précise la clé primaire de la table déclarée dans unique table
    .Find "Title='Evaluating Practice'"
    .Fields("Titles.PubId") = 192 'Numéro de l'éditeur Alpha Books
    .Fields("Title") = .Fields("Title") & "s"
    .Update
    .Resync adAffectCurrent
    Debug.Print .Fields("Name").Value
End With

Nous voyons alors que la valeur apparaissant dans la fenêtre exécution est la bonne et que la modification désirée a bien eu lieu dans la table.

Clients

VI-B-4. Unique Table, Unique Catalog & Unique Schema

Permet de désigner une table qui sera la cible unique des modifications d'un recordset issu d'une requête avec jointure. La clé primaire de cette table devient alors la clé primaire de tous le recordset.

Clients.

VI-B-5. Update Criteria

Défini comment le moteur de curseur va construire l'identification de l'enregistrement cible d'une modification, c'est à dire les valeurs qui apparaîtront dans le WHERE de la requête UPDATE. Prend une des valeurs suivantes :

Constante Valeur Description
AdCriteriaKey 0 Utilise uniquement les valeurs des champs clés.
AdCriteriaAllCols 1 Utilise les valeurs de tous les champs. (identique à un verrou optimiste)
AdCriteriaUpdCols 2 Utilise les valeurs des champs modifiés et des champs clés (défaut)
AdCriteriaTimeStamp 3 Utilise le champ TimeStamp au lieu des champs clé.

Attention à l'utilisation de adCriteriaKey. Ceci implique que l'enregistrement sera identifié correctement, et que la valeur sera mise à jour même si elle a été modifiée par quelqu'un d'autres. N'oubliez pas que les valeurs utilisées par le moteur de curseur sont les valeurs stockées dans la propriété OriginalValue des objets Fields concernés.

Clients

VI-B-6. Update Resync

 

Défini comment le recordset est synchronisé après un appel de la méthode Update ou UpdateBatch. N'oubliez pas que seuls les enregistrements modifiés ou ajoutés sont concernés par cette synchronisation. Prend une ou plusieurs des valeurs suivantes :

Constante Valeur Description
AdResyncNone 0 Pas de synchronisation
AdResyncAutoIncrement 1 Tente de renvoyer les valeurs générées automatiquement par le SGBD
AdResyncConflicts 2 Synchronise tous les enregistrements n'ayant pas pu être mis à jour lors du dernier appel de la méthode Update.
AdResyncUpdates 4 Synchronise tous les enregistrements mis à jour
AdResyncInserts 8 Synchronise tous les enregistrements ajoutés
AdResyncAll 15 Agit comme toutes les synchronisations précédentes.

Attention, le fait de paramétrer la propriété avec adResyncInserts ne suffira pas pour récupérer la valeur des champs à numérotation automatique. Dans ce cas vous devrez utiliser :

 
Sélectionnez
MonRs.Properties("Update Resync") = adResyncAutoIncrement + adResyncInserts

Clients

VI-C. Collection Fields

Chaque enregistrement d'un recordset est composé d'une collection Fields représentant les champs de l'enregistrement. Chaque objet Field possède un certain nombre de propriétés (type, taille, précision, etc...) qui sont propres au champ. Ils possèdent aussi tous une collection de propriétés dynamiques. Enfin ils possèdent aussi trois propriétés de "valeurs".

OriginalValue est la valeur du champ lors de la création du recordset. A chaque mise à jour réussi de l'enregistrement, cette propriété se synchronise avec la base. Nous verrons les problèmes que cela peut poser lors des traitements par lot.

UnderlyingValue est la valeur enregistrée dans la base du point de vue de l'utilisateur. C'est la propriété la plus difficile à appréhender. Si le curseur reflète les modifications de la base, cette propriété suit les modifications, sinon elle doit être synchronisée pour être juste.

Value est la valeur en cours du champ dans le recordset (pas nécessairement dans la base).

Nous verrons dans les exemples les utilisations de ces propriétés

VI-D. Méthodes

VI-D-1. AddNew

Ajoutes un nouvel enregistrement au recordset. De la forme

recordset .AddNew FieldList, Values

Ou FieldList et Values sont des paramètres facultatifs permettant d'entrer directement des valeurs dans le nouvel enregistrement.

Dès l'appel de AddNew, l'enregistrement créé devient l'enregistrement en cours.

Attention, l'utilisation des paramètres lance un Update implicite. Par exemple:

 
Sélectionnez
With MonRs
    .AddNew
    .Fields("Author") = "RABILLOUD, Jean-Marc"
    .Fields("year born") = 1967
    .Update
End With

Est équivalent à :

 
Sélectionnez
MonRs.AddNew Array("Author", "year born"), Array("RABILLOUD, Jean-Marc", 1967)

VI-D-2. CancelBatch

Annule les modifications en attente dans un traitement par lot. De la forme :

recordset.CancelBatch AffectRecords

Où AffectRecords détermine si la méthode porte sur un ou plusieurs enregistrements. Il peut prendre les valeurs adAffectAll, adAffectGroup ou adAffectCurrent.

Déclenche en fait un appel de la méthode CancelUpdate sur tous les enregistrements modifiés, ajoutés ou supprimés du recordset. Attention, comme toutes les opérations par lot, la méthode peut définir des erreurs dans la collection Errors de l'objet connection, sans interrompre le traitement.

VI-D-3. CancelUpdate

Annule les modifications apportées sur l'enregistrement en cours, ou annule l'enregistrement crée par AddNew.

VI-D-4. Clone

Duplique un objet Recordset. Les clones sont synchronisés avec l'original jusqu'à l'application de la méthode Requery sur celui-ci.

VI-D-5. Delete

Supprime un ou plusieurs enregistrements. De la forme :

recordset.Delete AffectRecords

Où AffectRecords détermine si la méthode porte sur l'enregistrement en cours ou sur tous les enregistrements qui correspondent à la propriété Filter.

VI-D-6. Find

Recherche les enregistrements répondant aux critères spécifiés. Cette méthode ne permet une recherche que sur un seul champ. De la forme :

recordset.Find (criteria, SkipRows, searchDirection, start)

SkipRows est une valeur facultative qui donne le décalage par rapport à la ligne en cours ou au paramètre Start, quand il est défini.

SearchDirection est une valeur facultative qui peut prendre les valeurs adSearchForward ou adSearchBackward

Start donne la position de l'enregistrement de démarrage de la recherche.

Criteria est l'expression du critère de recherche. Il se compose toujours du nom du champ suivi de l'opérateur de comparaison suivi de la valeur.

Le nom du champ doit être entre crochet s'il contient un espace

L'opérateur doit être (">" (supérieur à), "<" (inférieur à), "=" (égal) ">=" (supérieur à ou égal), "<=" (inférieur à ou égal), "<>" (différent de) ou "Like" (concordance avec un modèle).)

La valeur doit être entourée de simple quote ' s'il s'agit d'un texte, de dièse # si c'est une date ou de rien pour une valeur numérique.

Si aucun enregistrement correspondant n'est trouvé, le recordset se positionnera sur EOF ou BOF, selon le sens de la recherche.

N.B : Cette méthode est très coûteuse en ressource, essayez toujours de privilégier une méthode SQL sur les curseurs serveur.

VI-D-7. GetRows

Cette méthode permet de convertir un Recordset en tableau à deux dimensions (champ, enregistrement) de la forme :

Tableau = recordset.GetRows( Rows, Start, Fields )

Rows représentent le nombre d'enregistrements à convertir, si la valeur est -1 tous les enregistrements seront convertis à partir de la position donnée par le paramètre "Start", s'il est omis tous les enregistrements du Recordset seront convertis.

Start donne la position du premier enregistrement à convertir. Peut prendre les valeurs adBookmarkCurrent, adBookmarkFirst, adBookmarkLast

Fields est la liste des champs devant être converti.

Après l'appel de la méthode, le recordset se positionne sur le premier enregistrement non converti ou sur EOF.

VI-D-8. GetString

Renvoie le recordset sous forme d'une chaîne. De la forme :

Set Variant = recordset.GetString(StringFormat, NumRows, ColumnDelimiter, RowDelimiter, NullExpr)

Où StringFormat est toujours AdClipString

Les lignes sont délimitées par RowDelimiter, les colonnes par ColumnDelimiter et les valeurs NULL par NullExpr. Ces trois paramètres sont valides uniquement avec adClipString.

VI-D-9. MoveFirst, MoveLast, MoveNext, MovePrevious

Ces méthodes permettent de se déplacer dans le jeu d'enregistrements. A la différence des mêmes méthodes DAO, le déplacement de l'enregistrement en cours valide l'ensemble des modifications effectuées.

VI-D-10. Open

Ouvre le Recordset. Nous verrons plus loin qu'il y a plusieurs méthodes pour obtenir un jeu d'enregistrements. De la forme :

recordset.Open Source, ActiveConnection, CursorType, LockType, Options

CursorType et LockType sont les propriétés du même nom, ActiveConnection est un objet Connection (explicite) ou une chaîne de connexion (Implicite).

Options peut prendre une ou plusieurs valeurs (masque binaire) de CommandTypeEnum et de ExecuteOptionEnum qui sont des paramètres de la méthode Execute de l'objet Command.

CommandTypeEnum
Constantes Valeur Description
AdCmdUnspecified -1 Pas de spécification de type
AdCmdText 1 CommandText correspond à la définition textuelle d'une commande ou d'un appel de procédure stockée.
AdCmdTable 2 CommandText correspond au nom de table dont les colonnes sont toutes renvoyées par une requête SQL générée en interne.
AdCmdStoredProc 4 CommandText correspond au nom d'une procédure stockée.
AdCmdUnknown 8 Valeur utilisée par défaut. Le type de commande de la propriété CommandText est inconnu.
AdCmdFile 256 CommandText correspond au nom de fichier d'un Recordset permanent.
adCmdTableDirect 512 CommandText correspond à un nom de table dont les colonnes sont toutes renvoyées.

Ce paramètre doit être passé si le texte de la commande n'est pas une commande SQL, sous peine de ralentir le traitement.

ExecuteOptionEnum
Constantes Valeur Description
adAsyncExecute 16 Indique que la commande doit s'exécuter en mode asynchrone
adAsyncFetch 32 Indique que les lignes restant après la quantité initiale spécifiée dans la propriété "Initial Fetch Size" doivent être récupérées en mode asynchrone. Si une ligne nécessaire n'a pas été récupérée, le chemin principal est bloqué jusqu'à ce que la ligne demandée devienne disponible.
adAsyncFetchNonBlocking 64 Indique que le chemin principal n'est jamais bloqué pendant la recherche. Si la ligne demandée n'a pas été recherchée, la ligne en cours se place automatiquement en fin de fichier. Cela n'a pas d'effet si le recordset est ouvert en mode adCmdTableDirect

Ce paramètre doit être passé si l'on travaille en mode Asynchrone.

VI-D-11. Requery

Recrée le jeu d'enregistrements en ré-exécutant la requête. De la forme :

recordset.Requery Options

Où options est le même paramètre que dans le cas de la méthode Open.

Comme la requête est exécutée à nouveau, il peut y avoir des enregistrements en plus ou en moins ou provoquant des conflits du fait des actions d'autres utilisateurs. L'appel de la méthode déclenche une erreur si l'enregistrement en cours est en mode édition.

Attention, il n'est pas possible de modifier les paramètres du curseur dans l'appel de Requery. Pour modifier le curseur, vous devez utiliser Close puis Open.

VI-D-12. Resync

Met à jour le jeu d'enregistrement. Utilisée seulement sur des curseurs statiques ou en avant seulement ; si le curseur est côté client, il ne doit pas être en lecture seule De la forme

recordset.Resync AffectRecords, ResyncValues

Où AffectRecords spécifie les enregistrements à mettre à jour et ResyncValues précise si les modifications sont écrasées. Si la valeur est adResyncAllValues, toutes les modifications sont écrasées, on repart avec un recordset d'origine, si la valeur est adResyncUnderlyingValues les modifications en cours sont préservées.

Voyons comment cela fonctionne

Un objet Recordset peut être vu comme une collection d'enregistrements, chacun étant composé d'objet Field (champ). Lors de la création du recordset, chaque champ possède trois propriétés, OriginalValue, Value et UnderlyingValue qui représente la valeur du champ. Lorsque l'on fait des modifications on modifie la propriété Value, mais pas UnderlyingValue. Par comparaison des deux, le Recordset peut toujours "marquer" les enregistrements modifiés. Si on procède à une synchronisation des valeurs de la base, les propriétés UnderlyingValue reflètent les vraies valeurs de la base, mais les propriétés Valeurs peuvent ne pas être modifiées. Le fait de synchroniser le recordset peut donc permettre de voir par avance si des valeurs ont été modifiés par un autre utilisateur, en comparant les propriétés UnderlyingValue et OriginalValue avant de déclencher une mise à jour.

VI-D-13. Save

Sauvegarde le Recordset comme un fichier. Un tel Recordset est appelé jeu d'enregistrement permanent. De la forme recordset.Save FileName, PersistFormat

Où PersistFormat, précise si le recordset est sauvegardé comme un fichier XML ou selon un format spécifique. Nous verrons dans les exemples comment on peut utiliser ces recordset persistant, mais sachez dès à présent qu'il n'est pas nécessaire d'avoir le fournisseur qui a créé le recordset pour pouvoir l'ouvrir.

VI-D-14. Seek

Permet de faire une recherche multi champs sur les recordset indexés. Ne s'utilise que sur les curseurs serveurs. De la forme :

recordset.Seek KeyValues, SeekOption

Où KeyValues est une suite de valeurs de type "Variant". Un index consiste en une ou plusieurs colonnes ou le tableau contient autant de valeurs qu'il y a de colonne, permettant ainsi la comparaison avec chaque colonne correspondante.

SeekOption peut prendre les valeurs suivantes :

Constante Valeur Description
adSeekFirstEQ 1 Recherche la première clef égale à KeyValues
adSeekLastEQ 2 Recherche la dernière clef égale à KeyValues.
adSeekAfterEQ 4 Recherche soit une clef égale à KeyValues ou juste après l'emplacement où la correspondance serait intervenue.
adSeekAfter 8 Recherche une clef juste après l'emplacement où une correspondance avec KeyValues est intervenue.
adSeekBeforeEQ 16 Recherche soit une clef égale à KeyValues où juste avant l'emplacement où la correspondance serait intervenue.
adSeekBefore 32 Recherche une clef juste avant l'emplacement où une correspondance avec KeyValues est intervenue.

Pour utiliser la méthode Seek, il faut que le recordset supporte les index et que la commande soit ouverte en adCmdTableDirect.

Comme vous le verrez dans l'exemple le principe est simple, on ajoute un ou des index sur le(s) champ(s) cible de la recherche, et on passe le tableau des valeurs cherchées à la méthode Seek.

Serveurs

VI-D-15. Supports

Cette méthode est la meilleure amie du développeur ADO. Elle permet de savoir si un recordset donné va accepter une fonctionnalité spécifique. De la forme :

boolean = recordset.Supports( CursorOptions )

CursorOptions peut prendre les valeurs suivantes :

Constante Valeur Description
adAddNew 16778240 Vous pouvez utiliser la méthode AddNew pour ajouter de nouveaux enregistrements.
adApproxPosition 16384 Vous pouvez lire et définir les propriétés AbsolutePosition et AbsolutePage.
adBookmark 8192 Vous pouvez utiliser la propriété Bookmark pour accéder à des enregistrements spécifiques.
adDelete 16779264 Vous pouvez utiliser la méthode Delete pour supprimer des enregistrements.
adFind 524288 Vous pouvez utiliser la méthode Find pour localiser une ligne dans un Recordset.
adHoldRecords 256 Vous pouvez extraire plus d'enregistrements ou modifier la position d'extraction suivante sans valider toutes les modifications en attente.
adIndex 8388608 Vous pouvez utiliser la propriété Index pour donner un nom à un index.
adMovePrevious 512 Vous pouvez utiliser les méthodes MoveFirst et MovePrevious, et les méthodes Move ou GetRows pour faire reculer la position de l'enregistrement en cours sans recourir à des signets.
adNotify 262144 Indique que le fournisseur gère les événements du recordset
adResync 131072 Vous pouvez mettre à jour le curseur avec les données visibles dans la base de données sous-jacente, au moyen de la méthode Resync.
adSeek 4194304 Vous pouvez utiliser la méthode Seek pour localiser une ligne dans un Recordset.
adUpdate 16809984 Vous pouvez utiliser la méthode Update pour modifier les données existantes
adUpdateBatch 65536 Vous pouvez utiliser la mise à jour par lots (méthodes UpdateBatch et CancelBatch) pour transmettre des groupes de modifications au fournisseur.

On utilise dans le code la méthode Supports pour savoir comment va réagir le recordset et éviter de faire de la gestion d'erreurs a posteriori.

VI-D-16. Update

Sauvegarde les modifications apportées à l'enregistrement en cours. De la forme :

recordset.Update Fields, Values

Où Fields et Values sont la liste des champs et des valeurs à modifier (facultatif).

VI-D-17. UpdateBatch

Met à jour toutes les modifications en attente (opération par lot). De la forme

recordset.UpdateBatch AffectRecords

Où AffectRecords définit les enregistrements concernés.

Si toutes les modifications échouent, une erreur se produit, s'il n'y a que quelques échecs, ils sont ajoutés à la collection Errors de la connexion.

VI-E. Evènements

Pour pouvoir utiliser les évènements ADO, il faut déclarer la variable précédée du mot clé WithEvents.

Les évènements de l'objet Recordset sont tous appariés sauf un. Ce qui veut dire qu'il se produit un événement avant l'action concernée et un autre après. Ces évènements sont principalement utilisés en programmation asynchrone.

VI-E-1. AdStatusEnum

Valeur que peut prendre le paramètre adStatus présent dans presque tous les événements.

Constante Valeur Description
adStatusOK 1 Indique que l'opération qui a déclenché l'événement s'est passée avec succès
adStatusErrorsOccurred 2 Indique que l'opération qui a déclenché l'événement n'a pas pu se terminer correctement suite à une erreur
adStatusCantDeny 3 Indique qu'il est impossible d'annuler l'opération en cours
adStatusCancel 4 Une demande d'annulation a été demandée sur l'opération en cours
adStatusUnwantedEvent 5 Empêche de nouvelles notifications pendant le traitement d'un événement

VI-E-2. EndOfRecordset

 
Sélectionnez
Private Sub Recordset_EndOfRecordset(fMoreData As Boolean, adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset)

Se produit lorsque le recordset arrive en position EOF.

FMoreData défini s'il reste des enregistrements après. Doit être valorisé à "True" si pendant le traitement de l'événement on ajoute des enregistrements

AdStatus est l'état du recordset. Vaut adStatusOK si l'opération s'est bien passée et adStatusCantDeny si l'opération qui a déclenchée l'événement ne peut être annulée. Si vous devez modifier le recordset pendant la procédure, ce paramètre doit être mis à adStatusUnwantedEvent afin de supprimer les notifications non désirées.

Precordset est la référence à l'objet subissant l'événement.

VI-E-3. FetchProgress & FetchComplete

 
Sélectionnez
Private Sub MonRs_FetchProgress(ByVal Progress As Long, ByVal MaxProgress As Long, _
  adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset)

Cet événement se déclenche périodiquement lors des opérations d'extractions asynchrones de longues durées. Les paramètres :

Progress représente le nombre de ligne extraite

MaxProgress le nombre de lignes qui doivent être extraites

 
Sélectionnez
Private Sub MonRs_FetchComplete(ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, _ 
  ByVal pRecordset As ADODB.Recordset)

Se produit après la récupération du dernier enregistrement.

PError est un objet erreur ADO

VI-E-4. WillChangeField & FieldChangeComplete

 
Sélectionnez
Private Sub MonRs_WillChangeField(ByVal cFields As Long, _ 
	ByVal Fields As Variant, adStatus As ADODB.EventStatusEnum,  ByVal pRecordset As ADODB.Recordset)
 
Sélectionnez
Private Sub MonRs_FieldChangeComplete(ByVal cFields As Long, ByVal Fields As Variant, _
  ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset)

cFields est le nombre de champs modifiés et Fields un tableau contenant ces champs.

La méthode WillChangeField est appelée avant qu'une opération en attente modifie la valeur d'un ou plusieurs objets Field dans le Jeu d'enregistrements. La méthode FieldChangeComplete est appelée après modification de la valeur d'un ou plusieurs objets Field.

Là il convient bien de ne pas se mélanger dans les évènements. Ces évènements se produisent lorsque la propriété value d'un ou plusieurs objets Field(s) est modifiée. Cela n'a rien à voir avec la transmission de valeur vers la base de données.

Pour annuler la modification il suffit de mettre le paramètre adStatus à la valeur adStatusCancel dans l'événement WillChangeField.

VI-E-5. WillChangeRecord & RecordChangeComplete

 
Sélectionnez
Private Sub MonRs_WillChangeRecord(ByVal adReason As ADODB.EventReasonEnum, _
  ByVal cRecords As Long, adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset)
 
Sélectionnez
Private Sub MonRs_RecordChangeComplete(ByVal adReason As ADODB.EventReasonEnum, _ 
 ByVal cRecords As Long, ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset)

La méthode WillChangeRecord est appelée avant qu'un ou plusieurs enregistrements dans le Recordset ne soient modifiés. La méthode RecordChangeComplete est appelée après qu'un ou plusieurs enregistrement sont modifiés.

adReason peut prendre les valeurs suivantes : adRsnAddNew, adRsnDelete, adRsnUpdate, adRsnUndoUpdate, adRsnUndoAddNew, adRsnUndoDelete, adRsnFirstChange ou adRsnFirstChange.

Ce paramètre indique l'action ayant provoquée le déclenchement de l'événement.

cRecords renvoie le nombre d'enregistrements modifiés.

Ces évènements se produisent donc lorsqu'il y a modifications des recordset ou mise à jours des données. Ce sont des événements qui peuvent modifier ou annuler des modifications dans la base de données.

VI-E-6. WillChangeRecordset & RecordsetChangeComplete

 
Sélectionnez
Private Sub MonRs_WillChangeRecordset(ByVal adReason As ADODB.EventReasonEnum, _
  adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset)
 
Sélectionnez
Private Sub MonRs_RecordsetChangeComplete(ByVal adReason As ADODB.EventReasonEnum,_ 
 ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset)

La méthode WillChangeRecordset est appelée avant qu'une opération en attente modifie le Recordset. La méthode RecordsetChangeComplete est appelée après que le Recordset a été modifié.

adReason peut prendre les valeurs suivantes : adRsnReQuery, adRsnReSynch, adRsnClose, adRsnOpen

Ces évènements se produisent lors de remise à jours du recordset, ce sont des événements de recordset, ils n'influent jamais directement sur la base de données.

VI-E-7. WillMove & MoveComplete

 
Sélectionnez
Private Sub MonRs_WillMove(ByVal adReason As ADODB.EventReasonEnum, _ 
 adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset)
 
Sélectionnez
Private Sub MonRs_MoveComplete(ByVal adReason As ADODB.EventReasonEnum, _ 
 ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset)

La méthode WillMove est appelée avant que l'opération en attente change la position actuelle dans le Jeu d'enregistrements. La méthode MoveComplete est appelée après modification de la position actuelle dans le Recordset.

adReason peut prendre les valeurs suivantes : adRsnMoveFirst, adRsnMoveLast, adRsnMoveNext, adRsnMovePrevious, adRsnMove ou adRsnRequery

Attention à l'utilisation de ces évènements. De nombreuses méthodes provoquent une modification de l'enregistrements en cours ce qui déclenche systématiquement cet événement. De plus il est très facile d'écrire un événement en cascade.


précédentsommairesuivant

Copyright © 2003 bidou. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.