FAQ DelphiConsultez toutes les FAQ
Nombre d'auteurs : 124, nombre de questions : 934, dernière mise à jour : 23 octobre 2024 Ajouter une question
Cette FAQ a été réalisée à partir des questions fréquemment posées sur les forums Delphi et Delphi et bases de données de www.developpez.com et de l'expérience personnelle des auteurs.
Nous tenons à souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose soient correctes. Les auteurs font le maximum, mais l'erreur est humaine. Cette FAQ ne prétend pas non plus être complète. Si vous souhaitez y apporter des corrections ou la compléter, contactez un responsable (lien au bas de cette page).
Nous espérons que cette FAQ saura répondre à vos attentes. Nous vous en souhaitons une bonne lecture.
L'équipe Delphi de Developpez.com.
- Comment construire une chaîne de connexion ADO à l'exécution ?
- Comment résoudre l'erreur "CoInitialize n'a pas été appelé" ?
- Comment afficher la boîte de configuration d'ADO à l'exécution ?
- Comment exporter/importer une table contenue dans une base de données ADO au format XML ?
- Comment enregistrer un _RecordSet ADO au format CSV ?
Pour se connecter à des stockages de données ADO, nous devons spécifier des informations que nous fournissons à la propriété connectionString d'un composant ADO.
Lors de la conception, nous utilisons en général le Wizard qui construit automatiquement cette chaîne de connexion.
La fonction suivante permet de construire cette chaîne au runtime, uniquement pour les fournisseurs suivants : MS-SQL Server, Access, ODBC et ORACLE.
En cas d'erreur sur le nom du fournisseur, la fonction revoit la chaîne 'NONE'.
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | uses SysUtils, Strutils; // AnsiIndexStr type TBuilder=record ChaineConnexion : ShortString; numeroTemplate : Byte; end; Const NombreProvider=4; NombreTemplate=2; // Chaîne de connexion à construire Template : Array[1..NombreTemplate] of String = ('Provider=%S;Persist Security Info=False;Password=%S;User ID=%S;Initial Catalog=%S', 'Provider=%S;Persist Security Info=False;Password=%S;User ID=%S;Data Source=%S' ); // Nom des providers ADO Provider : Array[0..NombreProvider-1] of String= ('SQLSERVER', 'ACCESS', 'ODBC', 'ORACLE' ); // Informations utilisées dans la construction de la chaîne de connexion, cf. Template // Elles sont en correspondance avec l'indice du nom du provider. tabBuilder : Array [0..NombreProvider-1] Of TBuilder= ((ChaineConnexion :'SQLOLEDB.1'; numeroTemplate :1), // SQLSERVER (ChaineConnexion :'Microsoft.Jet.OLEDB.4.0'; numeroTemplate :2), // ACCESS (ChaineConnexion :'MSDASQL.1';numeroTemplate :2), // ODBC (ChaineConnexion :'MSDAORA.1';numeroTemplate :2) // ORACLE ); function buildConnexionString(Fournisseur,Base,User,PassWord: string):string; var Monprovider :Integer; begin Monprovider:=AnsiIndexStr(Fournisseur, Provider); If Monprovider >= 0 then with tabBuilder[Monprovider] do Result := Format(Template[numeroTemplate],[ChaineConnexion,Password,User,Base]) else raise Exception.Create(Format('Le fournisseur %s est inconnu.',[Fournisseur])); end; |
Code delphi : | Sélectionner tout |
1 2 | ADOConnection1.ConnectionString := buildConnexionString('ODBC','MaBaseNameAliasODBC','UserName','MotDePasse'); |
L'utilisation d'ADO revient à utiliser un ensemble de composants COM.
Il est nécessaire pour les applications d'initialiser la bibliothèque COM avant d'utiliser ces composants.
Si l'initialisation n'a pas eu lieu, dès la première utilisation d'un objet ADO, une exception sera levée avec pour message "CoInitialize n'a pas été appelé".
Une application initialise COM grâce à
Code delphi : | Sélectionner tout |
Application.Initialize;
Il existe néanmoins des cas où l'initialisation n'est pas automatique, comme entre autre une application Service NT, une DLL, une application WebSnap.
Afin d'initialiser COM, on utilisera alors
Code delphi : | Sélectionner tout |
CoInitialize(nil);
Code delphi : | Sélectionner tout |
CoUnInitialize;
Dans le cas d'un Service NT par exemple, on placera l'instruction CoInitialize dans l'événement ServiceStart, et l'instruction CoUnInitialize dans l'événement ServiceStop. L'utilisation des objets ADO se fera entre ces deux appels.
Dans le cas d'une application console, l'appel de CoInitialize doit être contenu dans le corps de l'application console, et non dans une procédure ou une fonction au risque de déclencher une violation d'accès.
Pour afficher la boite de configuration d'ADO et ainsi pouvoir construire la chaine de connexion à une base de données comme vous le feriez en conception :
- Il faut rajouter dans les clauses uses, l'unité AdoConEd
- Utiliser la commande EditConnectionString
Ci-dessous, un petit exemple :
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | procedure ConfigurerAdo; begin AdoConnection .Connected := False;//Ou utiliser l'équivalent AdoConnection.Close; EditConnectionString(AdoConnection); try AdoConnection .Connected := True;//Ou utiliser l'équivalent AdoConnection.Open; Except on E:Exception do Showmessage(E.Message); end; end; |
Sinon, une autre méthode, plus complète existe. Elle a pour avantage de récupérer la chaîne de configuration.
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | Uses ...,OleDB, ComObj, ActiveX,... ... implementation ... function ADOConnectionString(ParentHandle:THandle;InitialString:WideString;out NewString: string): Boolean; var DataInit: IDataInitialize; DBPrompt: IDBPromptInitialize; DataSource: IUnknown; InitStr: PWideChar; begin Result := False; DataInit := CreateComObject(CLSID_DataLinks) as IDataInitialize; if InitialString <> '' then DataInit.GetDataSource(nil,CLSCTX_INPROC_SERVER,PWideChar(InitialString),IUnknown, DataSource); DBPrompt := CreateComObject(CLSID_DataLinks) as IDBPromptInitialize; if Succeeded(DBPrompt.PromptDataSource(nil, ParentHandle, DBPROMPTOPTIONS_PROPERTYSHEET, 0, nil, nil, IUnknown, DataSource)) then begin InitStr := nil; DataInit.GetInitializationString(DataSource, True, InitStr); NewString := InitStr; Result := True; end; end; procedure TForm1.Button1Click(Sender: TObject); var initst, nexstr : string; begin initst := 'Provider=SQLOLEDB.1;Persist Security Info=False;User ID=MonLogin;Initial Catalog=MaBdd;Data Source=MonServeur'; if ADOConnectionString(form1.Handle,initst, nexstr) then MessageDlg(nexstr, mtWarning, [mbOK], 0); end; |
Code delphi : | Sélectionner tout |
Function PromptDataSource(ParentHandle: THandle; InitialString: WideString): WideString;
Code delphi : | Sélectionner tout |
PromptDataSource(0, ADOConnection.ConnectionString);
Il peut parfois s'avérer très utile d'exporter une table ADO dans un format plus "universel" que le format natif. Voici deux méthodes qui vous permettront d'importer et d'exporter une table "ADO" au format *.XML.
Vous noterez la concision du code qui se passe de commentaire ainsi que sa vélocité.
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | Unit Import_Export_Ado_Xml; interface uses Classes, ADOInt; function TableVersXML(const Atable: _Recordset): String; function TableDepuisXML(const XML: String): _Recordset; implementation uses ComObj; function TableVersXML(const Atable: _Recordset): String; var VT : Variant; AStream : TStringStream; begin Result := ''; if Atable = nil then Exit; AStream :=TStringStream.Create(''); try VT := CreateOleObject('ADODB.Recordset'); VT := ATable; VT.Save(TStreamAdapter.Create(Astream) as IUnknown, adPersistXML); AStream.Position:= 0; Result := AStream.DataString; finally AStream.Free; end; end; function TableDepuisXML(const XML: String): _Recordset; var VT : Variant; AStream : TStringStream; begin Result := nil; if XML = '' then Exit; try AStream := TStringStream.Create(XML); AStream.Position:= 0; VT := CreateOleObject('ADODB.Recordset'); VT.Open(TStreamAdapter.Create(AStream) as IUnknown); Result := IUnknown(VT) as _Recordset; finally AStream.Free; end; end; end. |
Nous supposerons que vous avez créé une fiche principale nommée "Form1" munie d'un TMemo nommé "Memo1", 2 TButton nommés "Button1", "Button2" ainsi que d'un TADOquery nommé "Adoquery1". Adoquery1 est connecté à votre base de données via sa propriété ConnectionString ; sa requête, pour "MaTable" étant : "SELECT MaTable.* FROM MaTable"
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // Uses ... Import_Export_Ado_Xml; // procedure TForm1.Button1Click(Sender: TObject); begin Memo1.Lines.Text := TableVersXML(ADOQuery1.Recordset); //Exportation end; procedure TForm1.Button2Click(Sender: TObject); begin ADOQuery1.Recordset := TableDepuisXML(Memo1.Lines.Text); //Importation end; |
- Fonctionne avec TADOTable, TADOQuery, TADODataSet
- Dans le cas de traitement par lot, veillez à sauvegarder toutes vos tables sous des noms différents sous peine de lever une exception pour cause de structure de table incompatible.
- Fonctionne avec pratiquement tout ce qui est connectable via les composants ADO
- Fonctionne avec toutes les versions de Access depuis la version 97 jusqu'à 2007
- Travaille avec tout type de champs. Cependant, dans le cas d'une table volumineuse, les champs Blob rendront vite votre fichier "balourd".
- Triez, filtrez vos données et utilisez ces fonctions en lieu et place d'un TBatchMove pour ADO
ADO propose, sur les classes dérivées de TCustomADODataSet, la propriété Recordset de type interface _Recordset.
Cette interface donne accès à l'ensemble des enregistrements et propose la méthode GetString permettant de récupérer ses données dans un WideString.
Voici comment récupérer, au format CVS, un _RecordSet ADO dans une chaîne de caractères de type WideString :
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | type ESaveDataSetNoData = Class(Exception); EDictionnaireVide=Class(Exception); const COLUMNDELIMITER = ';'; MsgNoData='Aucune donnée.'; {*------------------------------------------------------------------------------ Renvoie le contenu d'un RecordSet ADO au format CSV. Attention à la taille des données renvoyées. Le Header ( nom des champs sur la première ligne) n'est pas géré. @param ARecordSet RecordSet ADO @param StringFormat Format d'export : adClipString @param ColumnDelimiter Séparateur de champ @param RowDelimiter Séparateur de ligne @param NullExpr Expression pour les valeur de champ à NULL @return Une chaîne contenant l'intégralité d'un RecordSet ADO au format CSV ------------------------------------------------------------------------------*} Function SaveDataSetCSV(ARecordSet : _Recordset; StringFormat: StringFormatEnum; const ColumnDelimiter: WideString; const RowDelimiter: WideString; const NullExpr: WideString): WideString; begin Result := ''; //Récupère, au format CSV, l'intégralité d'un dataset dans une string With ARecordSet do begin if RecordCount = 0 then Raise ESaveDataSetNoData.Create(MsgNoData); Result := GetString(StringFormat, RecordCount, ColumnDelimiter, RowDelimiter, NullExpr); end; end; |
Ensuite il est aisé de l'enregistrer dans un fichier :
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | {*------------------------------------------------------------------------------ Ecrit, au format CSV, le contenu d'un RecordSet ADO dans un fichier. Attention à la taille des données renvoyées. S'il existe déjà un fichier portant ce nom, il est ouvert en mode écriture. @param AADOARecordSet RecordSet ADO @param AFilename Nom du fichier CSV ------------------------------------------------------------------------------*} Procedure SaveDataSetTo(AADOARecordSet : _Recordset; AFilename :TFileName); Overload; var AllData: string; Liste : TStringList; begin // Repositionne le curseur pour enregistrer l'intégralité des données. AADOARecordSet.First; Liste := TStringList.Create; try Liste.Text := SaveDataSetCSV(AADOARecordSet, adClipString, COLUMNDELIMITER, sLineBreak, ''); Liste.SaveToFile(AFilename); finally Liste.Free; end; end; |
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | {*------------------------------------------------------------------------------ Ecrit, au format CSV, le contenu d'un RecordSet ADO dans une TStrings existante. Attention à la taille des données renvoyées. La liste est remise à zéro avant l'opération. @param AADOARecordSet RecordSet ADO @param AList Liste de chaîne hébergeant les lignes du RecordSet ------------------------------------------------------------------------------*} Procedure SaveDataSetTo(AADOARecordSet : _Recordset; AList: TStringList);Overload; begin // obligatoire sinon la récupération des données ne se fera // qu'à la position courante du curseur dans la base de données: MoveFirst; AList.Text := SaveDataSetCSV(AADOARecordSet, adClipString, COLUMNDELIMITER, sLineBreak, ''); end; |
Code delphi : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | var Dictionnaire : TStringList begin ...//Creation de la requête try SaveDataSetTo(Query.Recordset,Dictionnaire); except on ESaveDataSetNoData do Raise EDictionnaireVide.Create('Le dictionnaire de recherche est vide'); end; ... end; |
- l'unité System pour accéder à la constante sLineBreak
- l'unité ADOint pour accéder à la constante adCliping et au type StringFormatEnum.
Note : Cette approche ne permet pas de traitement sur les données à exporter.
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.