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

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énements intéressants 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'enregistrements, 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 clef é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.

Évidemment; on peut 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 clef 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 clef 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 et 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 clef primaire de cette table devient alors la clef primaire de tout le recordset.

Clients.

VI-B-5. Update Criteria

Définit 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 clefs.

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 clefs (défaut)

AdCriteriaTimeStamp

3

Utilise le champ TimeStamp au lieu des champs clef.

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'autre. 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éfinit 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. À chaque mise à jour réussie 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éé 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 crochets 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 simples quotes ' 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ésente 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. À 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'enregistrements. 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'objets 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ées 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'enregistrements 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 multichamp 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. Évé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éfinit 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é 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 et 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 lignes extraites

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 et 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 et 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 enregistrements 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é 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 à jour 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 et 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 à jour du recordset, ce sont des événements de recordset, ils n'influent jamais directement sur la base de données.

VI-E-7. WillMove et 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'enregistrement 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.