MS Access/fr: what changed
Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.
| Old | New | Line | |
|---|---|---|---|
| 1 | - | ||
| 1 | + | --- | |
| 2 | + | [[Portal:Databases|**Portail de la base de données**]] | |
| 3 | + | Références: · [[Databases/fr|Information générale]] · [[Database libraries/fr|Bibliothèques]] · [[Database field type/fr|Types de champ]] · [[Data Controls tab/fr|Contrôles]] · [[Lazarus DB Faq/fr|FAQ]] · [[SqlDBHowto/fr|Comment faire en SQL ?]] · [[Working With TSQLQuery/fr|Travailler avec TSQLQuery]] · [[How to write in-memory database applications in Lazarus/FPC/fr|Applications de base de données en mémoire]] · Tutoriels/articles pratiques : · [[Lazarus Database Overview/fr|Vue d'ensemble]] · [[SQLdb Tutorial0/fr|0 - Configuration de la base de données]] · [[SQLdb Tutorial1/fr|1 - Commençons]] · [[SQLdb Tutorial2/fr|2 - Edition]] · [[SQLdb Tutorial3/fr|3 - Requêtes]] · [[SQLdb Tutorial4/fr|4 - Modules de données]] · [[SQLdb Programming Reference/fr|Référence de programmation SQLdb]] · Bases de données · [[Advantage Database Server/fr|Advantage]] \- [[MySQLDatabases/fr|MySQL]] \- [[mssqlconn/fr|MSSQL]] \- [[postgres/fr|Postgres]] \- [[Firebird/fr|Interbase]] \- [[Firebird/fr|Firebird]] \- [[Oracle/fr|Oracle]] \- [[ODBCConn/fr|ODBC]] \- [[TParadox/fr|Paradox]] \- [[SQLite/fr|SQLite]] \- [[Lazarus Tdbf Tutorial/fr|dBASE]] \- MS Access \- [[Zeos tutorial/fr|Zeos]] | |
| 4 | + | ||
| 5 | + | Cette page explique comment utiliser une base de données **Microsoft Access** en utilisant [[ODBCConn/fr|ODBC]] et le SQLDB intégré de FPC. | |
| 2 | 6 | ||
| 3 | 7 | # Spécificités MS Access | |
| 4 | 8 | ||
| 5 | 9 | ## UsePrimaryKeyAsKey | |
| 6 | 10 | ||
| 7 | - | ||
| 11 | + | Dans les propriétés **TSQLQuery** , vous pouvez avoir besoin de définir UsePrimaryKeyAsKey à False. | |
| 8 | 12 | ||
| 9 | 13 | ## Obtenir le numéro auto de clé primaire tout juste inséré | |
| 10 | 14 | ||
| 11 | - | ||
| 12 | - | ||
| 13 | - | ||
| 15 | + | Après insertion des données, Access 2000 et supérieur permet de récupérer la clé primaire auto-incrémentée en utuilisant cette requête: | |
| 16 | + | ``` | |
| 14 | 17 | SELECT @@IDENTITY | |
| 15 | 18 | ``` | |
| 16 | 19 | ||
| 17 | 20 | ## Pilotes ODBC | |
| 18 | 21 | ||
| 19 | 22 | ### Windows | |
| 20 | 23 | ||
| 21 | - | ||
| 24 | + | Il y a deux pilotes [[ODBCConn/fr|ODBC]] différent pour Microsoft Access : | |
| 22 | 25 | ||
| 23 | - | ||
| 24 | - | ||
| 26 | + | * L'ancien pilote qui peut seulement utiliser des fichiers au format.mdb, le nom du pilote est "Microsoft Access Driver (*.mdb)". Inclus dans plusieurs versions de Windows (de 2000 jusqu'à Vista (inclus?)) ; téléchargeable pour les anciennes versions de Windows comme partie des composants MDAC ou des composants Jet. En 32 bit seulement. | |
| 27 | + | * Le nouveau pilote qui peut accéder aux fichiers .mdb et .accdb à la fois, le nom du pilote est "Microsoft Access Driver (*.mdb, *.accdb)". Téléchargeable comme le "Microsoft Access Database Engine 2010 Redistributable" ; disponible en 32 et 64 bit. | |
| 25 | 28 | ||
| 26 | - | ||
| 29 | + | Comme d'habitude, avec un Lazarus/FPC 32 bit, utilisez des pilotes ODBC 32 bit. Avec un Lazarus/FPC 64 bit, utilisez des pilotes ODBC 64 bit. | |
| 27 | 30 | ||
| 28 | 31 | ### Unix/Linux | |
| 29 | 32 | ||
| 30 | - | ||
| 33 | + | Le [projet mdbtools](<http://sourceforge.net/projects/mdbtools/>) offre un support limité pour MS Access. Il inclut un pilote ODBC qui pourrait être utilisé. Essayez d'installer des paquets comme mdbtools mdbtools-dev mdbtools-gmdb. | |
| 31 | 34 | ||
| 32 | - | ||
| 35 | + | Au moins sur Debian, Le nom du pilote ODBC est "MDBTools". | |
| 33 | 36 | ||
| 34 | 37 | # Instructions de DSN basé sur un fichier | |
| 35 | 38 | ||
| 36 | - | ||
| 39 | + | Un fichier DSN est simplement un fichier contenant les réglage de connexion. La raison de ce fichier DSN est que si vous voulez distribuer une connexion à une source de données à plusieurs utilisateurs sur différents systèmes sans avoir à la configurer sur chaque système. Par exemple, je peux créer une un fichier DSN vers une base de données de rapports sur mon bureau. Je peux alors envoyer le fichier vers mes utilisateurs, ils peuvent enregistrer le fichier DSN dans leur disque dur et faire pointer leur applications de rapports vers le fichier DSN. | |
| 37 | 40 | ||
| 38 | - | ||
| 41 | + | Si vous voulez utiliser un DSN basé sur fichier avec le pilote SQLdb ODBC : | |
| 39 | 42 | ||
| 40 | 43 | ## Configurer le fichier DSN | |
| 41 | 44 | ||
| 42 | - | ||
| 43 | - | ||
| 44 | - | ||
| 45 | + | * Ouvrez le [Source de donnés ODBC] dans le panneau de contrôle de l'outil d'administration. | |
| 46 | + | * Allez sur l'onglet [Fichier DSN], cliquez sur Ajouter puis sélectionner <pilote Microsoft Access>. | |
| 47 | + | * Ensuite, naviguez vers le chemin courant de votre projet Lazarus por enregistrer le fichier .dsn, parce que ce fichier DSN contiendra la configuration demandée pour accéder à votre fichier de base de données Access (.mdb) qui sera utilisé dans votre TODBCConnection [FileDSN]. | |
| 45 | 48 | ||
| 46 | 49 | ### Contenus de fichier DSN | |
| 47 | 50 | ||
| 48 | - | ||
| 49 | - | ||
| 50 | - | ||
| 51 | + | A titre de référence, un fichier DSN qui fait référence à un fichier de base de données MS Access **peut** ressembler à quelque chose **comme** ceci : | |
| 52 | + | ``` | |
| 51 | 53 | [ODBC] | |
| 52 | - | ||
| 53 | - | ||
| 54 | - | ||
| 55 | - | ||
| 56 | - | ||
| 57 | - | ||
| 58 | - | ||
| 59 | - | ||
| 60 | - | ||
| 61 | - | ||
| 62 | - | ||
| 63 | - | ||
| 54 | + | DRIVER=Microsoft Access Driver (*.mdb) | |
| 55 | + | UID=admin | |
| 56 | + | UserCommitSync=Yes | |
| 57 | + | Threads=3 | |
| 58 | + | SafeTransactions=0 | |
| 59 | + | PageTimeout=5 | |
| 60 | + | MaxScanRows=8 | |
| 61 | + | MaxBufferSize=2048 | |
| 62 | + | FIL=MS Access | |
| 63 | + | DriverId=25 | |
| 64 | + | DefaultDir= | |
| 65 | + | DBQ=YOUR_msaccess.mdb | |
| 64 | 66 | ``` | |
| 65 | 67 | ||
| 66 | 68 | ## Configurez votre projet pour utiliser un DSN basé sur fichier | |
| 67 | 69 | ||
| 68 | - | ||
| 70 | + | L'utilisation de grille et d'autres composants liés aux données est identique à celle des autres connecteurs SQLDB, donc nous n'en parlerons pas ici. | |
| 69 | 71 | ||
| 70 | - | ||
| 72 | + | Comme vous utilisez une connexion ODBC, vous devriez avoir un objet **TODBCConnection**. | |
| 71 | 73 | ||
| 72 | - | ||
| 74 | + | Propriétés TOBDCConnection : | |
| 73 | 75 | ||
| 74 | - | ||
| 75 | - | ||
| 76 | + | * FileDSN : le chemin d'accès complet (avec le nom de fichier) vers le fichier DSN enregistré précédemment, p.ex. c:\mylazarus\project1\myFile.dsn. | |
| 77 | + | * Username : admin (ou n'importe quel utilisateur dont vous avez besoin si vous exploitez la sécurité d'Access), _ce paramètre n'est pas nécessaire si aucune sécurité d'Access n'est utilisée'_. | |
| 76 | 78 | ||
| 77 | - | ||
| 79 | + | Ne pas définir d'autres propriétés. | |
| 78 | 80 | ||
| 79 | 81 | # DSN Système/Utilisateur | |
| 80 | 82 | ||
| 81 | - | ||
| 83 | + | Comme expliqué dans l'article sur [[ODBCConn/fr|ODBC]], vous pouvez aussi utiliser des DSN systèem ou utilisateur, où les réglages de connexion sont définis dans le panneau de contrôle au lieu d'être stocké dans un fichier. | |
| 82 | 84 | ||
| 83 | - | ||
| 85 | + | Le TODBCConnection devrait avoir comme DatabaseName : <name_of_your_DSN>. | |
| 84 | 86 | ||
| 85 | 87 | # DSN sans connexion | |
| 86 | 88 | ||
| 87 | - | ||
| 88 | - | ||
| 89 | - | ||
| 90 | - | ||
| 91 | - | ||
| 92 | - | ||
| 93 | - | ||
| 89 | + | Comme expliqué dans l'article sur [[ODBCConn/fr|ODBC]], vous pouvez aussi créer une connexion sans DSN vers votre base de données Access, vous pouvez spécifier tous les paramètres dans le code, quelque chose comme cela : | |
| 94 | 90 | ``` | |
| 95 | - | ||
| 96 | - | ||
| 91 | + | //Notice we're using the new MS Access driver, we could probably use the old one too: | |
| 92 | + | conn.Driver:='Microsoft Access Driver (*.mdb, *.accdb)'; | |
| 93 | + | conn.Params.Add('DBQ=c:\somedirectory\test.mdb'); | |
| 94 | + | ... add whatever parameters you want/need... | |
| 95 | + | ``` | |
| 97 | 96 | ||
| 98 | - | ||
| 97 | + | Voici un exemple de comment interroger une table dans un fichier .mdb en utilisant TODBCConnection, TSQLTransaction and TSQLQuery (le fichier .mdb existe dans le même dossier que le programme exécutable) : | |
| 98 | + | ``` | |
| 99 | 99 | procedure TForm1.Button1Click(Sender: TObject); | |
| 100 | - | ||
| 101 | - | ||
| 102 | - | ||
| 103 | - | ||
| 104 | - | ||
| 105 | - | ||
| 106 | - | ||
| 107 | - | ||
| 108 | - | ||
| 109 | - | ||
| 110 | - | ||
| 111 | - | ||
| 112 | - | ||
| 113 | - | ||
| 114 | - | ||
| 115 | - | ||
| 116 | - | ||
| 117 | - | ||
| 118 | - | ||
| 119 | - | ||
| 100 | + | begin | |
| 101 | + | //connection | |
| 102 | + | ODBCConnection1.Driver := 'Microsoft Access Driver (*.mdb, *.accdb)'; | |
| 103 | + | ODBCConnection1.Params.Add('DBQ=.\test.mdb'); // or specify full path to mdb file | |
| 104 | + | ODBCConnection1.Params.Add('Locale Identifier=1031'); | |
| 105 | + | ODBCConnection1.Params.Add('ExtendedAnsiSQL=1'); | |
| 106 | + | ODBCConnection1.Params.Add('CHARSET=ansi'); | |
| 107 | + | ODBCConnection1.Connected := True; | |
| 108 | + | ODBCConnection1.KeepConnection := True; | |
| 109 | + | ||
| 110 | + | //transaction | |
| 111 | + | SQLTransaction1.DataBase := ODBCConnection1; | |
| 112 | + | SQLTransaction1.Action := caCommit; | |
| 113 | + | SQLTransaction1.Active := True; | |
| 114 | + | ||
| 115 | + | SQLQuery1.DataBase := ODBCConnection1; | |
| 116 | + | SQLQuery1.UsePrimaryKeyAsKey := False; | |
| 117 | + | SQLQuery1.SQL.Text := 'select * from Customers'; | |
| 118 | + | SQLQuery1.Open; | |
| 119 | + | end; | |
| 120 | 120 | ``` | |
| 121 | 121 | ||
| 122 | 122 | # Exemple de code | |
| 123 | 123 | ||
| 124 | 124 | ## Lazarus: Contrôles liés aux données sur les fiches | |
| 125 | 125 | ||
| 126 | - | ||
| 127 | - | ||
| 128 | - | ||
| 126 | + | Exemple de code source fonctionnel :<http://www.mediafire.com/file/ne1jx3zpnwzefq3/msaccesstest2.zip>. | |
| 127 | + | ``` | |
| 129 | 128 | unit Unit1; | |
| 130 | - | ||
| 131 | - | ||
| 132 | - | ||
| 133 | - | ||
| 134 | - | ||
| 135 | - | ||
| 136 | - | ||
| 137 | - | ||
| 138 | - | ||
| 139 | - | ||
| 140 | - | ||
| 141 | - | ||
| 142 | - | ||
| 143 | - | ||
| 144 | - | ||
| 145 | - | ||
| 146 | - | ||
| 147 | - | ||
| 148 | - | ||
| 149 | - | ||
| 150 | - | ||
| 151 | - | ||
| 152 | - | ||
| 153 | - | ||
| 154 | - | ||
| 155 | - | ||
| 156 | - | ||
| 157 | - | ||
| 158 | - | ||
| 159 | - | ||
| 160 | - | ||
| 161 | - | ||
| 162 | - | ||
| 163 | - | ||
| 164 | - | ||
| 165 | - | ||
| 166 | - | ||
| 167 | - | ||
| 168 | - | ||
| 169 | - | ||
| 170 | - | ||
| 171 | - | ||
| 172 | - | ||
| 173 | - | ||
| 174 | - | ||
| 175 | - | ||
| 176 | - | ||
| 177 | - | ||
| 178 | - | ||
| 179 | - | ||
| 180 | - | ||
| 181 | - | ||
| 182 | - | ||
| 183 | - | ||
| 184 | - | ||
| 185 | - | ||
| 186 | - | ||
| 187 | - | ||
| 188 | - | ||
| 189 | - | ||
| 190 | - | ||
| 191 | - | ||
| 192 | - | ||
| 193 | - | ||
| 194 | - | ||
| 195 | - | ||
| 196 | - | ||
| 197 | - | ||
| 198 | - | ||
| 199 | - | ||
| 200 | - | ||
| 201 | - | ||
| 202 | - | ||
| 203 | - | ||
| 204 | - | ||
| 205 | - | ||
| 206 | - | ||
| 207 | - | ||
| 208 | - | ||
| 209 | - | ||
| 210 | - | ||
| 211 | - | ||
| 212 | - | ||
| 213 | - | ||
| 214 | - | ||
| 215 | - | ||
| 216 | - | ||
| 217 | - | ||
| 218 | - | ||
| 219 | - | ||
| 220 | - | ||
| 221 | - | ||
| 222 | - | ||
| 223 | - | ||
| 224 | - | ||
| 129 | + | ||
| 130 | + | {$mode objfpc}{$H+} | |
| 131 | + | ||
| 132 | + | interface | |
| 133 | + | ||
| 134 | + | uses | |
| 135 | + | Classes, SysUtils, odbcconn, sqldb, db, FileUtil, LResources, Forms, Controls, | |
| 136 | + | Graphics, Dialogs, DBGrids, DbCtrls, StdCtrls, Printers, PrintersDlgs; | |
| 137 | + | ||
| 138 | + | type | |
| 139 | + | ||
| 140 | + | { TForm1 } | |
| 141 | + | ||
| 142 | + | TForm1 = class(TForm) | |
| 143 | + | Button1: TButton; | |
| 144 | + | Button2: TButton; | |
| 145 | + | Button3: TButton; | |
| 146 | + | Button4: TButton; | |
| 147 | + | Datasource1: TDatasource; | |
| 148 | + | DBEdit1: TDBEdit; | |
| 149 | + | DBEdit2: TDBEdit; | |
| 150 | + | DBGrid1: TDBGrid; | |
| 151 | + | ODBCConnection1: TODBCConnection; | |
| 152 | + | PrintDialog1: TPrintDialog; | |
| 153 | + | SQLQuery1: TSQLQuery; | |
| 154 | + | SQLTransaction1: TSQLTransaction; | |
| 155 | + | procedure Button1Click(Sender: TObject); | |
| 156 | + | procedure Button2Click(Sender: TObject); | |
| 157 | + | procedure Button3Click(Sender: TObject); | |
| 158 | + | procedure Button4Click(Sender: TObject); | |
| 159 | + | procedure FormCloseQuery(Sender: TObject; var CanClose: boolean); | |
| 160 | + | procedure FormShow(Sender: TObject); | |
| 161 | + | private | |
| 162 | + | { private declarations } | |
| 163 | + | procedure PrintDbGrid(dbGrid:TdbGrid); | |
| 164 | + | public | |
| 165 | + | { public declarations } | |
| 166 | + | end; | |
| 167 | + | ||
| 168 | + | var | |
| 169 | + | Form1: TForm1; | |
| 170 | + | ||
| 171 | + | implementation | |
| 172 | + | ||
| 173 | + | { TForm1 } | |
| 174 | + | ||
| 175 | + | procedure TForm1.FormShow(Sender: TObject); | |
| 225 | 176 | begin | |
| 226 | - | ||
| 227 | - | ||
| 228 | - | ||
| 229 | - | ||
| 230 | - | ||
| 231 | - | ||
| 177 | + | //connection | |
| 178 | + | ODBCConnection1.FileDSN := ExtractFilePath(Application.ExeName) + 'file.dsn'; | |
| 179 | + | ODBCConnection1.Connected := True; | |
| 180 | + | ODBCConnection1.KeepConnection := True; | |
| 181 | + | ||
| 182 | + | //transaction | |
| 183 | + | SQLTransaction1.DataBase := ODBCConnection1; | |
| 184 | + | SQLTransaction1.Action := caCommit; | |
| 185 | + | SQLTransaction1.Active := True; //not applied to ms access(false) | |
| 186 | + | ||
| 187 | + | SQLQuery1.DataBase := ODBCConnection1; | |
| 188 | + | SQLQuery1.UsePrimaryKeyAsKey := False; | |
| 189 | + | ||
| 190 | + | SQLQuery1.SQL.Text := 'select * from table1'; | |
| 191 | + | ||
| 192 | + | // :id is the parameter for the field name id | |
| 193 | + | SQLQuery1.deleteSQL.Text := 'delete from table1 where id=:id'; | |
| 194 | + | //:name is the parameter for the field name name | |
| 195 | + | SQLQuery1.updateSQL.Text := 'update table1 set name=:name where id=:id'; | |
| 196 | + | ||
| 197 | + | DataSource1.DataSet := SQLQuery1; | |
| 198 | + | DBGrid1.DataSource := DataSource1; | |
| 199 | + | DBGrid1.ReadOnly := true; | |
| 200 | + | ||
| 201 | + | DBEdit1.DataField := 'id'; | |
| 202 | + | DBEdit1.DataSource := DataSource1; | |
| 203 | + | DBEdit2.DataField := 'name'; | |
| 204 | + | DBEdit2.DataSource := DataSource1; | |
| 205 | + | ||
| 206 | + | SQLQuery1.Open; | |
| 207 | + | end; | |
| 208 | + | ||
| 209 | + | function MulDiv(nNumber, nNumerator, nDenominator: Integer): Integer; | |
| 210 | + | begin | |
| 211 | + | Result:=Round(int64(nNumber)*int64(nNumerator)/nDenominator); | |
| 212 | + | end; | |
| 213 | + | ||
| 214 | + | procedure TForm1.PrintDbGrid(dbGrid:TdbGrid); | |
| 215 | + | const | |
| 216 | + | LeftMargin = 0.05; | |
| 217 | + | TopMargin = 0.05; | |
| 218 | + | BottomMargin = 0.05; | |
| 219 | + | var | |
| 220 | + | i: integer; | |
| 221 | + | x,y: integer; | |
| 222 | + | begin | |
| 223 | + | if PrintDialog1.Execute then | |
| 224 | + | begin | |
| 225 | + | Printer.BeginDoc; | |
| 226 | + | Printer.Canvas.Font.Size := 12; | |
| 227 | + | ||
| 228 | + | y := Round(TopMargin*Printer.PageHeight); | |
| 229 | + | dbGrid.DataSource.DataSet.First; | |
| 230 | + | while not dbGrid.DataSource.DataSet.Eof do | |
| 231 | + | begin | |
| 232 | + | x := Round(LeftMargin*Printer.PageWidth); | |
| 233 | + | for i := 0 to dbGrid.DataSource.DataSet.FieldCount-1 do | |
| 234 | + | begin | |
| 235 | + | printer.Canvas.TextOut(x,y,dbGrid.DataSource.DataSet.Fields[i].AsString); | |
| 236 | + | x := x + MulDiv(dbGrid.Columns[i].Width,72, dbGrid.Width); | |
| 237 | + | end; | |
| 238 | + | dbGrid.DataSource.DataSet.Next; | |
| 239 | + | y := y + printer.Canvas.TextHeight('A'); | |
| 240 | + | if y > (1-TopMargin-BottomMargin)* Printer.PageHeight then | |
| 241 | + | begin | |
| 242 | + | y := Round(TopMargin*Printer.PageHeight); | |
| 243 | + | Printer.NewPage; | |
| 244 | + | end; | |
| 245 | + | end; | |
| 246 | + | Printer.EndDoc; | |
| 247 | + | end | |
| 248 | + | else | |
| 249 | + | Form1.caption := 'NO PRINTER INSTALLED'; | |
| 250 | + | end; | |
| 251 | + | ||
| 252 | + | procedure TForm1.Button1Click(Sender: TObject); | |
| 253 | + | begin | |
| 254 | + | PrintDbGrid(DBGrid1); | |
| 255 | + | end; | |
| 256 | + | ||
| 257 | + | procedure TForm1.Button2Click(Sender: TObject); | |
| 258 | + | begin | |
| 259 | + | if button2.Caption = 'new' then | |
| 260 | + | begin | |
| 261 | + | SQLQuery1.Insert; | |
| 262 | + | button2.Caption := 'save'; | |
| 263 | + | exit | |
| 264 | + | end | |
| 265 | + | else | |
| 232 | 266 | begin | |
| 233 | - | ||
| 234 | - | ||
| 267 | + | if (dbedit1.Text = '') or (dbedit2.Text = '') | |
| 268 | + | then | |
| 235 | 269 | begin | |
| 236 | - | ||
| 237 | - | ||
| 238 | - | ||
| 239 | - | ||
| 240 | - | ||
| 241 | - | ||
| 270 | + | SQLQuery1.Cancel; | |
| 271 | + | end | |
| 272 | + | else | |
| 242 | 273 | begin | |
| 243 | - | ||
| 244 | - | ||
| 274 | + | if SQLQuery1.State = dsInsert then | |
| 275 | + | begin | |
| 276 | + | SQLQuery1.Post; | |
| 277 | + | SQLQuery1.ApplyUpdates; | |
| 278 | + | Form1.caption := 'ADDED'; | |
| 279 | + | end; | |
| 245 | 280 | end; | |
| 246 | 281 | end; | |
| 247 | - | ||
| 248 | - | ||
| 249 | - | ||
| 250 | - | ||
| 251 | - | ||
| 252 | - | ||
| 253 | - | ||
| 254 | - | ||
| 255 | - | ||
| 256 | - | ||
| 257 | - | ||
| 258 | - | ||
| 259 | - | ||
| 260 | - | ||
| 261 | - | ||
| 262 | - | ||
| 263 | - | ||
| 264 | - | ||
| 265 | - | ||
| 266 | - | ||
| 267 | - | ||
| 268 | - | ||
| 269 | - | ||
| 282 | + | button2.Caption := 'new'; | |
| 283 | + | end; | |
| 284 | + | ||
| 285 | + | procedure TForm1.Button3Click(Sender: TObject); | |
| 270 | 286 | begin | |
| 271 | - | ||
| 272 | - | ||
| 273 | - | ||
| 287 | + | if SQLQuery1.RecordCount>0 then | |
| 288 | + | begin | |
| 289 | + | SQLQuery1.Delete; | |
| 290 | + | SQLQuery1.ApplyUpdates; | |
| 291 | + | ||
| 292 | + | //REMOVED or ADD this 2 lines if there is a problem in your SQLdB | |
| 293 | + | //THESE 2 lines apparently work around a bug in SQLdB for MS_Access dataBase' | |
| 294 | + | //**** missing reference to bugtracker item; please create a bugtracker item | |
| 295 | + | //SQLQuery1.Close; | |
| 296 | + | //SQLQuery1.Open; | |
| 297 | + | ||
| 298 | + | ||
| 299 | + | Form1.caption := 'DELETED'; | |
| 300 | + | end; | |
| 301 | + | end; | |
| 302 | + | ||
| 303 | + | procedure TForm1.Button4Click(Sender: TObject); | |
| 274 | 304 | begin | |
| 275 | - | ||
| 276 | - | ||
| 277 | - | ||
| 278 | - | ||
| 279 | - | ||
| 280 | - | ||
| 305 | + | if SQLQuery1.RecordCount>0 then | |
| 306 | + | begin | |
| 307 | + | SQLQuery1.Edit; | |
| 308 | + | SQLQuery1.Post; | |
| 309 | + | Sqlquery1.ApplyUpdates; | |
| 310 | + | Form1.caption := 'UPDATED'; | |
| 311 | + | end; | |
| 281 | 312 | end; | |
| 282 | - | ||
| 283 | - | ||
| 284 | - | ||
| 285 | - | ||
| 286 | - | ||
| 287 | - | ||
| 288 | - | ||
| 289 | - | ||
| 290 | - | ||
| 291 | - | ||
| 292 | - | ||
| 293 | - | ||
| 294 | - | ||
| 295 | - | ||
| 296 | - | ||
| 297 | - | ||
| 298 | - | ||
| 299 | - | ||
| 300 | - | ||
| 301 | - | ||
| 302 | - | ||
| 303 | - | ||
| 304 | - | ||
| 305 | - | ||
| 306 | - | ||
| 307 | - | ||
| 308 | - | ||
| 309 | - | ||
| 310 | - | ||
| 311 | - | ||
| 312 | - | ||
| 313 | - | ||
| 314 | - | ||
| 315 | - | ||
| 316 | - | ||
| 317 | - | ||
| 318 | - | ||
| 319 | - | ||
| 320 | - | ||
| 321 | - | ||
| 322 | - | ||
| 323 | - | ||
| 313 | + | ||
| 314 | + | procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: boolean); | |
| 315 | + | begin | |
| 316 | + | SQLQuery1.Close; | |
| 317 | + | CanClose := True; | |
| 318 | + | end; | |
| 319 | + | ||
| 320 | + | initialization | |
| 321 | + | {$I unit1.lrs} | |
| 322 | + | ||
| 323 | + | end. | |
| 324 | 324 | ``` | |
| 325 | 325 | ||
| 326 | 326 | ## Créer une base de données par programmation | |
| 327 | 327 | ||
| 328 | - | ||
| 329 | - | ||
| 330 | - | ||
| 328 | + | En utilisant un pilote ODBC, vous pouvez créer des bases de données Microsoft Access par programme. (Note: la gestion des erreurs n'a pas été testée ; veuillez mettre à jour la page si vous l'avez testé) | |
| 331 | 329 | ||
| 332 | - | ||
| 330 | + | Programme d'exemple : | |
| 331 | + | ``` | |
| 333 | 332 | program CreateAccessDb; | |
| 334 | - | ||
| 335 | - | ||
| 336 | - | ||
| 337 | - | ||
| 338 | - | ||
| 339 | - | ||
| 340 | - | ||
| 341 | - | ||
| 342 | - | ||
| 343 | - | ||
| 344 | - | ||
| 345 | - | ||
| 346 | - | ||
| 347 | - | ||
| 348 | - | ||
| 349 | - | ||
| 350 | - | ||
| 351 | - | ||
| 352 | - | ||
| 353 | - | ||
| 354 | - | ||
| 355 | - | ||
| 356 | - | ||
| 357 | - | ||
| 358 | - | ||
| 359 | - | ||
| 360 | - | ||
| 361 | - | ||
| 362 | - | ||
| 363 | - | ||
| 364 | - | ||
| 365 | - | ||
| 366 | - | ||
| 367 | - | ||
| 368 | - | ||
| 369 | - | ||
| 370 | - | ||
| 371 | - | ||
| 372 | - | ||
| 373 | - | ||
| 374 | - | ||
| 375 | - | ||
| 376 | - | ||
| 377 | - | ||
| 378 | - | ||
| 379 | - | ||
| 380 | - | ||
| 381 | - | ||
| 382 | - | ||
| 383 | - | ||
| 384 | - | ||
| 385 | - | ||
| 386 | - | ||
| 387 | - | ||
| 388 | - | ||
| 389 | - | ||
| 390 | - | ||
| 391 | - | ||
| 392 | - | ||
| 393 | - | ||
| 333 | + | ||
| 334 | + | {$mode objfpc}{$H+} | |
| 335 | + | ||
| 336 | + | uses | |
| 337 | + | {$IFDEF UNIX}{$IFDEF UseCThreads} | |
| 338 | + | cthreads, | |
| 339 | + | {$ENDIF}{$ENDIF} | |
| 340 | + | Classes, sysutils, | |
| 341 | + | LCLType; | |
| 342 | + | ||
| 343 | + | Const | |
| 344 | + | ODBC_ADD_DSN=1; | |
| 345 | + | ODBC_CONFIG_DSN=2; | |
| 346 | + | ODBC_REMOVE_DSN=3; | |
| 347 | + | ODBC_ADD_SYS_DSN=4; | |
| 348 | + | ODBC_CONFIG_SYS_DSN=5; | |
| 349 | + | ODBC_REMOVE_SYS_DSN=6; | |
| 350 | + | ODBC_REMOVE_DEFAULT_DSN=7; | |
| 351 | + | function SQLConfigDataSource(hwndParent: Integer; fRequest: Integer; | |
| 352 | + | lpszDriverString: PChar; lpszAttributes: PChar): Integer; stdcall; external 'odbccp32.dll'; | |
| 353 | + | function SQLInstallerError(iError: integer; pfErrorCode: PInteger; lpszErrorMsg: string; cbErrorMsgMax: integer; pcbErrorMsg: PInteger): integer; stdcall; external 'odbccp32.dll'; | |
| 354 | + | ||
| 355 | + | function CreateAccessDatabase(DatabaseFile: string): boolean; | |
| 356 | + | var | |
| 357 | + | DBPChar: PChar; | |
| 358 | + | Driver: PChar; | |
| 359 | + | ErrorCode, ResizeErrorMessage: integer; | |
| 360 | + | ErrorMessage: PChar; | |
| 361 | + | retCode: integer; | |
| 362 | + | begin | |
| 363 | + | driver := 'Microsoft Access Driver (*.mdb, *.accdb)'; | |
| 364 | + | { With this driver, | |
| 365 | + | CREATE_DB/CREATE_DBV12 will create an .accdb format database; | |
| 366 | + | CREATE_DBV4 will create an mdb | |
| 367 | + | http://stackoverflow.com/questions/9205633/how-do-i-specify-the-odbc-access-driver-format-when-creating-the-database | |
| 368 | + | } | |
| 369 | + | DBPChar:=PChar('CREATE_DBV4="'+DatabaseFile+'"'); | |
| 370 | + | retCode := SQLConfigDataSource(Hwnd(nil), ODBC_ADD_DSN, Driver, DBPChar); | |
| 371 | + | if retCode<>0 then | |
| 372 | + | begin | |
| 373 | + | //try alternate driver | |
| 374 | + | Driver := 'Microsoft Access Driver (*.mdb)'; | |
| 375 | + | DBPChar:=PChar('CREATE_DB="'+DatabaseFile+'"'); | |
| 376 | + | retCode := SQLConfigDataSource(Hwnd(nil), ODBC_ADD_DSN, Driver, DBPChar); | |
| 377 | + | end; | |
| 378 | + | if retCode=0 then | |
| 379 | + | begin | |
| 380 | + | result:=true; | |
| 381 | + | end | |
| 382 | + | else | |
| 383 | + | begin | |
| 384 | + | result:=false; | |
| 385 | + | ErrorCode:=0; | |
| 386 | + | ResizeErrorMessage:=0; | |
| 387 | + | // todo: verify how the DLL is called - use pointers?; has not been tested. | |
| 388 | + | GetMem(ErrorMessage,512); | |
| 389 | + | try | |
| 390 | + | SQLInstallerError(1, @ErrorCode, ErrorMessage, SizeOf(ErrorMessage), @ResizeErrorMessage); | |
| 391 | + | finally | |
| 392 | + | FreeMem(ErrorMessage); | |
| 393 | + | end; | |
| 394 | + | raise Exception.CreateFmt('Error creating Access database: %s', [ErrorMessage]); | |
| 395 | + | end; | |
| 394 | 396 | end; | |
| 395 | - | ||
| 396 | - | ||
| 397 | - | ||
| 398 | - | ||
| 399 | - | ||
| 400 | - | ||
| 401 | - | ||
| 402 | - | ||
| 397 | + | ||
| 398 | + | begin | |
| 399 | + | writeln('Result: '); | |
| 400 | + | write(CreateAccessDatabase('d:\cop\t\bla.mdb')); | |
| 401 | + | end. | |
| 403 | 402 | ``` | |
| 404 | 403 | ||
| 405 | 404 | ## Problème de jeu de caractères | |
| 406 | 405 | ||
| 407 | - | ||
| 408 | - | ||
| 409 | - | ||
| 406 | + | Les anciennes bases de données Access sont encodées en utilisant le jeu de caractères ANSI (je en sais pas au sujet des nouvelles, elles utilisant sans doute des chaînes large). Ainsi, les caractères non imprimables ne sont pas affichés correctement dans un DBGrid ou autre contrôle sensible aux données. Cela peut corrigé en attachant des gestionnaire aux événements OnGetText et OnSetText du DataSet après overture : | |
| 407 | + | ``` | |
| 410 | 408 | uses | |
| 411 | - | ||
| 412 | - | ||
| 413 | - | ||
| 414 | - | ||
| 415 | - | ||
| 416 | - | ||
| 417 | - | ||
| 418 | - | ||
| 419 | - | ||
| 409 | + | lconvencoding; | |
| 410 | + | ||
| 411 | + | procedure TForm1.SQLQuery1AfterOpen(DataSet: TDataSet); | |
| 412 | + | var | |
| 413 | + | i: Integer; | |
| 420 | 414 | begin | |
| 421 | - | ||
| 422 | - | ||
| 415 | + | for i:=0 to DataSet.Fields.Count-1 do | |
| 416 | + | begin | |
| 417 | + | if DataSet.Fields[i].DataType=ftString then | |
| 418 | + | begin | |
| 419 | + | DataSet.Fields[i].OnGetText := @ConvertFromDB; | |
| 420 | + | DataSet.Fields[i].OnSetText := @ConvertToDB; | |
| 421 | + | end; | |
| 422 | + | end; | |
| 423 | 423 | end; | |
| 424 | - | ||
| 425 | - | ||
| 426 | - | ||
| 427 | - | ||
| 428 | - | ||
| 429 | - | ||
| 430 | - | ||
| 431 | - | ||
| 432 | - | ||
| 433 | - | ||
| 434 | - | ||
| 435 | - | ||
| 436 | - | ||
| 437 | - | ||
| 424 | + | ||
| 425 | + | procedure TForm1.ConvertFromDB(Sender: TField; var aText: string; DisplayText: Boolean); | |
| 426 | + | begin | |
| 427 | + | if not Sender.IsNull then | |
| 428 | + | aText := WinCPToUTF8(Sender.AsString); // if encoded in windows default code page | |
| 429 | + | end; | |
| 430 | + | ||
| 431 | + | procedure TForm1.ConvertToDB(Sender: TField; const aText: string); | |
| 432 | + | begin | |
| 433 | + | if aText <> '' then | |
| 434 | + | Sender.Value := UTF8ToWinCP(aText); | |
| 435 | + | end; | |
| 438 | 436 | ``` | |
| 439 | 437 | ||
| 440 | 438 | # Exemple de base de données | |
| 441 | 439 | ||
| 442 | - | ||
| 440 | + | Microsoft Access est fourni avec l'exemple de base de données Northwind. | |
| 443 | 441 | ||
| 444 | - | ||
| 442 | + | Si vous avez seulement installé le moteur d'exécution, vous pouvez utiliser cette base de données alternative depuis le projet Mondial comme base de test : [[1]](<http://databases.about.com/od/sampleaccessdatabases/a/Microsoft-Access-Sample-Database-Countries-Cities-And-Provinces.htm>) | |
| 445 | 443 | ||
| 446 | 444 | # Voir aussi | |
| 447 | 445 | ||
| 448 | - | ||
| 446 | + | * [[ODBCConn/fr|ODBCConn]] Le connecteur ODBC que cet article utilise. | |
| 449 | 447 | ||
| 450 | 448 | --- | |
| 451 | - | ||
| 449 | + | *From the Free Pascal wiki, page "MS Access/fr", as the Internet Archive kept it on 2025-03-15, last changed on 2020-02-21. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* |
