Site:  Cours VB.net  
6.6 Charger des contrôles avec des SGBD.

A - Comment remplir des listBox avec des tables venant de base de données?

B - Comment remplir des DataGrid avec des tables venant de base de données?

C - Comment avec quelques click et sans une ligne de code, créer une application permettant d'afficher le contenu d'une base de données? (en VB 2005)

Cette liaison de données entre une source de données et un contrôle se nomme 'DATABINDING'.

A - Remplir une ListBox avec une colonne d'une table d'une BD:

Exemple:

Dans une base de données Accès nommé 'BaseNom', j'ai une table 'NomPatient' avec plusieurs colonnes, je veux afficher la colonne des noms dans une listBox:

 

Champs Civilité Champ Nom Champ Prénom Champ Numéro Interne

 

M. Durand Luc 1
Mme Dupont Josette 2
M. Thomas Guy 3

 

 

On peut utiliser un 'DataReader'

Voir la page 6-4  Lire rapidement en lecture seule: le DataReader

C'est de la 'lecture seule' très rapide.

 

On peut utiliser un 'DataSet', créer un 'DataTable' et la lier au contrôle.

Le DataSet est une représentation en mémoire des données; Une fois chargé on peut travailler en mode déconnecté.

Pour le remplir il faut un DataAdapter.

 

Bien sur il faut importer des espaces de nom:

 

Imports System

Imports System.Data

Imports System.Data.OleDb

 

Dans la zone déclaration de la fenêtre:

'Déclarer la connexion

Private ObjetConnection As OleDbConnection

' Déclaration l'Objet Commande

Private ObjetCommand As OleDbCommand

' Déclaration Objet DataAdapter

Private ObjetDataAdapter As OleDbDataAdapter

' Déclaration Objet DataSet

Private ObjetDataSet As New DataSet

'String contenant la 'Requête SQL'

Private strSql As String

' Déclaration Objet DataTable

Private ObjetDataTable As DataTable

'Paramêtres de connexion à la DB

Private strConn As String

 

Dans une routine  Button1_Click créer les divers objets et remplir la listbox.

 

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

'Initialisation de la chaîne de paramètres pour la connexion

strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source= c:\Basenom.mdb;"

'Initialisation de la chaîne contenant l'instruction SQL

strSql = "SELECT FICHEPATIENT.* FROM FICHEPATIENT"

'Instanciation d'un Objet Connexion

ObjetConnection = New OleDbConnection

'Donner à la propriété ConnectionString les paramètres de connexion

ObjetConnection.ConnectionString = strConn

'Ouvrir la connexion

ObjetConnection.Open()

'Instancier un objet Commande

ObjetCommand = New OleDbCommand(strSql)

'Instancier un objet Adapter

ObjetDataAdapter = New OleDbDataAdapter(ObjetCommand)

'initialiser l'objet Command

ObjetCommand.Connection() = ObjetConnection

'Avec l'aide de la propriété Fill du DataAdapter charger le DataSet

ObjetDataAdapter.Fill(ObjetDataSet, "FICHEPATIENT")

'Mettre dans un Objet DataTable une table du DataSet

ObjetDataTable = ObjetDataSet.Tables("FICHEPATIENT")

 

'Indiquer au ListBox d'afficher la table "fichepatient" (indiquer la source)

ListBox1.DataSource = ObjetDataSet.Tables("FICHEPATIENT")

'Indiquer quelle colonne afficher

ListBox1.DisplayMember = "NOM"

End Sub

 

Voilà, cela affiche la liste des noms.

 

Bien respecter les minuscules et majuscules dans les noms de tables et de champs+++

 

Récupérer la valeur d'un autre champ

 

 

On a vu que dans la table, chaque enregistrement avait un champ 'Nom' mais aussi un champ 'NumInt' (numéro interne)

Dans les programmes, on a souvent besoin de récupérer le numéro interne (un ID) quand l'utilisateur clique sur un des noms; le numéro interne servira a travailler sur ce patient.

 

Exemple: comment récupérer le numéro interne 3 quand l'utilisateur clique sur 'Thomas'?

 

Il faut indiquer à la ListBox que la Value de chaque ligne est 'NumInt' en utilisant la propriété ListBox1.ValueMember.

Quand l'utilisateur clique sur une ligne de la ListBox, cela déclenche l'évènement ListBox1_SelectedIndexChanged, là on récupère la valeur de NumInt correspondant; elle se trouve dans ListBox1.SelectedValue. (C'est un Int32)

 

Attention:

Les exemples de Microsoft ne fonctionnent pas!! car, on n'explique nulle part l'importance de l'ordre des lignes remplissant la ListBox.

 

 C'est DataSource qui semble  déclencher le chargement de la ListBox avec la prise en compte de DisplayMember et ValueMember.

 

Si on fait comme Microsoft (renseigner ListBox1.DataSource en premier):

ListBox1.DataSource = ObjetDataSet.Tables("FICHEPATIENT")

ListBox1.DisplayMember = "NOM"

ListBox1.ValueMember = "NUMINT"

 

ValueMember ne fonctionne pas bien, et ListBox1.SelectedValue retourne un objet de type DataRowView impossible à utiliser. 

 

Il faut donc renseigner le DataSource en dernier.

 

ListBox1.DisplayMember = "NOM"

ListBox1.ValueMember = "NUMINT"

ListBox1.DataSource = ObjetDataSet.Tables("FICHEPATIENT")

Dans ce cas ListBox1.SelectedValue contient bien un Int32 correspondant au 'NutInt' selectionné.

'Ensuite on peut récupérer sans problème NumInt (et l'afficher par exemple dans une TextBox)

Private Sub ListBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged

Dim o As New Object

If ListBox1.SelectedIndex <> -1 Then

TextBox1.Text = CType(ListBox1.SelectedValue, String)

End If

End Sub

 

 

B - Remplir un DataGrid avec une base de données via un DataSet:
 

Avec mise à jour de la base de donnée, si on fait une modification dans le Datagrid. Oui ça marche.(Depuis que j'ai ajouté le CommandBluider)

Il faut créer une Connection, un DataAdapter et un DataSet, puis en UNE ligne de code, on peut l'afficher dans un DataGrid.(Grille avec des lignes et des colonnes comme un tableur), ne pas oublier le CommandBuilder sinon Update ne marche pas.

Dans la zone de déclaration:

' Déclaration Objet Connection

Private ObjetConnection As OleDbConnection

' Déclaration Objet Commande

Private ObjetCommand As OleDbCommand

' Déclaration Objet DataAdapter

Private ObjetDataAdapter As OleDbDataAdapter

' Déclaration Objet DataSet

Private ObjetDataSet As New DataSet

' Déclaration Objet DataTable

Private ObjetDataTable As New DataTable

'String contenant la 'Requête SQL'

Private strSql As String

'Paramêtres de connexion à la DB

Private strConn As String

' Déclaration d'un  OleDbCommandBuilder

Private ObjetCB As OleDbCommandBuilder

 

 

Le bouton ButtonAfficheGrid remplie le DataGrid avec nom.mdb table 'FICHEPATIENT'

 

Private Sub ButtonAfficheGrid_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonAfficheGrid.Click

'Initialisation de la chaîne de paramètres pour la connexion

strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source= c:\nom.mdb;"

'Initialisation de la chaîne contenant l'instruction SQL

strSql = "SELECT FICHEPATIENT.* FROM FICHEPATIENT"

'Instanciation d'un Objet Connexion

ObjetConnection = New OleDbConnection

'Donner à la propriété ConnectionString les paramètres de connexion

ObjetConnection.ConnectionString = strConn

'Ouvrir la connexion

ObjetConnection.Open()

'Instancier un objet Commande

ObjetCommand = New OleDbCommand(strSql)

'Instancier un objet Adapter

ObjetDataAdapter = New OleDbDataAdapter(ObjetCommand)

'initialiser l'objet Command

ObjetCommand.Connection() = ObjetConnection

'initialiser l'objet OleCBComandBuilder (sinon pas d'update)

ObjetCB = New OleDbCommandBuilder(ObjetDataAdapter)

'Avec l'aide de la propriété Fill du DataAdapter charger le DataSet

ObjetDataAdapter.Fill(ObjetDataSet, "FICHEPATIENT")

'Créer une datatable à partir du dataset

ObjetDataTable = ObjetDataSet.Tables("FICHEPATIENT")

'Mettre dans le DataGrid une table  DataTable

DataGrid1.DataSource= ObjetDataTable

End Sub

 

Le bouton ButtonMiseA jour met à jour nom.mdb si on a fait une modification dans le DataGrid.

Private Sub ButtonMiseAJour_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonMiseAJour.Click

    'Mettre à jour

    ObjetDataAdapter.Update(ObjetDataSet, "FICHEPATIENT")

End Sub

 

 

 

 

 

Les lignes, colonnes, nom des champs, ascenseurs... sont crées automatiquement avec la table "FICHEPATIENT"!! Génial.

On peut cliquer dans une cellule, la modifier..rajouter ou enlever des lignes.

 

 

On peut aussi remplir le Datagrid avec:

 

DataGrid1.DataSource = ObjetDataSet

DataGrid1.DataMember = "FICHEPATIENT"

 

En mode Design, on peut modifier l'aspect du DataGrid dans la fenêtre de propriété ou en utilisant la mise en forme automatique (lien en bas de la fenêtre de propriétés.)en VB 2003!!

 

 

 

Comment ne pas écrire de code.

Il est possible de remplir un DataGrid avec les tables d'une base de données sans taper une ligne de code. On crée des objets Connections, Objet DataAdapter.. à la souris.

Voici un très bon didacticiel: http://www.profsr.com/vbnetfr/15440n9.htm

On peut aussi mettre les cellules d'une base de données dans des textBox:

http://www.profsr.com/vbnetfr/15440n10.htm

 

Mise à jour:

Comment la mise à jour fonctionne-t elle en interne?

On n'a pas à s'en occuper, dans c'est sympa à comprendre.

Exemple: votre application utilise un groupe de données contenant une seule table. L'application extrait deux lignes de la base de données. La table de données en mémoire ressemble à ceci :

(RowState)     CustomerID   Name             Status
(Unchanged)    A         Philippe      		Yes
(Unchanged)    B         Paul    		Yes

Votre application modifie le statusde 'Paul' en " No ". La valeur de la propriété DataRow.RowState de cette ligne passe de Unchanged à Modified. La valeur de la propriété RowState de la première ligne reste Unchanged. La table de données ressemble maintenant à ceci :

(RowState)     CustomerID   Name        Status
(Unchanged)    A         Philippe      	Yes
(Modified)     B         Paul  		No

Votre application appelle à présent la méthode Update pour transmettre le groupe de données à la base de données. Cette méthode examine chaque ligne. Pour la première ligne, la méthode ne transmet pas d'instruction SQL à la base de données car cette ligne n'a pas été modifiée depuis son extraction de la base de données.

Pour la seconde ligne, la méthode Update appelle automatiquement la commande de données appropriée et la transmet à la base de données. La syntaxe particulière de l'instruction SQL dépend du langage SQL pris en charge. Mais il est intéressant de considérer les caractéristiques suivantes de l'instruction SQL transmise :

 

C - Remplir un DataGrid avec une base de données sans une ligne de code (VB 2005):
 

On a une base de données Access (Nom.MDB), on veut afficher le contenu d'une des tables (la table 'FICHEPATIENT') dans une grille.

 

A - Il faut créer une source de données: la BD Nom.MDB.

B - Il faut créer automatiquement l'interface utilisateur et les liens entre cette interface et une table de la BD.

 

A - Création de la source de données:

Il faut créer une source de données:

Menu 'Données'=> 'Ajouter une nouvelle source de données'

 

Ici la source de données est une base de données:

On clique sur 'Base de données' puis bouton 'Suivant'.

Ensuite il faut faire le choix de la connexion (Cela correspond au choix d'une base de données existante).

Cliquer sur 'Nouvelle connexion'. Une nouvelle fenêtre nommée 'Ajouter une connexion' s'ouvre:

Indiquer le type de source de données (ici Microsoft Access (OLEDB), puis le nom de la base de données; enfin cliquer sur "Ok".

On retrouve le nom de la bd dans la zone connexion, cliquer sur "Suivant".

Ensuite VB vous demande s'il faut copier la BD dans le projet: Si oui la BD sera copiée dans le répertoire de travail quand vous installerez votre application. A vous de voir.

 

Ensuite VB vous propose d'enregistrer les chaînes de connexion (nom de la base...) dans le fichier de configuration afin qu'elles soient stockées et lues lors de l'utilisation ultérieure. (Automatiquement bien sur) A vous de voir.

 

Ensuite il faut choisir dans la base les objets  qui seront chargés dans le dataset.

C'est habituellement les Tables. Cocher 'Tables'.

Cliquer sur "Terminer".

 

B - Génération automatique de l'interface utilisateur:

Visual Studio dispose d'une fenêtre 'Sources de données' depuis laquelle vous pouvez faire glisser des éléments jusqu'à un formulaire pour créer automatiquement des contrôles liés aux données qui affichent des données.

Afficher les sources de données:

Menu 'Données' puis 'Afficher les sources de données'

 

Il apparaît à droite la fenêtre 'Sources de données'

Dérouler 'NomDataSet'(c'est le nom donné par VB à la connexion) et cliquer sur 'FICHEPATIENT' (c'est le nom d'une table de la BD).

Enfin faire un drag ans drop à partir de FICHEPATIENT et déposer le sur la form de gauche (qui est vide au départ)

Miracle: il apparaît automatiquement:

-un datagrid.

-une barre de navigation (tout est généré automatiquement: les bitmap des boutons dans les ressources  Setting...)

-Un DataSet, un TableAdapter

-Un composant BindingSource.(Il fait le lien entre l'interface et la source de données)

-Un composant BindingNavigator.(Il gère la barre de navigation)

 

On voit bien en dessous les 4 composants qui ont été ajoutés.

 

C'est terminé!!

 

Il suffit de lancer le programme, et on se voit la bd dans la grille, on se ballade dedans avec le curseur ou la barre de navigation, on peut ajouter, effacer une ligne, enregistrer les modifications:

 

 

 

 

Pour générer, non par une grid mais des zones de saisie textbox pour chaque champ, avant de faire le drag and drop, dérouler la liste contre la Table dans les sources de données et cliquer sur 'Détails'.

Il y a un exemple dans la section 5-10 qui donne ceci: