Accès aux données : ADO.NET
Objectif
Maîtriser l’accès aux bases de données, en utilisant les objets ADO.net
Mode d’emploi
Pour chacun des thèmes abordés, ce support de formation :
 présente les points essentiels
 renvoie à des supports de cours, des livres ou à la documentation en ligne du
constructeur, par le symbole :


propose des exercices pratiques par le symbole :

Autres symboles utilisés :

Point important qui mérite d’être souligné

A éviter à tout prix !

Manipulation à réaliser avec un utilitaire graphique (qui devrait
normalement simplifier le travail !)

Approfondissement : travail de documentation ou exercice supplémentaire,
à faire individuellement (non intégré dans le temps de formation moyen)
Lectures conseillées
-
Manuel de référence Microsoft ADO. NET, de David Sceppa
-
La documentation en ligne de VB .NET (très détaillée, et en français). Nous
indiquerons à chaque chapitre les recherches à effectuer dans l’index.
Outils de développement
Visual Studio .net
Microsoft SQL server
Sommaire
1
PRESENTATION GENERALE D’ADO .NET ...................................................... 3
1.1
Quelques mots sur l’architecture .NET de Microsoft .......................................................................... 3
1.2
Le modèle objet d’ADO .NET................................................................................................................ 3
1.3
Les objets du Fournisseur de données................................................................................................... 5
1.4
Les objets du DataSet ............................................................................................................................. 5
2
2.1
L’ACCES AUX DONNEES EN MODE CONNECTE ........................................... 6
La connexion ado .net ............................................................................................................................. 6
2.1.1
2.1.2
2.1.3
2.1.4
2.2
Créer une connexion par code ........................................................................... 6
Quelques propriétés et méthodes de l’objet SqlConnection ............................... 7
Créer et configurer une connexion avec l’assistant ........................................... 7
Accéder aux données, par l’explorateur de serveurs ......................................... 8
La commande ado .net............................................................................................................................ 9
2.2.1
Création et initialisation d’une commande par code ......................................... 9
2.2.2
Quelques propriétés et méthodes de l’objet Command ...................................... 9
2.2.3
Requêtes de mise à jour .................................................................................... 10
2.2.4
Requêtes paramétrées ...................................................................................... 11
2.2.4.1 Utilisation des commandes paramétrées, par code ............................................... 11
2.2.4.2 Quelques propriétés et méthodes des paramètres ................................................. 12
2.2.4.3 Création d’une commande paramétrée, avec l’assistant ..................................... 13
2.2.5
Requête de type SELECT .................................................................................. 13
2.2.5.1 Exécution d’une commande par ExecuteScalar() ................................................. 13
2.2.5.2 Exécution d’une commande par ExecuteReader() ............................................... 14
2.2.5.3 Quelques propriétés et méthodes de l’objet DataReader .................................... 15
2.3
Les transactions .................................................................................................................................... 18
2.3.1
2.3.2
2.4
L’utilisation des procédures stockées .................................................................................................. 19
2.4.1
2.4.2
2.4.3
3
3.1
Appel de la procédure stockée ......................................................................... 19
Récupération des résultats de la procédure stockée ........................................ 20
Procédure stockée et gestion des transactions ................................................. 20
L’ACCES AUX DONNEES EN MODE DECONNECTE .................................... 22
Le DataSet ............................................................................................................................................. 22
3.1.1
3.2
La gestion des transactions ............................................................................... 18
Quelques propriétés et méthodes de l’objet Transaction ................................. 19
Quelques propriétés et méthodes des objets DataSet et DataTable ................. 22
Le DataAdapter .................................................................................................................................... 23
3.2.1
Quelques propriétés et méthodes de l’objet DataAdapter ............................... 24
3.3
Utilisation du DataSet et du DataAdapter par code ......................................................................... 25
3.4
Utilisation du DataSet à l’aide de l’assistant ..................................................................................... 27
3.5
les controles liés ..................................................................................................................................... 29
3.5.1
3.5.2
Le DataBinding ................................................................................................ 29
Les DataGrids .................................................................................................. 30
3.5.3
3.6
4
Les ComboBox et les ListBox ........................................................................... 32
Les mises a jour via les datasets .......................................................................................................... 34
LES REPORTS ................................................................................................ 36
4.1
Création d’un Report ........................................................................................................................... 36
4.2
Exécution du report .............................................................................................................................. 37
Presentation generale d’ADO .NET
Dans la plupart des applications informatiques actuelles, il est indispensable d’accéder en
lecture ou en mise à jour à des bases de données, locales ou distantes. Ce document montre
comment utiliser Visual Studio .NET pour accéder aux données et pour les présenter à
l’utilisateur.
Quelques mots sur l’architecture .NET de Microsoft
Visual Studio .NET est une plate-forme de développement d’applications graphiques,
multilangages (Visual Basic .NET, C# etc..). Tous les exemples de ce document sont écrits
en VB .Net mais peuvent facilement être transposés dans n’importe quel langage de la plateforme.
Visual Studio .NET possède un modèle objet appelé ADO .NET (ActiveX Data Object
.NET), qui permet de se connecter à de nombreuses bases de données relationnelles. Le même
modèle est utilisable dans des applications client-serveur classiques écrites en VB .NET et
dans des applications Web basées sur ASP .NET (Active Server Page .NET).
WEB (ASP.NET)
Client (VB .NET )
Bibliothèque de classes communes
(Framework .NET)
IHM
Données
ADO.NET
Common Language Runtime
Système d’exploitation
ADO .NET fait partie d’une bibliothèque de classes (le Framework) qui peut fonctionner
sur plusieurs architectures : PC de bureau, Téléphones portables, Pocket PC. Toutes les
classes du Framework s’appuient sur une couche logicielle, la CLR (Common Language
Runtime) qui les interface avec les différents systèmes d’exploitation. La CLR est l’équivalent
dans le monde Microsoft, de la machine virtuelle Java.
Le modèle objet d’ADO .NET
ADO .NET permet de travailler en deux modes :
-
« connecté » : le poste client maintient une « connexion » réseau avec le serveur, et lui
envoie des requêtes pour lire ou écrire directement dans la base de données distante ;
-
« déconnecté » : le poste client effectue une copie locale des données en mémoire, dans
un DataSet (groupe de données). Le DataSet contient des tables qui permettent de copier
et d’organiser les données sur le poste client.
ADO.NET distingue :
-
La communication avec la base de données, qui s’effectue par un Fournisseur de
données (Data Provider). Il existe des fournisseurs génériques (préfixes OleDb, Odbc)
qui sont reconnus par la plupart des bases de données, et quelques fournisseurs
spécialisés pour un SGBD donné (préfixes sql pour SqlServer, oracle pour Oracle).
Dans ce document, nous prendrons toujours comme exemple le fournisseur d’accès pour
SqlServer.
-
La manipulation locale des données, que l’on peut recopier dans un DataSet
Les objets du Fournisseur de données
-
L’objet Connection permet de se connecter à une base de données en donnant le nom du
serveur, de la base, et le nom et le mot de passe d’un utilisateur connu du SGDB. En
utilisant l’objet Connection, votre programme effectue la même opération vis-à-vis du
serveur que la phase de connexion de l’utilisateur dans « L’Analyseur de requêtes ».
-
L'objet Command permet d’envoyer à la base de données, des requêtes SQL
d’interrogation ou de modification, avec ou sans paramètres. L’objet Command contient
une collection Parameters qui permet de passer des paramètres en entrée à la requête
avant son exécution sur le serveur, et de récupérer des paramètres de sortie après
exécution. A noter que l’objet Command permet également d’exécuter des procédures
stockées sur le serveur, et de récupérer leur valeur de retour.
-
Pour les requêtes qui renvoient des données (SELECT), on peut récupérer directement
ces données en mode connecté grâce au DataReader : cet objet simple permet de lire
séquentiellement les lignes sélectionnées par le SELECT, sans pouvoir les modifier ou
revenir en arrière.
-
L’objet DataAdapter est le support du mode « déconnecté ». Il est plus élaboré que le
DataReader et contient quatre commandes, correspondant aux quatre instructions SQL
de base : SELECT, UPDATE, INSERT, DELETE. Il permet de remplir le DataSet,
grâce à sa requête SELECT, et éventuellement de répercuter des mises à jour du DataSet
vers la base de données via les requêtes UPDATE, INSERT et DELETE.
Les objets du DataSet
-
Le DataSet stocke une copie des données en mode déconnecté, indépendamment de
toute base de données : on peut le remplir localement avec des tableaux, des collections.
Il peut être utilisé avec plusieurs bases de données, ou des fichiers XML.
-
Le DataSet constitue à lui seul une petite base de données relationnelles en mémoire. Il
contient une ou plusieurs tables (collection d'un ou plusieurs objets DataTable)
constituées de lignes (DataRowCollection) et de colonnes (DataColumnCollection), et
éventuellement des définitions de contraintes d’intégrité (clés primaires et clés
étrangères).
2 L’ACCES AUX DONNEES EN MODE CONNECTE
La connexion ado .net
2.1.1 Créer une connexion par code
a) Importer dans votre programme l’espace de noms System.Data.SqlClient qui contient le
fournisseur de données pour SqlServer, ou System.Data.OleDb pour le fournisseur générique
OleDb, ou System.Data.Odbc pour le fournisseur générique Odbc :
Imports System.Data
Imports System.Data.SqlClient
b) Créer une instance de la classe SqlConnection, en passant une chaîne de connexion à son
constructeur :
Dim co as SqlConnection
co = New SqlConnection("server=SERVEUR-CR;Initial Catalog=BanqueDémo;
User Id=stage;Password=stage;")
Syntaxe de la chaîne de connexion :
-
server : nom du serveur Sql Server
Initial Catalog : nom de la base de données
User Id : nom de l’utilisateur déclaré dans Sql Server
Password : mot de passe de l’utilisateur
On peut aussi créer la connexion avec le constructeur non paramétré, et renseigner sa
propriété ConnexionString
Dim co SqlConnection
co = New SqlConnection
co.ConnectionString = "server=SERVEUR-CR;Initial Catalog=BanqueDémo;
User Id=stage;Password=stage;"
c) Ouvrir la connexion
co.Open()
Jusqu’ici, VB .NET a seulement préparé un objet en mémoire, sans effectuer aucune
vérification. C’est à l’ouverture qu’il recherche le serveur sur le réseau, et l’interroge pour
vérifier le nom de l’utilisateur et son mot de passe. Si la chaîne de connexion est erronée, le
fournisseur de données génère une exception de la classe SqlException : par exemple,
« SQL Server n’existe pas ou l’accès est refusé ».

Documentation .Net (index) : Connection (objet) / Connexion à une source de
données à l’aide de ADO .NET
2.1.2 Quelques propriétés et méthodes de l’objet SqlConnection
Méthodes publiques
Méthode
Open
Close
BeginTransaction
CreateCommand
ChangeDatabase
Description
Ouvre la connexion vers une base de données avec les paramètres
spécifiés dans la propriété ConnectionString.
Ferme la connexion.
Lance une nouvelle transaction, en créant un objet de la classe
SqlTransaction qui fournit les méthodes commit et rollback
Crée et retourne un objet SqlCommand associé à SqlConnection
Modifie la base de données en cours d'un SqlConnection ouvert.
Propriétés publiques
Propriété
ConnectionString
State
Database
CommandTimeout
WorkstationId

Description
pour définir la connexion à une source de données : serveur, base de
données, utilisateur….
Obtient l'état actuel de la connexion.
Obtient le nom de la base de données en cours ou de la base de
données à utiliser une fois la connexion ouverte
Nombre de secondes d'attente avant de renvoyer une
erreur, suite à une tentative d'exécution d'une commande
Chaîne qui identifie le client de la base de données. S'il n'est pas
spécifié, nom de l'ordinateur client.
Documentation .Net (index) : SqlConnection
2.1.3 Créer et configurer une connexion avec l’assistant
Dans la boîte à outils, choisir un objet connexion : par exemple SqlConnection
pour une connexion vers SqlServer.
Dans la propriété ConnectionString, choisir Nouvelle connexion… et configurer la
connexion grâce à l’assistant Propriétés des liaisons de données : nom du serveur, nom de
l’utilisateur, mot de passe, base de données sur le serveur.
Toujours Tester la connexion avant de valider
2.1.4 Utiliser la connexion pour accéder aux données, par l’explorateur de serveurs
Pour travailler en client-serveur, nous avons besoin de visualiser les tables et leur contenu,
indépendamment du programme en cours de développement
Ceci peut se faire par n’importe quel client : Analyseur de requêtes, Enterprise
Manager mais aussi directement dans Visual Studio .NET, par l’explorateur de serveurs.
Cette méthode permet de tester la nouvelle connexion, et de vérifier les droits de
l’utilisateur sur les tables.
La commande ado .net
2.2.1 Création et initialisation d’une commande par code
-
Selon le fournisseur de données choisi, on utilisera la classe OleDb.OleDbCommand
ou SqlClient.SqlCommand.
-
Une commande doit toujours être reliée à une connexion, soit lors de son instanciation,
soit en affectant sa propriété Connection. Il faut bien sûr ouvrir cette connexion, avant
d’exécuter la commande.
-
Il existe trois types de commandes, qui permettent soit d’exécuter une procédure
stockée, soit de récupérer le contenu d’une table entière, soit d’exécuter une requête
SQL. Le type d’une commande est fixé par la propriété CommandType :
procédure stockée -> StoredProcedure
table entière
-> TableDirect
requête (par défaut) -> Text
-
L’énoncé de la commande – nom de procédure, de table ou chaîne de requête selon le
cas - est renseigné par sa propriété CommandText - ou encore lors de son instanciation
lorsqu'il s'agit d'une requête.
Dim commande As SqlCommand
' création d'une nouvelle commande
commande = New SqlCommand
' on rattache la nouvelle commande à la connexion en cours
' (voir création et ouverture de la connexion dans l’extrait précédent)
commande.Connection = co
' type de commande : ici une requête SQL
commande.CommandType = CommandType.Text
' texte de la requête SQL
commande.CommandText = "INSERT Compte (Nom, Prénom, Solde) VALUES ('Lécu',
'Régis', 10000)"
-
Dans cet exemple, la commande est figée : elle insère dans la base un utilisateur connu
à l’avance.
-
On peut généraliser simplement cette méthode en construisant dynamiquement le texte
de la requête SQL, par des concaténations de String :
commande.CommandText = "INSERT Compte (Nom, Prénom, Solde) " + "VALUES ('"
+ txtNom.Text + "','" + txtPrenom.Text + "'," + txtSolde.Text + ")"

Documentation .Net (index) : SqlCommand
2.2.2 Quelques propriétés et méthodes de l’objet Command
Méthodes publiques
Méthode
CreateParameter
ExecuteNonQuery
Description
Crée un nouvel objet Paramètre.
Exécute la commande et renvoie le nombre de lignes affectées dans
ExecuteReader
ExecuteScalar
Prepare
le cas de INSERT, UPDATE et DELETE, et renvoie -1 dans le cas
de SELECT
Exécute la commande et crée un objet DataReader
Exécute la commande et récupère un résultat unique sans créer de
jeu de données.
Permet de compiler la requête avant de l’exécuter
Propriétés publiques
Propriété
CommandText
CommandTimeOut
CommandeType
Connection
Transaction
Parameters
Description
Définit le texte de la requête SQL, le nom de la table, ou le nom de
la procédure stockée
Définit le temps avant la levée d’une exception, si la commande
n’aboutit pas
Type de la commande. Valeurs possibles :
Text : Requête SQL
StoredProc : Procédure stockée
TableDirect :Table (cette valeur n’existe que pour OleDbCommand)
Renvoie ou définit la connexion sur laquelle la commande est
définie
Renvoie ou définit la transaction à laquelle appartient la commande
Renvoie la collection des objets Parameters d’une commande
2.2.3 Requêtes de mise à jour
-
Cette méthode de l’objet commande permet d’exécuter des requêtes SQL de type
UPDATE, INSERT ou DELETE qui ne renvoient pas de lignes au poste client.
-
La valeur de retour donne le nombre de lignes affectées par la requête.
-
Il faut penser à gérer les exceptions renvoyées par le serveur : dans cet exemple, on
affiche le message de l’exception (ex.Message).
' voir création de la commande dans l’extrait précédent
Try
' on soumet la commande au serveur, sans interrogation.
' La méthode retourne le nombre de lignes affectées
Dim nblignes As Integer
nblignes = commande.ExecuteNonQuery()
Catch ex As Exception
MsgBox("Erreur insertion : " + ex.Message, MsgBoxStyle.Critical, Me.Text)
End Try

EXERCICE 1 Nous allons, pour découvrir ADO.net, concevoir et réaliser une
application bancaire de gestion des comptes courants. On ne gèrera pas les problèmes liés aux
virements inter banques.
La base de données sera gérée sur SQL-SERVER
La structure de la base est la suivante :
MCD :
COMPTE
NumCompte
Nom
0,n
Débite
r
1,1
VIREMENT
NumVirement
0,n
1,1
Crédite
r
MLD :
COMPTE (NumCompte, Nom, Prenom, Solde)
VIREMENT (NumVirement, NumCompteDebit, NumCompteCredit, Montant, Datevir)




NumCompte sera un numéro automatique.
Solde est initialisé par défaut à zéro.
Datevir est par défaut la date du jour.
NumCheque n’est pas en numéro automatique.
 EXERCICE 2 :
Créer une feuille permettant de saisir un nouveau compte.





Contrôler avant soumission que tous les champs sont remplis
Se connecter à la base
Exécuter la commande d’insertion
Se déconnecter
Gérer une éventuelle exception.
Dans cette première version de l’exercice, vous créerez par code les objets SqlConnection et
SqlCommand.
2.2.4 Requêtes paramétrées
2.2.4.1
-
Utilisation des commandes paramétrées, par code
La méthode précédente par concaténation de String devient vite fastidieuse, pour des cas
compliqués
-
La classe SqlCommand permet de construire des requêtes paramétrées. Dans le texte de
la commande (CommandText), les paramètres sont désignés par un nom quelconque
précédé du caractère @ (@num dans l’exemple suivant)
' Créer la commande RQInit, en passant la requête SQL à son constructeur
Dim RQInit as SqlCommand
RQInit = New SqlCommand("Update Compte Set solde=0 WHERE [email protected]")
-
Les objets de la classe SqlCommand possèdent une propriété Parameters qui permet de
déclarer les paramètres utilisés dans le texte de la commande. Chaque paramètre est luimême un objet de la classe SqlParameter qui doit être créé, initialisé et ajouté à la
collection Parameters de la commande.
' définir les paramètres en entrée de la commande : ici le numéro de compte
RQInit.Parameters.Add ( New SqlParameter("@num", SqlDbType.Int, 4) )
Dans cet exemple, on crée un seul paramètre de nom @num, de type SQL SqlDbType.Int,
de taille 4.
-
Avant de lancer la commande, il faut renseigner tous les paramètres en entrée. On
accède aux paramètres, dans la collection Parameters, soit par leur nom ( @num), soit
par leur indice ( 0 )
RQInit.Parameters ("@num").Value = Cint(txtNum.Text)
' on lance la commande paramétrée
RQInit.ExecuteNonQuery()


2.2.4.2
Documentation .Net (index) : SqlParameter
SqlCommand : propriété Parameters
Quelques propriétés et méthodes des paramètres
Méthodes publiques de la collection Parameters
Méthode
Add
Description
Permet d’ajouter un nouveau paramètre à la collection. Par ex :
commande.Parameters.Add ( New SqlParameter("@num",
SqlDbType.Int, 4)
Propriétés publiques de l’objet Parameter
Propriété
DBType
Direction
Description
Définit le type du paramètre.
Prend l’une des valeurs suivantes :
Input : paramètre d’entrée
InputOutput : paramètre d’entrée sortie
Output : paramètre de sortie
ReturnValue : représente un code retour
2.2.4.3
Création d’une commande paramétrée, avec l’assistant
 On peut aussi utiliser l’assistant pour créer des commandes paramétrées.
Dans la boîte à outils, choisir un objet commande : par exemple SqlCommand pour une
connexion vers SqlServer (ou OdbcCommand, OleDbCommand). Dans les propriétés de
la commande ainsi créée, on peut définir la propriété CommandText, avec une requête,
éventuellement paramétrée. Dans ce cas, on peut indiquer les paramètres utilisés à l’aide
de la propriété Parameters
 EXERCICE 2bis ;
Refaire l’exercice précédent en créant par la boîte à outils les objets SQLConnection et
SQLCommand ; utiliser une requête insert paramétrée.
2.2.5 Requête de type SELECT
Le jeu d'enregistrements récupéré suite à l'exécution d'un "select" d'une requête ou procédure
stockée s'exploite de 2 façons:
Soit en mode connecté, ligne par ligne, grâce à un objet DataReader permettant un accès en
lecture seule et en mode séquentiel, comme sur un flux classique. Ce mode a l'avantage de
décharger la mémoire puisqu'il ne stocke qu'une ligne à la fois, mais il oblige à garder la
connexion ouverte tout le long de son exploitation.
Soit en mode déconnecté, grâce à un objet DataSet qui est un cache en mémoire des données
extraites de la source de données, et qui facilite le travail grâce à des tables qu’il fabrique avec
des données provenant de sources disparates.. Ce mode de connexion est rapide et permet de
fermer la connexion, donc de libérer la base.
C’est le mode connecté que nous allons étudier dans un premier temps.
2.2.5.1
Exécution d’une commande par ExecuteScalar()
Cette méthode de l’objet commande permet d’exécuter des requêtes SQL de type
SELECT qui renvoient un résultat unique au poste client. La méthode renvoie la
première colonne de la première ligne du jeu de résultats retourné par la requête.
Dim commande As SqlCommand
Dim solde As Object ' objet retourné par ExecuteScalar
Try
' création d'une nouvelle commande
commande = New SqlCommand
' on rattache la nouvelle commande à la connexion en cours
commande.Connection = co
' type de commande : ici une requête SQL
commande.CommandType = CommandType.Text
' texte de la requête SQL
commande.CommandText = "SELECT solde FROM Compte WHERE NumCompte= " +
txtNum.Text
' on soumet la commande au serveur : ExecuteScalar renvoie la première
colonne de la première ligne envoyée par le serveur
solde = commande.ExecuteScalar()
...
2.2.5.2
Exécution d’une commande par ExecuteReader()
Cette méthode de l’objet commande permet d’exécuter des requêtes SQL de type
SELECT qui renvoient des lignes au poste client.
Attention : Les lignes renvoyées peuvent être accédées en lecture seule et en mode
séquentiel (en avant seulement)
Il faut d’abord créer une commande (soit par code, soit en utilisant l’assistant) - pour cela
voir chapitre précédent -.
On exécute ensuite la commande en récupérant le résultat dans un SqlDataReader en
appelant commande.ExecuteReader().
On peut ensuite utiliser la méthode Read() de l'objet DataReader pour obtenir une ligne
de résultats de la requête. La méthode Read() renvoie false lorsque l’on est en fin de
DataReader.
Pendant l'utilisation de SqlDataReader, la connexion associée est occupée à prendre
en charge le SqlDataReader et aucune autre opération ne peut être effectuée sur cette
connexion en dehors de sa fermeture. Cette situation subsiste jusqu'à ce que la méthode Close
du SqlDataReader soit appelée.
On navigue à l’intérieur d’un DataReader à l’aide de la méthode Read(). On peut accéder
à chaque colonne de la ligne retournée de différentes manières : en passant le nom ou la
référence ordinale de la colonne au DataReader. Cependant, pour une meilleure
performance, le DataReader fournit une série de méthodes qui vous permettent d'accéder aux
valeurs de colonnes dans leurs types de données natifs (GetDateTime, GetDouble, GetGuid,
GetInt32, etc.).
Par exemple :
Rd("Montant")
Rd(0)
Rd.Item("Montant")
Rd.Item(0)
Rd.GetDouble("Montant")
Rd.GetDouble(0)
' Toutes ces commandes
' font référence au même
' champ
Si plusieurs jeux de résultats sont retournés (cas ou plusieurs requêtes sont exécutées à la
suite), on peut naviguer entre les différents jeux de résultats à l’aide de la méthode
NextResult.
'création de la requête
Dim req As String
req = "SELECT * from personne where nom = " & txtnom.Text
Dim com As SqlCommand = New SqlCommand(req, con)
'exécution de la commande; le résultat est récupéré dans le
'DataReader rd qu’il faut ensuite balayer
Dim rd As SqlDataReader = com.ExecuteReader()
'personne inexistante
If rd.Read() = False Then
MessageBox.Show("personne inexistant", "Erreur")
Else
'affichage des infos personne
txtnom.Text = rd(1)
txtprenom.Text = rd(2)
txtadresse.Text = rd(3)
End If
...

Documentation .Net (index) : SqlDataReader, DataReader
2.2.5.3
Quelques propriétés et méthodes de l’objet DataReader
Méthodes publiques
Méthode
Close
GetDateTime,
GetDouble,
GetBoolean…..
GetSchemaTable
IsDbNull
NextResult
Read
Description
Ferme le DataReader.
Renvoie la valeur d’une colonne sous la forme d’une donnée typée.
On utilise la méthode IsDbNull avant, pour vérifier que la colonne
n’est pas nulle.
Permet de récupérer les informations des colonnes (schéma des
données) dans un objet DataTable.
Renvoie vrai si la donnée est nulle.
Permet de changer de jeu d’enregistrements (dans le cas où l’on a
plusieurs jeux d’enregistrements, issus de plusieurs requêtes qui
s’exécutent à la suite)
Se positionne sur l’enregistrement suivant. Renvoie True s’il existe
une ligne suivante, False sinon. Ne fait pas la récupération des
valeurs. Au début (à la création du DataReader), on est positionné
avant le premier enregistrement. Il faut donc faire un Read.
Propriétés publiques
Propriété
FieldCount
HasRow
IsClosed
Item
Description
Renvoie le nombre de colonnes présentes dans la ligne en cours
Renvoie vrai si le jeu d’enregistrements contient au moins une ligne
Renvoie vrai si l’objet est fermé
Renvoie la valeur de la colonne. On peut identifier la colonne par
son nom ou par sa position ordinale. On peut omettre la propriété
item. (Rd.Item(“montant”), Rd.Item(0) et Rd(0) sont équivalentes)
 EXERCICE 3 :
Afficher (par code) les détails d’un compte de numéro donné. Ce numéro sera saisi dans
un champ texte.


Avant soumission, vérifier que le numéro saisi est un entier valide
Gérer une éventuelle non existence du compte
 EXERCICE 3bis ;
Refaire l’exercice précédent en créant par la boîte à outils les objets SQLConnection et
SQLCommand.
Les transactions
2.3.1
La gestion des transactions
Les transactions ont pour objectif de garantir l’intégrité des données. Vous avez déjà vu le
principe de fonctionnement des transactions (Cf. cours SQL), ainsi que les différentes
techniques à mettre en œuvre.
Ces principes doivent être appliqués aussi depuis une application VB.Net qui met à jour des
données.
Voici une portion de code qui montre comment tout cela s'organise :
Try
'ouverture transaction
tr = con.BeginTransaction()
Dim req As String
req = "UPDATE ...
"
Dim com As SqlCommand = New SqlCommand(req, con)
'on precise que cette commande est associée à la transaction
com.Transaction = tr
'ensuite on exécute la requete
com.ExecuteNonQuery()
'on fait un commit si tout se passe bien
tr.Commit()
Catch ex As Exception
MessageBox.Show(Err.Description, "Erreur")
'on fait un rollback en cas d’erreur
if not isNothing(tr) Then
tr.Rollback()
end if
End Try
Nous validons les modifications avec Commit, à condition qu'aucune des requêtes ne renvoie
d'erreur. Si l'une échoue, nous abandonnons les mises à jour avec Rollback. On remarquera
l'utilisation du test permettant de savoir si une transaction est ouverte avant de faire le
Rollback … En effet, lorsque l’on va en erreur, on n’a peut être pas encore ouvert la
transaction; dans ce cas, il ne faut pas faire de Rollback sous peine de plantage…

Documentation .Net (index) : Transaction (objet)
2.3.2
Quelques propriétés et méthodes de l’objet Transaction
Méthodes publiques
Méthode
Commit
Rollback
Save
Description
Valide la totalité de la transaction
Annule la transaction jusqu’au dernier état stable (soit la création de
la transaction, soit le dernier point Save défini).
Crée un point intermédiaire d’enregistrement de la transaction.
Propriétés publiques
Propriété
Connection
IsolationLevel
Description
Renvoie la connexion à laquelle est associée la transaction
Spécifie le niveau d’isolation de cette transaction
 EXERCICE 4 ;
 Compléter l’écran précédent pour gérer les dépôts d’espèces et les retraits


Avant soumission vérifier que le montant est un décimal valide
Mettre en place une transaction pour :
Vérifier le solde avant opération,
Exécuter l’opération,
En cas d’exception faire un rollback et signaler l’erreur.
Faire 2 versions de cet exercice : en créant par code, et à l’aide de la boîte à outils, les objets
SQLConnection et SQLCommand.
L’utilisation des procédures stockées
2.4.1
Appel de la procédure stockée
Une procédure stockée est un groupe d'instructions Transact-SQL qui est compilé une fois pour toutes
et peut être exécuté plusieurs fois. La procédure accepte des paramètres d'entrée et renvoie plusieurs
valeurs sous forme de paramètres de sortie et/ou de code retour.
ADO.NET permet d'appeler ces procédures au moyen de l'objet Command, dont la propriété
.CommandType sera alors mise à la valeur "StoredProcedure " et dont la propriété .CommandText
contiendra le nom de la procédure à invoquer.
Avant d'appeler la procédure stockée par la méthode ExecuteNonQuery(), il faut initialiser ses
paramètres en entrée (collection Parameters de l'objet Command) : chaque commande possède une
collection Parameters de paramètres (de types OleDbParameter ou SqlParameter) que l'on peut
définir ou lire individuellement pour passer ou recevoir des valeurs.
' on renseigne les paramètres en entrée de la procédure stockée
PSRetrait.Parameters("@NumCompte").Value = txtNumCompte.Text
PSRetrait.Parameters("@Montant").Value = txtMontant.Text
2.4.2
Récupération des résultats de la procédure stockée
Pour les paramètres autres que Input, vous devez définir la propriété ParameterDirection pour
spécifier si le type de paramètre est InputOutput, Output ou ReturnValue.
Après exécution, on récupère la valeur de retour et les paramètres en sortie de la procédure dans la
collection Parameters
Try
' on lance la procédure stockée (ExecuteNonQuery pour les
procédures qui ne renvoient pas d'informations par des SELECT)
PSRetrait.ExecuteNonQuery()
' on récupère la valeur de retour @return_value
Dim cr As Integer
cr = PSRetrait.Parameters("@return_value").Value
' si le compte rendu est OK, on récupère le paramètre en sortie
If cr = 0 Then
txtSolde.Text = PSRetrait.Parameters("@NouveauSolde").Value
' sinon on affiche le message d'erreur
Else
AfficherErreur(cr)
End If
Catch ex As Exception
MsgBox("Appel procédure stockée : " + ex.Message,
MsgBoxStyle.Critical, Me.Text)
End Try
2.4.3
Procédure stockée et gestion des transactions
Lorsque l’on encapsule la gestion des transactions dans une procédure stockée, et si l’on a une
exception lors de l'exécution de cette procédure, la transaction risque de rester ouverte. Il faut alors la
fermer depuis VB.Net, dans la gestion des exceptions (dans le catch..), en allant exécuter une requête
qui va vérifier si une transaction est ouverte et, si oui, qui fait un rollback.
' Procédure stockée de vérification, en Transac SQL
if @@TRANCOUNT>0
rollback transaction
return (0)
 EXERCICE 5 :
 Construire une nouvelle feuille permettant de saisir et valider un virement de compte à
compte.
- Saisir séparément chaque numéro de compte et la clé. La clé n’est pas un champ de la
table compte, c’est le reste de la division par 7 du numéro de compte.
- Les boutons « valider », après saisie du numéro de compte (débiteur ou créditeur),
vérifient que la clé correspondante est cohérente avec le numéro de compte, vérifient
l’existence du compte, et affichent le nom du client correspondant pour un contrôle
visuel.
- Dès que le numéro (ou la clé) est modifié(e), les champs nom et prénom sont effacés.
- Effectuer les contrôles : le virement n’est possible que si débiteur et créditeur ont été
validés, le numéro de virement doit être un entier valide et ne doit pas déjà exister, et le
montant doit être un décimal valide.
- Faire le traitement dans une procédure stockée bien protégée, avec code retour et
sécuriser le virement dans une transaction, annuler en cas d’incident.
- Tester en simulant un crash entre les deux mises à jour (débit et crédit).
3 L’ACCES AUX DONNEES EN MODE DECONNECTE
Le DataSet
Un DataSet (ou groupe de données) est un cache en mémoire qui représente un jeu de données
composé de plusieurs tables, de relations entre les différentes tables, et de contraintes qui s’appliquent
aux données. Ce cache est déconnecté de la source de données.
Plusieurs cas d’utilisation d’un DataSet peuvent être envisagés :



Il peut être utilisé pour gérer des données locales à l’application : dans ce cas, on peut créer
des DataTables, DataRelations et Constraints dans un DataSet et remplir les tables de
données par programme.
Il peut être rempli à partir d’une ou plusieurs sources de données existantes : dans ce cas on
utilise un DataAdapter pour remplir les différentes tables.
Il peut être rempli à partir de données XML.
Étant donné que le DataSet est indépendant de la source de données, il peut inclure des données
locales par rapport à l'application ainsi que des données provenant de plusieurs sources. L'interaction
avec les sources de données existantes est contrôlée par le DataAdapter
Un conseil : essayez toujours de limiter au maximum la taille d'un groupe de données en le
remplissant uniquement avec les enregistrements dont vous avez besoin.
Les DataSets utilisent le modèle objet suivant :
Modèle d'objet DataSet
Pour simplifier, un DataSet est composé d'une collection de tables (sa propriété .Tables), chaque table
(objet de type DataTable) étant elle même composée d'une collection de colonnes (sa propriété
.Columns) pour son schéma (objets de type DataColumn) et de lignes (sa propriété .Rows) pour son
contenu (objets de type DataRow).

3.1.1
Documentation .Net (index) : DataSet
Quelques propriétés et méthodes des objets DataSet et DataTable
Méthodes publiques de l’objet DataSet
Méthode
Description
AcceptChanges
Clear
Merge
Reset
Valide toutes les modifications en cours (méthode existant aussi
pour les objets DataTable et DataRow). Bascule toutes les lignes de
toutes les tables vers l’état ‘Unchanged’
Supprime toutes les lignes de toutes les tables du DataSet. A faire
avant de recharger un DataSet.
Permet de fusionner deux DataSet
Réinitialise le DataSet dans son état d’origine
Propriétés publiques de l’objet DataSet
Propriété
Relations
Tables
Description
Obtient la collection des relations qui relient les tables et permettent
de naviguer entre tables.
Obtient la collection des tables contenues dans le DataSet.
Méthodes publiques de l’objet DataTableCollection
Méthode
Add
Description
Ajoute une table à la collection des tables du DataSet
Propriétés publiques de l’objet DataTable
Propriété
Columns
Constraints
PrimaryKey
Rows
Description
Obtient la collection des colonnes de la table.
Obtient la collection des contraintes de la table
Renvoie un tableau d’objets DataColumn qui contient la ou les
colonnes composant la clé primaire de la table.
Obtient la collection des lignes de la table
Le DataAdapter
Chaque fournisseur de données .NET Framework fourni avec le .NET Framework dispose d'un objet
DataAdapter : (OleDbDataAdapter, SqlDataAdapter ou OdbcDataAdapter).
Un DataAdapter est utilisé pour extraire les données d'une source de données et remplir les tables
dans un DataSet. Le DataAdapter répercute aussi les modifications apportées au DataSet dans la
source de données.
Le DataAdapter utilise l'objet Connection du fournisseur de données .NET Framework pour se
connecter à une source de données, et les objets Command pour extraire les données de la source et y
répercuter les modifications.
La propriété SelectCommand du DataAdapter est un objet Command qui extrait les données de la
source de données. On peut aussi passer directement en paramètre la commande qui va permettre
d’extraire les données. Les propriétés InsertCommand, UpdateCommand et DeleteCommand du
DataAdapter sont des objets Command qui gèrent les mises à jour dans la source de données
conformément aux modifications faites dans le DataSet.
La méthode Fill du DataAdapter est utilisée pour remplir un DataSet avec les résultats de
SelectCommand du DataAdapter. Fill prend comme arguments un DataSet à remplir et un objet
DataTable ou le nom du DataTable à remplir avec les lignes retournées par SelectCommand.
Remarque : la méthode Fill ouvre automatiquement la connexion que le DataAdapter utilise, si la
connexion n'est pas déjà ouverte. Dans ce cas, la connexion sera automatiquement fermée lorsque le
Fill est terminé. Si l’on veut garder la connexion ouverte pendant plusieurs opérations (pour améliorer
les performances de l’application), il faut appeler de manière explicite la méthode Open de la
connexion, effectuer les opérations sur la source de données puis appeler la méthode Close de la
connexion.

3.2.1
Documentation .Net (index) : DataAdapter
Quelques propriétés et méthodes de l’objet DataAdapter
Méthodes publiques
Méthode
Fill
GetFillParameters
Update
Description
Permet de récupérer des données vers un DataSet. La valeur
retournée est le nombre de lignes rapatriées. Cette méthode utilise
l’objet Command du DataAdapter défini dans la propriété
SelectCommand. Si la connexion est fermée, le DataAdapter
l’ouvre le temps du rapatriement des données, puis la referme. Si
plusieurs jeux d’enregistrements sont rapatriés, il est créé autant de
tables que de jeux.
Permet de récupérer les paramètres de la requête Select définie dans
la propriété SelectCommand.
Cette méthode déclenche l’envoi des modifications faites dans le
DataSet vers la source de données. Elle renvoie le nombre de lignes
modifiées. Lors de l’appel de la méthode ‘Update’, le DataAdapter
regarde la propriété ‘RowState’ de chaque ligne et tente de
répercuter les modifications des lignes qui ne sont pas à
‘Unchanged’.
Pour chaque ligne, la commande concernée (InsertCommand,
DeleteCommand ou UpdateCommand) sera exécutée. Ces
commandes peuvent être définies par le programmeur. Si elles ne
sont pas définies, et si la commande concerne une table unique,
l’objet CommandBuilder va générer automatiquement ces
commandes à partir de la commande SelectCommand.
Propriétés publiques
Propriété
DeleteCommand
InsertCommand
SelectCommand
UpdateCommand
Description
Obtient ou définit une requête ou une procédure stockée pour
supprimer un enregistrement dans la source de données.
Obtient ou définit une requête ou une procédure stockée pour créer
un enregistrement dans la source de données.
Obtient ou définit une requête ou une procédure stockée permettant
de rapatrier des données dans le DataSet
Obtient ou définit une requête ou une procédure stockée pour mettre
à jour des enregistrements dans la source de données.
Utilisation du DataSet et du DataAdapter par code
On va commencer par créer le DataSet et le DataAdapter. Pour cela, on crée une commande associée à
la requête que l’on veut exécuter, et on crée un DataAdapter qui reçoit en paramètre la commande
créée. Tout ceci peut s’effectuer une seule fois (dans le load de la feuille par exemple).
' Apres avoir créé une connection, création d'une nouvelle commande
commande = New SqlCommand
' on rattache la nouvelle commande à la connexion en cours
commande.Connection = maConnexion
' type de commande : ici une requête SQL
commande.CommandType = CommandType.Text
' texte de la commande SQL : sélection sur toute la table
commande.CommandText = "SELECT * FROM Compte"
' création du Data Adapter : sert de lien entre le Data Set et le
' serveur
' Le Data Adapter reçoit en paramètre la commande qui va permettre
' de rapatrier les données du serveur
monDataAdapter = New SqlDataAdapter(commande)
' création du Data Set : réservoir local de données en mémoire
monDataSet = New DataSet
On va ensuite charger le DataSet. Le chargement du DataSet se fait par la méthode Fill() du
DataAdapter : on charge une table du DataSet ; il faut nommer cette table (ici, "mesComptes").
Attention, avant de rafraîchir le DataSet, il faut le vider à l’aide de la méthode Clear(), sinon les
données nouvelles viennent s’ajouter aux données déjà présentes.
' on vide le Data Set
monDataSet.Clear()
' on rafraichit le Data Set grâce au Data Adapter
monDataAdapter.Fill(monDataSet, "mesComptes")
' on affiche le nombre de lignes du Data Set, chargées en local
txtNbFiches.Text = monDataSet.Tables("mesComptes").Rows.Count
...
On va enfin exploiter les données contenues dans le DataSet :
txtNum.Text = monDataSet.Tables("mesComptes").Rows(i).Item("NumCompte")
txtNom.Text = monDataSet.Tables("mesComptes").Rows(i).Item("Nom")
txtSolde.Text = monDataSet.Tables("mesComptes").Rows(i).Item("solde")
Attention, si des colonnes sont facultatives et peuvent contenir une valeur nulle, il faut tester leur
contenu en utilisant IsDBNull().
 EXERCICE 6 :
 Construire une nouvelle feuille permettant de lire les comptes existants
- Le bouton charger permet la lecture en mode déconnecté (dans un DataSet) de tous les
comptes, et l’affichage du premier, ainsi que le nombre de comptes.
- Les boutons « premier », « dernier », « suivant », « précédent » permettent de naviguer
dans le DataSet et d’afficher le compte courant. Pensez à désactiver les boutons qui n’ont
pas de raison d’être.
Créer les DataSet et les DataAdapter par code.
Utilisation du DataSet à l’aide de l’assistant

On peut aussi créer le DataSet et le DataAdapter en utilisant les assistants.
On crée la connexion "maConnexion" par l'assistant, et on configure la chaîne de connexion en
sélectionnant "connexionString" dans les propriétés.
Ensuite, on crée un Data Adapter en le sélectionnant dans la boîte à outils. L’assistant de configuration
d’adaptateur de données se déclenche automatiquement, et va nous permettre de créer la commande
associée.
Enfin, on crée le Data Set à partir du Data Adapter, par l'option "Générer le Groupe de données" (click
droit sur le DataAdapter).
Seuls, le rafraîchissement du DataSet et l’exploitation des données sont à faire par code.
 EXERCICE 6bis :
 Refaire l’exercice précédent en utilisant les assistants.
les controles liés
3.5.1
Le DataBinding
Il est possible d’associer directement des données (issues d’une source de données) à des composants
de contrôle Win Forms : c'est le mécanisme du Data Binding. Le lien entre les données et le contrôle
est à double sens : les données peuvent être liées à l’une des propriétés du contrôle (pour être affichées
par exemple), et les modifications de données peuvent aussi être répercutées dans la source de
données.
Il existe des liaisons de données simples où un contrôle est lié à un seul élément de données (c’est le
cas des contrôles Text, Label) , et des liaisons de données complexes, où il est possible de lier un
contrôle à plusieurs éléments de données (c’est le cas des DataGrid et ListBox, ComboBox…).
Si l’on veut créer une liaison simple avec un contrôle dérivé de la classe
System.Windows.Forms.Control (par exemple, les contrôles Label, Button, TextBox, RadioButton
…), il faut utiliser la propriété .DataBindings de ce contrôle. Ceci permet d’accéder à la collection des
liaisons de données du contrôle. En ajoutant un objet de type Binding à cette collection, on peut lier
une propriété du contrôle à une source de données.
Exemple : Pour créer une liaison avec un textBox, dans la feuille de propriété des zones de texte,
choisir DataBindings, puis dans Text : on sélectionne le Data Set, la table et la colonne que l'on veut
associer à la zone de texte
Attention : en utilisant la feuille de propriété, on ne peut lier des contrôles qu'à des Data Set "Typés"
qui possèdent leur schéma XML (par code, tout est possible).
On peut ensuite utiliser par code certaines propriétés intéressantes de l’objet BindingContext de la
feuille. Cet objet sert schématiquement à la synchronisation des contrôles dépendants dans un
Windows Form qui sont liés à la même source de données:
' pour naviguer dans le DataSet, et se positionner sur une ligne (ici, la
première)
Me.BindingContext.Item(monDataSet, "Compte").Position = 0
....
' termine la modification en cours dans le champ texte qui a le focus
Me.BindingContext.Item(monDataSet, "Compte").EndCurrentEdit()
Attention : l’utilisation du DataBinding pour des contrôles simples (autres que les
DataGrids et DataCombos) ne nous paraît guère utile. En effet, seul le fait de mettre à jour
automatiquement les données liées nous semble fonctionnellement intéressant, mais est
dangereux en terme de gestion des transactions et des conflits d’accès. Il nous semble donc
préférable que le programmeur garde la maîtrise de son code, et gère lui-même les affichages et
les mises à jour associées à ces contrôles.
3.5.2
Les DataGrids
L'espace de noms System.Windows.Forms propose une classe DataGrid particulièrement bien
adaptée à l'affichage des données.
Un DataGrid sert à afficher des données liées sous forme de tableau et permet de les sélectionner, trier
et modifier.

Documentation .Net (index) : DataGrid
On utilise le DataGrid pour des liaisons de données complexes, afin d’afficher les champs d'une
source de données sous forme de colonnes dans un tableau. Chaque ligne représente un enregistrement
de la source de données.
Le DataGrid peut être lié au moment du design en définissant ses propriétés DataSource et
DataMember ou au moment de l'exécution en modifiant ces même propriétés ou en appelant la
méthode SetDataBinding().
Il est possible de lier un contrôle DataGrid à toute structure de données qui prend en charge l'interface
Ilist (ou un dérivé), et sous condition que les objets de cette structure exposent des propriétés
publiques.
Alors la grille affichera toutes les propriétés publiques des éléments de la structure de données.
Un tableau représentant une instance de la classe System.Array, une DataTable, un DataSet, ou une
DataView sont des exemples de structure adéquate.
Exemple de chargement d’un DataGrid à partir d’un DataSet :
' on crée une connexion, un adapter associé à la commande et un
DataSet. On remplit le DataSet grâce au DataAdapteur en créant la table
locale Personne
monDataAdapter.Fill(monDataSet, "Personne")
' on remplit le DataGrid avec la table "Personne" du DataSet
' Ceci n’est à faire qu’une fois !!!
dtgListe.DataSource = monDataSet
dtgListe.DataMember = "Personne"
'On peut aussi faire dtgListe.SetDataBinding(monDataSet, "Personne")
' Cela revient au même !!!
Exemple de rafraîchissement d’un DataGrid :
' on vide le Data Set
monDataSet.Clear()
' Attention, passer les bons paramètres si requête paramétrée
da.SelectCommand.Parameters(0).Value = cbnom.Text
' on rafraîchit le Data Set, grâce au Data Adapter
monDataAdapter.Fill(monDataSet, "Personne")
 EXERCICE 7 et 7bis ;
 Afficher tous les comptes dans une grille. (Faire une version par code et une version en
utilisant les assistants.)
 EXERCICE 8 et 8bis ;
 Afficher tous les comptes dans une grille pour un nom saisi. (Faire une version par code et
une version en utilisant les assistants.)
3.5.3
Les ComboBox et les ListBox
Le contrôle ListBox permet d'afficher une liste de choix d'éléments dans laquelle l'utilisateur peut
sélectionner en cliquant. Un contrôle ListBox peut fournir des sélections uniques ou multiples suivant
la valeur de la propriété SelectionMode.
Un ComboBox affiche un champ d'édition associé à un ListBox, permettant à l'utilisateur de
sélectionner dans la liste ou d'entrer un nouveau texte. Par défaut, un ComboBox affiche un champ
d'édition avec une liste déroulante masquée. La propriété DropDownStyle détermine le style de la
zone de liste déroulante à afficher.
Un CheckedListBox affiche un objet ListBox dans lequel une case à cocher est affichée à gauche de
chaque élément.
Les propriétés suivantes permettront de retrouver l’élément sélectionné : SelectedIndex, qui obtient
(ou définit) l'index de base zéro de l'élément sélectionné, et SelectedItem qui obtient (ou définit)
l’élément sélectionné.
Les collections SelectedIndices et SelectedItems contiennent respectivement les index et éléments
lors de sélections multiples.
De plus ces contrôles ont en commun des propriétés qui n’ont de sens que lors du DataBinding :
- DataSource, qui spécifie l’objet source de données,
- DisplayMember, qui spécifie la propriété (nom de la colonne) de la source de données qui doit
être affichée,
- SelectedValue, qui obtient (ou définit) la valeur sélectionnée,
'remplissage combobox
Dim req As String
'Attention!!! aux majuscules dans les noms de colonnes
req = "SELECT nom from Personnes"
Dim com As SqlCommand = New SqlCommand(req, con)
'Ouverture dataadapter
da.SelectCommand = com
da.Fill(ds, "nom")
'remplissage combobox
cbnom.DataSource = ds.Tables("nom")
cbnom.DisplayMember = "nom"
Attention à l'ordre des événements en VB .NET : il ne faut gérer l'événement SelectedIndexChanged
sur la liste déroulante que lorsque la fenêtre s'est complètement chargée, sinon on risque d’avoir
certaines anomalies. Pour cela, une solution consiste à ajouter, à la fin du chargement de la feuille
(load), un handler d’événement SelectedIndexChanged sur la combobox comme suit :
' dans le load de la feuille, terminer l'initialisation, pour accepter
les événements sur la liste déroulante en ajoutant un handler
d'événement sur la liste déroulante
AddHandler cbnNum.SelectedIndexChanged, AddressOf
cbnNum_SelectedIndexChanged
...
' dans l’événement selectedIndexChanged de la liste déroulante,
enlever le handler par défaut (comme suit :)
Private Sub cbnNum_SelectedIndexChanged(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles cbnNum.SelectedIndexChanged
 EXERCICE 9 et 9bis ;
 Comme précédemment mais les noms sont proposés dans une liste déroulante.
(Faire une version par code et une version en utilisant les assistants.)
 EXERCICE 10 ;
 A partir de l’exercice précédent, un double clic sur la grille, provoque l’ouverture d’un
nouvel écran, qui affiche tous les détails de ce compte et permet des modifications, sauf le
numéro de compte.
Conseils :






La grille sera affichée en mode déconnecté via un dataAdapter.
Le numéro de compte sera récupéré au double clic dans une variable.
Le deuxième écran sera ouvert en mode modal
Les détails du compte seront récupérés en mode connecté au load du deuxième écran.
La mise à jour sera effectuée en mode connecté.
A la fermeture du deuxième écran et lors du retour dans le premier, on en profitera pour
actualiser la grille.
Les mises a jour via les datasets
Si vous avez lié des éléments d’interface à un DataSet, les données saisies ou modifiées sont
répercutées automatiquement dans le DataSet. Par contre la mise à jour de la base de données n’est
pas automatique.
La méthode Update du DataAdapter est appelée pour répercuter de telles modifications dans la
source de données. La méthode Update, comme la méthode Fill, prend comme arguments une instance
d'un DataSet (qui contient les modifications apportées) et un objet DataTable (qui identifie la table
où les modifications doivent être extraites).
Lorsque vous appelez la méthode Update, le DataAdapter analyse les modifications apportées.
Lorsqu’il trouve une modification dans une ligne (DataRow), il utilise InsertCommand,
UpdateCommand ou DeleteCommand pour traiter la modification :
- Vous pouvez spécifier vous-même la syntaxe de la commande (des insert, update ou delete)
au moment du design et, si possible, par l'intermédiaire de l'utilisation de procédures
stockées. Vous devez explicitement définir les commandes avant d'appeler Update. Si
Update est appelé et si la commande appropriée n'existe pas pour une mise à jour
particulière (par exemple pas de DeleteCommand pour les lignes supprimées), une
exception sera levée.
- Dans le cas ou votre DataTable mappe une table de base de données unique, vous pouvez
générer automatiquement les DeleteCommand, InsertCommand et UpdateCommand du
DataAdapter, en utilisant l'objet CommandBuilder.
La méthode Update répercutera vos modifications dans la source de données, cependant d'autres
clients peuvent avoir modifié les données au niveau de la source depuis la dernière fois où vous avez
rempli le DataSet. Pour actualiser votre DataSet avec les données en cours, utilisez le DataAdapter et
remplissez (Fill) à nouveau le DataSet. De nouvelles lignes seront ajoutées à la table et les
informations mises à jour seront incorporées dans les lignes existantes.
La méthode Fill détermine si une nouvelle ligne sera ajoutée ou une ligne existante mise à jour en se
fondant sur les valeurs de clé primaire des lignes du DataSet et des lignes retournées par
SelectCommand. Si une valeur de clé primaire d'une ligne du DataSet correspond à celle d'une ligne
des résultats retournés par SelectCommand, la méthode Fill met à jour la ligne existante en y insérant
les informations de la ligne retournée par SelectCommand et définit pour le RowState de la ligne
existante la valeur Unchanged. Si la valeur de clé primaire d'une ligne retournée par SelectCommand
n'a pas de correspondance dans les lignes du DataSet, la méthode Fill ajoute une nouvelle ligne avec
un RowState ayant pour valeur Unchanged.
' on actualise le serveur avec les données du Data Set
Try
monDataAdapter.Update(monDataSet, "mesComptes")
Catch ex As Exception
MsgBox(ex.Message, MsgBoxStyle.Critical, Me.Text)
End Try
Attention : l’utilisation du DataSet pour effectuer des modifications (et plus
généralement le fait d’effectuer des modifications en mode déconnecté) n’est pas très
recommandé. Afin de garantir une bonne gestion des transactions et des conflits d’accès, il est
préférable d’effectuer les mises à jour en mode connecté.


Documentation .Net (index) : DataAdapter – méthode Update
Documentation .Net (index) : DataAdapter – Propiétés InsertCommand,
UpdateCommand, DeleteCommand
4 LES REPORTS
Création d’un Report
La création d’un report s’effectue à l’aide de l’outil intégré CrystalReport.
Pour créer un état, il faut ajouter un nouvel élément dans le projet, de type Etat Crystal Report.
On peut ensuite utiliser l’assistant Expert Etat, qui nous guidera tout au long du processus de
création de l'état.
Remarque : la Galerie d'états contient un certain nombre d'experts qui peuvent vous aider tout au
long de la création de types d'états spécifiques.
Il faut commencer par choisir les données constitutives de l’état. Lorsque l’on est sur cet écran, deux
solutions sont possibles : soit on crée complètement l’état en utilisant les assistants (dans ce cas,
cliquer sur OLEDB et recréer une connexion, choisir une table et des données à afficher,….), soit on
utilise un dataset (basé sur une connexion et une requête) que l’on aura créé par ailleurs (dans le
formulaire).
Cette seconde solution parait préférable dans la mesure où le programmeur reste maître de son code.
De plus, ceci évite de recréer une connexion différente à chaque état.
Si l’on utilise cette seconde solution, il faut affecter (par code), le Dataset au report, comme suit :
'Après avoir créé un
Private rep As cr
'ouvrir la connection et remplir le data set
Me.da.Fill(Me.Ds)
'transmettre le data set à l'état
rep = New cr
rep.SetDataSource(Me.Ds)
Ensuite on peut passer aux écrans suivants qui vont nous permettre de choisir les colonnes à intégrer
dans l’état, de faire de regroupements, d’intégrer des diagrammes, etc….
Exécution du report
Pour exécuter le report, on est obligé d’utiliser le composant CrystalReportViewer, que l’on rajoute à
la feuille (il est disponible dans la boîte à outils). Ce composant permet de pré-visualiser l’état et se
présente comme suit :
De nombreuses propriétés du CrystalReportViewer permettent de modifier son apparence.
Le CrystalReportViewer est lié au Report soit directement par sa propriété ReportSource, soit par code
de la manière suivante :
'lier le crystalviewer crv au Report rep
Me.crv.ReportSource = Me.rep
On peut ensuite imprimer l’état, soit en cliquant sur l’icône d’imprimante du CrystalReportViewer,
soit par code de la manière suivante :
'imprimer le Report associé au crystalviewer crv
crv.PrintReport()
Attention : lorsque l’on renseigne la propriété ReportSource du CrystalReportViewer dans l’écran
propriétés, le chemin du ReportSource est géré en absolu (et en dur), ce qui pose des problèmes de
portabilité.