Utilisation d'ADO avec Delphi édition personnelle

Thierry AIM

Utilisation d'ADO avec Delphi édition personnelle.

La version téléchargeable de ce document est disponible ici : AdoDelphiPerso.zip version HTML.

- Titre : Utilisation d'ADO avec Delphi édition personnelle

- Auteur : Thierry AIM

- Parution : 17 avril 2004

- Mise à jour : 26 décembre 2019

- Licence : Les sources présentés sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2004 Cécile MUNO (Khany). Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.

Sommaire

- Introduction

- I. Connexion ODBC avec DSN

- I-A. Qu'est-ce que ODBC ?

- I-B. Qu'est-ce qu'un DSN ?

- I-C. Exemple de connexion ODBC à une base de données Access 2000

- I-C-1. Importer la bibliothèque ADO

- I-C-2. Création de l'unité DSN

- I-C-3. Unité principale du programme

- I-C-4. Procédure pour l'affichage des données dans la grille

- I-C-5. Bouton Créer et Remplir la grille

- II. Connexion ADO directe

- II-A. Exemple de connexion ADO à une base de données Access 2000

- II-A-1. Importer la bibliothèque ADO

- II-A-2. Déclaration des variables publiques

- II-A-3. Bouton Créer et Remplir la grille

- III. Source des exemples

Introduction

L'édition personnelle de Delphi6 ou Delphi7 n'inclut pas les composants d'accès aux données de type ADO. (ActiveX Data Objects.)
Je ne m'étendrai pas sur ce qu'est ADO, il existe d'autres tutoriels qui l'expliquent beaucoup mieux que je ne saurais le faire. En résumé, ce sont des composants universels d'accès aux données de tous types.

Ce cours ne constitue qu'un complément sur l'utilisation d'ADO, destiné aux utilisateurs de Delphi édition personnelle.

Nous supposerons donc que vous savez ce qu'est un recordset (jeu d'enregistrements), une chaîne de connexion, un objet Command. Dans le cas contraire, je vous invite auparavant à lire les autres cours de ce site sur l'accès aux bases de données avec ADO :

- Débuter avec ADO en Delphi(par Cyril Beaussier) ;

- Programmer ADO en Delphi(par J-M. Rabilloud).

Même si l'on ne dispose pas de ces composants, il est tout à fait possible de réaliser une connexion à une base de données moyennant quelques petites manipulations et un peu de code, et d'utiliser les Recordsets ADO.

Ce tutoriel vous permettra de vous connecter à une base de données Access (mais ceci reste un exemple) de deux façons différentes avec Delphi Perso (testé avec Delphi6 et Win2000) :

- par la technologie ODBC et DSN ;

- par une connexion ADO directe.

(Exemples testés avec Delphi6, Win2000 et ADO 2.5, 2.6 et 2.7)
(testés avec Delphi7 et WinME par Nono40)

I - Connexion ODBC avec DSN

I-A - Qu'est-ce que ODBC ?

ODBC : Open DataBase Connectivity.
ODBC est un format défini par Microsoft, fonctionnant quasi exclusivement sous Windows et permettant la communication entre des clients de bases de données et les différents fournisseurs de bases de données. (Sous réserve que ceux-ci possèdent un driver ODBC, ce qui est le cas de tous les principaux SGBD : Access, Oracle, SQL Server, Dbase…)

Gestionnaire ODBC pour Windows 95 et 98 :
Panneau de configuration : Sources de données ODBC (32 bits).

Gestionnaire ODBC pour Windows 2000, XP :
Panneau de configuration, puis Outils d'administration : Sources de données (ODBC).

Pour lier une base de données à notre application, il va falloir définir une source de données, appelée DSN.

I-B - Qu'est-ce qu'un DSN ?

DSN : Data Source Name (Nom de la Source de Données).

La source de données peut être de différents types : une base de données, un fichier Excel, un fichier texte…

Il nous faut donc définir une source de données pour permettre à ODBC de connecter notre programme (client) à la base de données (serveur ODBC).

L'exemple ci-après permet la création par le code du DSN nécessaire à la connexion d'une base de données Access.

Toutefois vous pouvez créer vous-même le DSN dans le gestionnaire ODBC de Windows (voir précédemment).

I-C - Exemple de connexion ODBC à une base de données Access 2000

I-C-1 - Importer la bibliothèque ADO

NOTE : cet exemple ne s'applique qu'aux systèmes d'exploitation Microsoft Windows.

Si ce n'est pas déjà fait, vous devez en premier lieu installer les composants d'accès aux données de Microsoft (petite entorse à Borland, nécessaire pour le fonctionnement du projet).

Si vous ne l'avez pas, téléchargez MDAC_TYP.EXE [5Mo] sur le site de Microsoft.

Ouvrez un nouveau projet Delphi.

Si l'installation de Mdac_typ s'est correctement effectuée, dans l'onglet « Projet » et « Importer une bibliothèque de type », vous devez trouver :

Procédez à l'importation en cliquant « Créer l'unité », l'unité ADODB_TBL est créée. Vous devez alors l'ajouter à votre projet, onglet « Projet » et « Ajouter au projet … ».

Définissez ensuite votre interface (un exemple est donné dans les codes source disponibles à la fin de cet article).

I-C-2 - Création de l'unité DSN

Dans l'application, créez une nouvelle unité nommée DSN. Nous allons définir dans cette unité, les fonctions qui nous permettent de créer, modifier et effacer un DSN. Pour cela nous allons créer une classe (class) nommée FctDSN, incluant des fonctions de classes (class function).

Définition d'une classe pour l'accès au DSN :

- Create pour la création ;

- Remove pour la suppression ;

- Modify pour la modification des propriétés.

unit DSN;

interface

type

FctDSN = class
class function Create (DSNDriver : AnsiString; DSNName: AnsiString;
DSNDescription: AnsiString; DSNbd: AnsiString) : Longint ;
class function Remove (DSNDriver : AnsiString; DSNName : AnsiString) : Longint ;
class function Modify (hwnd : Longint; DSNDriver : AnsiString; DSNName : AnsiString) : Longint;
end;

implementation

Déclaration de la fonction externe pour accéder à la configuration des DSN. Cette fonction appartient à la bibliothèque ODBCCP32.dll du gestionnaire ODBC.

function SQLConfigDataSource (hwndParent : hwnd; fRequest : Longint;
lpszDriver : AnsiString; lpszAttributes : AnsiString)  : Longint;
stdcall;  external 'ODBCCP32.DLL' name  'SQLConfigDataSource' ;

Définition de la fonction pour la création d'un DSN.
Cette fonction nécessite en paramètres :

- DSNDriver : nom du driver utilisé (dans notre cas, il s'agira du driver Access) ;

- DSNName : nom du DSN (c'est le nom que l'on va retrouver dans la liste du gestionnaire ODBC) ;

- DSNDescription : une brève description de notre DSN (non nécessaire au fonctionnement) ;

- DSNdb : le nom (et éventuellement le chemin complet) de la base de données à laquelle on veut se connecter.

class function FctDSN.Create(DSNDriver : AnsiString; DSNName: AnsiString;
DSNDescription: AnsiString; DSNbd: AnsiString) :Longint;
var
intRet : longint ;
DSNAttributes: AnsiString  ;
begin
DSNAttributes := 'DSN=' + DSNName + #0 ;
DSNAttributes := DSNAttributes + 'DESCRIPTION=' + DSNDescription + #0 ;
DSNAttributes := DSNAttributes + 'DBQ=' + DSNbd + #0 ;
intRet :=SQLConfigDataSource(vbAPINull, ODBC_ADD_DSN, DSNDriver, DSNAttributes);
If intRet = 0 Then
Showmessage( 'Échec de création du DSN') ;
Result := intRet;
end;

Définition de la fonction pour la suppression d'un DSN.
Cette fonction nécessite en paramètres :

- DSNDriver : nom du driver utilisé (dans notre cas, il s'agira du driver Access) ;

- DSNName : nom du DSN (c'est le nom que l'on va retrouver dans la liste du gestionnaire ODBC).

class function FctDSN.Remove(DSNDriver : AnsiString; DSNName : AnsiString):Longint;
var
intRet : longint ;
DSNAttributes: AnsiString  ;
begin
DSNAttributes := 'DSN=' + DSNName + #0  ;
intRet := SQLConfigDataSource(vbAPINull, ODBC_REMOVE_DSN, DSNDriver, DSNAttributes) ;
If intRet = 0 Then Showmessage ('Échec de suppression du DSN') ;
Result := intRet;
End;

Définition de la fonction pour la modification d'un DSN.
Cette fonction nécessite en paramètres :

- hwnd : handle de la fenêtre appelante ;

- DSNDriver : nom du driver utilisé (dans notre cas, il s'agira du driver Access) ;

- DSNName : nom du DSN (c'est le nom que l'on va retrouver dans la liste du gestionnaire ODBC).

class function fctDSN.Modify(hwnd : Longint; DSNDriver : AnsiString; DSNName : AnsiString): Longint;
var
intRet : longint ;
DSNAttributes: AnsiString  ;
begin
DSNAttributes := 'DSN=' + DSNName + #0  ;
intRet :=SQLConfigDataSource(hwnd, ODBC_CONFIG_DSN, DSNDriver, DSNAttributes) ;
Result := intRet;
end;

end.

I-C-3 - Unité principale du programme

Dans notre exemple, nous définirons des constantes pour transmettre les paramètres nécessaires aux fonctions DSN. Ces valeurs peuvent bien sûr être paramétrées.

DSNDriver = 'Microsoft Access Driver (*.mdb)';

Nom du driver ODBC à utiliser.
Si vous ne le connaissez pas, vérifiez dans le gestionnaire ODBC si votre driver existe et, si oui, trouvez son nom. Pour notre exemple nous utiliserons le driver pour Access.

DSNName = 'MS Access Delphi6';

Nom du DSN (qui apparaitra dans le gestionnaire ODBC)
C'est le nom sous lequel sera reconnu votre DSN pour votre application.

DSNDescription = 'Demo DSN ADO';

Description succincte du DSN.
Une chaîne de caractères qui identifie plus précisément votre DSN. Cette valeur n'est qu'une indication et n'a pas de fonctionnalité.

SQL = 'SELECT * FROM Outils';

Requête de sélection.
Une requête SQL classique, compatible avec le moteur Microsoft Jet.

DSNbd = 'bd1.mdb';

Nom de la base de données (si celle-ci ne se trouve pas dans le répertoire de l'application, indiquez le chemin complet).

I-C-4 - Procédure pour l'affichage des données dans la grille

Elle reçoit en paramètre le recordset.
Elle extrait le nom des champs du recordset et les affiche sur la 1re ligne de la grille
Elle affiche toutes les valeurs dans la grille :

procedure TForm1.Display(RecordSet: _RecordSet);
var
Y, i: Integer;
begin
Y := 1;
StringGrid1.ColCount:=RecordSet.Fields.Count;
RecordSet.MoveFirst;
for i := 0 to RecordSet.Fields.Count-1 do
StringGrid1.Cells[i, 0]:=  RecordSet.Fields[i].Name ;
repeat
StringGrid1.RowCount := Y+1;
for i := 0 to RecordSet.Fields.Count-1 do
if not VarIsNull(RecordSet.Fields[i].Value) then
StringGrid1.Cells[i, Y] :=  RecordSet.Fields[i].Value;
RecordSet.Move(1, EmptyParam);
Inc(Y);
until RecordSet.EOF;
end;

Cette procédure est incluse dans le code source, vous pouvez bien sûr la personnaliser à loisir, en fonction de vos inspirations.

I-C-5 - Bouton Créer et Remplir la grille

Nous allons détailler cette fonction, qui est bien sûr, la plus intéressante :

procedure TForm1.CmdRemplirClick(Sender: TObject);
...
Begin

Créer un DSN pour la liaison ODBC. Nous utilisons la fonction de création que nous avons définie dans l'unité DSN

try
FctDSN.Create (DSNDriver, DSNName, DSNDescription, DSNbd);

En cas d'erreur, vous êtes renvoyé dans la partie except de l'instruction : vérifiez votre paramétrage dans les constantes ou dans vos variables.

Créer un objet Recordset vide :

OleCheck(CoCreateInstance(CLASS_RecordSet, nil, CLSCTX_ALL, IID__RecordSet, RS));
DSNstrg := 'DSN=' + DSNName;

Remplir le recordset (Fonction Open d'ADO).

RS.CursorLocation := adUseServer; {localisation curseur coté serveur}
RS.Open(SQL, DSNstrg, adOpenForwardOnly, adLockReadOnly, adCmdUnspecified);

Display(RS); {Afficher les valeurs dans la grille}
except
On E:Exception Do ShowMessage('Erreur d''ouverture de la base.'+ #13+E.Message);
end;
end;

Les autres fonctions sont construites sur le même principe.

II - Connexion ADO directe

Dans le cas d'une base Access (utilisant les fonctionnalités Jet), une connexion directe peut être plus intéressante, car moins lourde en programmation.

II-A - Exemple de connexion ADO à une base de données Access 2000

II-A-1 - Importer la bibliothèque ADO

N'ayant pas besoin de créer un DSN, pour l'accès direct avec ADO, toute la différence réside dans la création de la connexion à la base de données. Je ne détaillerai pas tous les subtilités et paramètres des fonctionnalités d'ADO, un de mes confrères l'a déjà fait, beaucoup mieux que je ne saurais le faire.

Je vous engage une nouvelle fois à lire les autres tutoriels de ce site, afin de bien comprendre les mécanismes de ADO. Je rappelle que cet article ne constitue qu'un complément pour utiliser ADO avec une version personnelle de Delphi.

Comme dans l'exemple précédent, vous devez procéder à l'installation de Mdac_typ de Microsoft, importer la bibliothèque ADO et l'ajouter à votre projet.

Vous n'avez pas besoin de l'unité DSN, décrite dans le chapitre précédent.

Dans l'unité Main, la procédure d'affichage Display est rigoureusement identique à celle décrite ci-dessus.

II-A-2 - Déclaration des variables publiques

var
RS: _RecordSet;       {notre Recordset}
Cnx : _Connection;    {La connexion à définir}
Cmd: _Command;        {un objet command}

const
SQL = 'SELECT * FROM Outils';

Requête de sélection, une requête SQL classique, compatible avec le moteur Microsoft Jet.

DSNbd = 'bd1.mdb';

Nom de la base de données (si celle-ci ne se trouve pas dans le répertoire de l'application, indiquer le chemin complet).

II-A-3 - Bouton Créer et Remplir la grille

procedure TForm1.CmdRemplirClick(Sender: TObject);
begin

Créer la connexion ADO pour Access 2000 (Microsoft jet 4.0) :

try
Cnx := CoConnection.Create;

Vous devez définir le provider (l'équivalent du driver à utiliser dans la version avec DSN), ainsi que tous les paramètres nécessaires à la connexion.

Cnx.Open( 'Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin; Data Source=bd1.mdb;', 'admin', '', -1 );

Créer un Recordset ADO.

RS := CoRecordSet.Create;

Créer un objet command ADO pour permettre de remplir le recordset

Cmd := CoCommand.Create;
Cmd.CommandText := SQL;
Cmd.Set_ActiveConnection(Cnx);

Remplir le recordset

RS.CursorLocation := adUseServer; {localisation curseur coté serveur}
RS.Open(Cmd, Emptyparam, adOpenKeyset, adLockOptimistic, adCmdText );

Display(RS); {Afficher les valeurs dans la grille}
except
On E:Exception Do ShowMessage('Erreur d''ouverture de la base.'+ #13+E.Message);
end;
end;

Ne pas oublier de fermer les objets ouverts avant de quitter l'application pour éviter tous déboires collatéraux :

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
RS.Close;
Cnx.Close;
end;

Voilà, nous sommes arrivés au terme de notre projet. Téléchargez les sources complètes (à la fin de cet article) Configurez les constantes dans l'unité Main et votre grille pour l'affichage en fonction de votre BD et testez.

III - Source des exemples

Les codes source des exemples sont disponibles sur les liens ci-après. Ils comprennent toutes les unités et une petite base de données avec une table correspondant à l'exemple.

- D6_ODBC.ZIP exemple avec ODBC

- D6_ADO.ZIP exemple avec ADO