Sign in Join
Wiki copytemporary

MS Access/ja: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: MS Access/ja

OldNewLine
1+---
2+[[Portal:Databases/ja|**データベースのポータル**]]
3+参照: · [[Databases/ja|Databases 概要]] · [[Database libraries/ja|ライブラリ]] · [[Database field type/ja|フィールドの型]] · [[Data Controls tab/ja|コントロール]] · [[Lazarus DB Faq/ja|FAQ]] · [[SqlDBHowto/ja]] · [[Working With TSQLQuery/ja|TSQLQuery の利用]] · [[How to write in-memory database applications in Lazarus/FPC/ja|メモリ上で動作するデータベースの作り方]] · チュートリアル/練習となる記事: · [[Lazarus Database Overview/ja|概要]] · [[SQLdb Tutorial0/ja|0 - データベースのセットアップ]] · [[SQLdb Tutorial1/ja|1 - 開始]] · [[SQLdb Tutorial2/ja|2 - 編集]] · [[SQLdb Tutorial3/ja|3 - クエリ]] · [[SQLdb Tutorial4/ja|4 - データモジュール]] · [[SQLdb Programming Reference/ja]] · 各種データベース · [[Advantage Database Server/ja|Advantage]] \- [[MySQLDatabases/ja|MySQL]] \- [[mssqlconn/ja|MSSQL]] \- [[postgres/ja|Postgres]] \- [[Firebird/ja|Interbase]] \- [[Firebird/ja|Firebird]] \- [[Oracle/ja|Oracle]] \- [[ODBCConn/ja|ODBC]] \- [[TParadox/ja|Paradox]] \- [[SQLite/ja|SQLite]] \- [[Lazarus Tdbf Tutorial/ja|dBASE]] \- MS Access \- [[Zeos tutorial/ja|Zeos]]
4+
5+このページは[[ODBCConn|ODBC]]とFPCのビルトイン、SQLDBを用いてどのようにして **Microsoft Access** データベースを用いるか解説する。
6+
7+
8+
9+## MS Access 固有事項
10+
11+### プライマリキーをキーとして用いる
12+
13+**TSQLQuery** プロパティでは、Set UsePrimaryKeyAsKey: Falseと設定しなければならないだろう
14+
15+
16+
17+### オートナンバープライマリキーを挿入させる
18+
19+データを挿入した後で、Access 2000とより新しいバージョンはこのクエリを用いて、適時挿入のオートナンバープライマリキーの挿入をサポートしている:
20+```
21+SELECT @@IDENTITY
22+```
23+
24+### ODBC ドライバ
25+
26+#### Windows
27+
28+2つの異なる [[ODBCConn|ODBC]] ドライバがMicrosoft Accessにある:
29+
30+ * ドライバ名が"Microsoft Access Driver (*.mdb)"の.mdbフォーマットのみに使われる古いドライバ。Windows 2000以降(でVista?)の多くのWindowsに含まれる。MDACコンポーネントあるいはJetコンポーネントの一部としてダウンロードできる古いWindowsバージョンのためのもの。32 bitのみ。
31+ * ドライバの名前が"Microsoft Access Driver (*.mdb, *.accdb)"の.mdbと.accdbの双方にアクセスできる新しいドライバ。 "Microsoft Access Database Engine 2010 Redistributable"としてダウンロードできる 32 と 64 bit.普段通り、32 bit Lazarus/FPCを用いるときには32 bitODBCドライバを用いること。64 bit Lazarus/FPCを用いるときには64 bit ODBCドライバを用いること。
32+
33+#### Unix/Linux
34+
35+The [mdbtools project] はMS Accesssに限定的なサポートを提供している。おそらく使うことのできるODBCドライバが含まれている。Mdbtools、mdbtools-dev、mdbtools-gmdbパッケージをインストールしてみること。
36+
37+少なくともDebianではODBCドライバ名は"MDBTools"である。
38+
39+### SQLクエリにおけるワイルドカード
40+
41+Microsoft Accessは他のデータベースシステムと比較して異なったワイルドカード文法を持っている。以下の情報は _"Intermediate Microsoft Jet SQL for Access 2000"_ [MSDN]で取得したもので、これはもはやここにはない(第3者のサイトにコピーがある)。機能するようにテストされている。
42+
43+
44+
45+ワイルドカード文字 | 摘要
46+---|---
47+% (パーセント) | どの文字のどの数ともマッチし、パターン文字列でどこでも使える。
48+_ (アンダースコア) | どの1文字にもマッチし、パターン文字列でどこでも使える。
49+[] (角括弧) | 括弧の中に含まれたリストの1文字にマッチし、パターン文字列でどこでも使える。
50+! (エクスクラメーション) | 角括弧に含まれたリストにないどの1文字にマッチする。
51+\- (ハイフン) | 角括弧に含まれた範囲のどの文字列にもマッチする。
52+
53+以下に注意
54+
55+ * Accessの`WHERE` 条件は丸カッコに入れなければならない。
56+ * 文字列はシングルクォートで囲う。
57+ * 日付は`#yyyy-mm-dd#` のようにあらわす(年-月-日の順で'#'で囲う)。
58+ * フィールドとテーブルの名前で通常禁止された文字は角括弧で囲うこと。
59+
60+例: `SELECT * FROM [Birthday Table] WHERE ([Birth date] >= #2000-01-01#)`
61+
62+## ファイルベースのDSN 要領
63+
64+ファイルDSNは単に接続設定がファイルに書かれた単純なものである。ファイルDSNを持つ理由は、もしもしデータソース接続を多くの異なるシステムのユーザーに配布したいときに、ファイルDSNは各々のシステムでDSNの設定をしなくてもするためである。 例えば、デスクトップにファイルDSNをデータベースの所在を報告するために作ったとする。そうするとユーザーにそのファイルを送ることができる。ユーザーはそのファイルDSNをハードディスクに保存しファイルDSNで示された場所を特定することができる。
65+
66+ファイルベースのDSNをSQLDBドライバで使いたいときは:
67+
68+### ファイルDSNの設定
69+
70+ * コントロールパネルのWindowsツール、データソース [Data sources (ODBC)]に行き、
71+ * [File DSN] タブメニューを選び、 追加をクリック、そして、Microsoft Access Driver(*.mdb, *.accdb)を選ぶ
72+ * 次に今のLazarusプロジェクトバスを指し、DSNファイルに保存する。というのも、そのdnsファイルはAccessデータベースファイル(.mdb)にアクセスするのに必要な設定を含んでいるからだ。
73+ * 次へをクリックして終わる(これで新しい.dsnファイルができた)それはTODBCConnection [FileDSN]で用いることができる。
74+
75+#### ファイル DSNの内部
76+
77+例えば、MS Accessデータベースを参照するファイルDSNはこんな**感じ** に**なるかも** しれない:
78+```
79+[ODBC]
80+ DRIVER=Microsoft Access Driver (*.mdb)
81+ UID=admin
82+ UserCommitSync=Yes
83+ Threads=3
84+ SafeTransactions=0
85+ PageTimeout=5
86+ MaxScanRows=8
87+ MaxBufferSize=2048
88+ FIL=MS Access
89+ DriverId=25
90+ DefaultDir=
91+ DBQ=YOUR_msaccess.mdb
92+```
93+
94+### ファイルベースのDSNを設定する
95+
96+グリッドと他の埋め込みコントロールの使用法は他のSQLDBコネクタと同じであるので、ここでは割愛する。
97+
98+ODBC接続を使うときには、**TODBCConnection** オブジェクトが必要である。
99+
100+TOBDCConnection プロパティ:
101+
102+ファイルDSN: 先に保存したDSNファイルに対するpath+ファイル名、例えばc:\mylazarus\project1\myFile.dsn Username: admin(もしくはAccessセキュリティを用いているなら何らかのユーザー名)、このパラメータはMS Accessセキュリティを用いていないならば必要ない。 他のプロパティには手を触れないこと。
103+
104+## システム/ユーザー DSN
105+
106+[[ODBCConn/ja|ODBC]]で説明した通り、システム、またはユーザーDSNを用いることもでき、その場合、接続設定は保存されたファイルではなく、ODBCコントロールパネルで定義される。 TODBCConnectionは
107+
108+DatabaseName: <name_of_your_DSN>
109+
110+を持たなければならない。
111+
112+## DSNレス接続
113+
114+[[ODBCConn/ja|ODBC]]で説明したとおり、DSNレスの接続はAccessデータベースに対するすべての接続パラメータを特定する記述することにより可能となる。それはこのようなものになるだろう:
115+```
116+//注意: ここでは新しいMS Accessドライバを用いている。おそらく古いものも使えるだろう:
117+ conn.Driver:='Microsoft Access Driver (*.mdb, *.accdb)';
118+ conn.Params.Add('DBQ=c:\somedirectory\test.mdb');
119+ ... 望む/必要な記述を加える...
120+```
121+
122+これはTODBCConnectionを用いたAccess mdbのテーブルに対するクエリの仕方の例である、TSQLTransaction と TSQLQuery; mdbファイルはプロジェクトのバイナリと同じフォルダにある。
123+```
124+procedure TForm1.Button1Click(Sender: TObject);
125+ begin
126+ //接続
127+ ODBCConnection1.Driver := 'Microsoft Access Driver (*.mdb, *.accdb)';
128+ ODBCConnection1.Params.Add('DBQ='+Application.Location+'test.mdb'); // 必要なmdbファイルの場所
129+ ODBCConnection1.Params.Add('Locale Identifier=1031');
130+ ODBCConnection1.Params.Add('ExtendedAnsiSQL=1');
131+ ODBCConnection1.Params.Add('CHARSET=ansi');
132+ ODBCConnection1.Connected := True;
133+ ODBCConnection1.KeepConnection := True;
134+
135+ //トランザクション
136+ SQLTransaction1.DataBase := ODBCConnection1;
137+ SQLTransaction1.Action := caCommit;
138+ SQLTransaction1.Active := True;
139+
140+ SQLQuery1.DataBase := ODBCConnection1;
141+ SQLQuery1.UsePrimaryKeyAsKey := False;
142+ SQLQuery1.SQL.Text := 'select * from Customers';
143+ SQLQuery1.Open;
144+ end;
145+```
146+
147+## コード例
148+
149+### Lazarus: フォームにデータを埋め込む
150+
151+実際に動くコード例:(Updated2_with_add_delete_update) www.mediafire.com/file/ne1jx3zpnwzefq3/msaccesstest2.zip _[このリンクは - 2020 11月時点では切れている]_
152+```
153+unit Unit1;
154+
155+ {$mode objfpc}{$H+}
156+
157+ interface
158+
159+ uses
160+ Classes, SysUtils, odbcconn, sqldb, db, FileUtil, LResources, Forms, Controls,
161+ Graphics, Dialogs, DBGrids, DbCtrls, StdCtrls, Printers, PrintersDlgs;
162+
163+ type
164+
165+ { TForm1 }
166+
167+ TForm1 = class(TForm)
168+ Button1: TButton;
169+ Button2: TButton;
170+ Button3: TButton;
171+ Button4: TButton;
172+ Datasource1: TDatasource;
173+ DBEdit1: TDBEdit;
174+ DBEdit2: TDBEdit;
175+ DBGrid1: TDBGrid;
176+ ODBCConnection1: TODBCConnection;
177+ PrintDialog1: TPrintDialog;
178+ SQLQuery1: TSQLQuery;
179+ SQLTransaction1: TSQLTransaction;
180+ procedure Button1Click(Sender: TObject);
181+ procedure Button2Click(Sender: TObject);
182+ procedure Button3Click(Sender: TObject);
183+ procedure Button4Click(Sender: TObject);
184+ procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
185+ procedure FormShow(Sender: TObject);
186+ private
187+ { private declarations }
188+ procedure PrintDbGrid(dbGrid:TdbGrid);
189+ public
190+ { public declarations }
191+ end;
192+
193+ var
194+ Form1: TForm1;
195+
196+ implementation
197+
198+ { TForm1 }
199+
200+ procedure TForm1.FormShow(Sender: TObject);
201+ begin
202+ //接続
203+ ODBCConnection1.FileDSN := ExtractFilePath(Application.ExeName) + 'file.dsn';
204+ ODBCConnection1.Connected := True;
205+ ODBCConnection1.KeepConnection := True;
206+
207+ //トランザクション
208+ SQLTransaction1.DataBase := ODBCConnection1;
209+ SQLTransaction1.Action := caCommit;
210+ SQLTransaction1.Active := True; //not applied to ms access(false)
211+
212+ SQLQuery1.DataBase := ODBCConnection1;
213+ SQLQuery1.UsePrimaryKeyAsKey := False;
214+
215+ SQLQuery1.SQL.Text := 'select * from table1';
216+
217+ // :id はフィールド名 idのパラメータ
218+ SQLQuery1.deleteSQL.Text := 'delete from table1 where id=:id';
219+ //:name はフィールド名 nameのパラメータ
220+ SQLQuery1.updateSQL.Text := 'update table1 set name=:name where id=:id';
221+
222+ DataSource1.DataSet := SQLQuery1;
223+ DBGrid1.DataSource := DataSource1;
224+ DBGrid1.ReadOnly := true;
225+
226+ DBEdit1.DataField := 'id';
227+ DBEdit1.DataSource := DataSource1;
228+ DBEdit2.DataField := 'name';
229+ DBEdit2.DataSource := DataSource1;
230+
231+ SQLQuery1.Open;
232+ end;
233+
234+ function MulDiv(nNumber, nNumerator, nDenominator: Integer): Integer;
235+ begin
236+ Result:=Round(int64(nNumber)*int64(nNumerator)/nDenominator);
237+ end;
238+ procedure TForm1.PrintDbGrid(dbGrid:TdbGrid);
239+ const
240+ LeftMargin = 0.05;
241+ TopMargin = 0.05;
242+ BottomMargin = 0.05;
243+ var
244+ i: integer;
245+ x,y: integer;
246+ begin
247+ if PrintDialog1.Execute then
248+ begin
249+ Printer.BeginDoc;
250+ Printer.Canvas.Font.Size := 12;
251+
252+ y := Round(TopMargin*Printer.PageHeight);
253+ dbGrid.DataSource.DataSet.First;
254+ while not dbGrid.DataSource.DataSet.Eof do
255+ begin
256+ x := Round(LeftMargin*Printer.PageWidth);
257+ for i := 0 to dbGrid.DataSource.DataSet.FieldCount-1 do
258+ begin
259+ printer.Canvas.TextOut(x,y,dbGrid.DataSource.DataSet.Fields[i].AsString);
260+ x := x + MulDiv(dbGrid.Columns[i].Width,72, dbGrid.Width);
261+ end;
262+ dbGrid.DataSource.DataSet.Next;
263+ y := y + printer.Canvas.TextHeight('A');
264+ if y > (1-TopMargin-BottomMargin)* Printer.PageHeight then
265+ begin
266+ y := Round(TopMargin*Printer.PageHeight);
267+ Printer.NewPage;
268+ end;
269+ end;
270+ Printer.EndDoc;
271+ end
272+ else
273+ Form1.caption := 'NO PRINTER INSTALLED';
274+ end;
275+
276+ procedure TForm1.Button1Click(Sender: TObject);
277+ begin
278+ PrintDbGrid(DBGrid1);
279+ end;
280+
281+ procedure TForm1.Button2Click(Sender: TObject);
282+ begin
283+ if button2.Caption = 'new' then
284+ begin
285+ SQLQuery1.Insert;
286+ button2.Caption := 'save';
287+ exit
288+ end
289+ else
290+ begin
291+ if (dbedit1.Text = '') or (dbedit2.Text = '')
292+ then
293+ begin
294+ SQLQuery1.Cancel;
295+ end
296+ else
297+ begin
298+ if SQLQuery1.State = dsInsert then
299+ begin
300+ SQLQuery1.Post;
301+ SQLQuery1.ApplyUpdates;
302+ Form1.caption := 'ADDED';
303+ end;
304+ end;
305+ end;
306+ button2.Caption := 'new';
307+ end;
308+
309+ procedure TForm1.Button3Click(Sender: TObject);
310+ begin
311+ if SQLQuery1.RecordCount>0 then
312+ begin
313+ SQLQuery1.Delete;
314+ SQLQuery1.ApplyUpdates;
315+
316+ //もしSQLdBで問題が生じたら、この2行を加える、あるいは除いてみる
317+ //これら2ラインはMS AccessデータベースのSQLdBのバグに対する手当である
318+ //**** bugtracker アイテムには見当たらない、bugtrackerを作ってほしい
319+ //SQLQuery1.Close;
320+ //SQLQuery1.Open;
321+
322+
323+ Form1.caption := 'DELETED';
324+ end;
325+ end;
326+
327+ procedure TForm1.Button4Click(Sender: TObject);
328+ begin
329+ if SQLQuery1.RecordCount>0 then
330+ begin
331+ SQLQuery1.Edit;
332+ SQLQuery1.Post;
333+ Sqlquery1.ApplyUpdates;
334+ Form1.caption := 'UPDATED';
335+ end;
336+ end;
337+
338+ procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: boolean);
339+ begin
340+ SQLQuery1.Close;
341+ CanClose := True;
342+ end;
343+
344+ initialization
345+ {$I unit1.lrs}
346+
347+ end.
348+```
349+
350+### プログラム的にデータベースを生成する
351+
352+ODBCドライバを用い、プログラム的にMicrosoft Accessデータベースを作ることができる。以下のコードはWindowsの32-bit、64-bitで実行可能である。
353+
354+コード例:
355+```
356+uses
357+ ..., sysutils, odbcsqldyn;
358+
359+ const
360+ ODBC_ADD_DSN=1;
361+ { just for reference...
362+ ODBC_CONFIG_DSN=2;
363+ ODBC_REMOVE_DSN=3;
364+ ODBC_ADD_SYS_DSN=4;
365+ ODBC_CONFIG_SYS_DSN=5;
366+ ODBC_REMOVE_SYS_DSN=6;
367+ ODBC_REMOVE_DEFAULT_DSN=7; }
368+
369+ function SQLConfigDataSource(hwndParent: Integer; fRequest: Integer;
370+ lpszDriverString: PChar; lpszAttributes: PChar): Integer; stdcall;
371+ external 'odbccp32.dll';
372+
373+ function SQLInstallerError(iError: integer; pfErrorCode: PInteger;
374+ lpszErrorMsg: String; cbErrorMsgMax: integer; pcbErrorMsg: PInteger): integer; stdcall;
375+ external 'odbccp32.dll';
376+
377+ procedure CreateAccessDatabase(DatabaseFile: string);
378+ var
379+ cmd: String;
380+ driver: String;
381+ errCode, errMsgLength: DWord;
382+ errMsg: String;
383+ retCode: integer;
384+ ext: String;
385+ begin
386+ ext := Lowercase(ExtractFileExt(DatabaseFile));
387+
388+ driver := 'Microsoft Access Driver (*.mdb, *.accdb)';
389+ { このドライバで
390+ CREATE_DBV12 は .accdbフォーマットデータベースができる
391+ CREATE_DBV4 は.mdbフォーマットデータベースができる
392+ //stackoverflow.com/questions/9205633/how-do-i-specify-the-odbc-access-driver-format-when-creating-the-database
393+ }
394+ if ext = '.mdb' then
395+ cmd := 'CREATE_DBV4="' + DatabaseFile + '"'
396+ else if ext = '.accdb' then
397+ cmd := 'CREATE_DBV12="' + DatabaseFile + '"'
398+ else
399+ raise Exception.Create('Invalid database file extension.');
400+
401+ retCode := SQLConfigDataSource(0, ODBC_ADD_DSN, PChar(driver), PChar(cmd));
402+ if not (retCode in [SQL_SUCCESS, SQL_SUCCESS_WITH_INFO]) then
403+ begin
404+ //別のドライバを試す
405+ driver := 'Microsoft Access Driver (*.mdb)';
406+ cmd := 'CREATE_DB="' + DatabaseFile + '"';
407+ retCode := SQLConfigDataSource(0, ODBC_ADD_DSN, PChar(driver), PChar(cmd));
408+ end;
409+
410+ if not (retCode in [SQL_SUCCESS, SQL_SUCCESS_WITH_INFO]) then
411+ begin
412+ errCode := 0;
413+ errMsgLength := 0;
414+ SetLength(errMsg, SQL_MAX_MESSAGE_LENGTH);
415+ SQLInstallerError(1, @errCode, PChar(errMsg), Length(errMsg), @errMsgLength);
416+ SetLength(errMsg, errMsgLength);
417+ raise Exception.CreateFmt('Error creating Access database: %s', [errMsg]);
418+ end;
419+ end;
420+```
421+
422+### 文字集合問題
423+
424+古いAccessデータベースはANSIキャラクタセットでエンコードされていた(新しいものに関してはわからない - おそらくより広い文字集合を使っているだろう)。そのため、非ASCIIキャラクタはDBGidや、他のデータ志向型コントロールで正しく表示されない。これはOnGetTextとOnSetTextをデータセットを開いたのちに適用すれば修正される可能性がある:
425+```
426+uses
427+ lconvencoding;
428+
429+ procedure TForm1.SQLQuery1AfterOpen(DataSet: TDataSet);
430+ var
431+ i: Integer;
432+ begin
433+ for i:=0 to DataSet.Fields.Count-1 do
434+ begin
435+ if DataSet.Fields[i].DataType=ftString then
436+ begin
437+ DataSet.Fields[i].OnGetText := @ConvertFromDB;
438+ DataSet.Fields[i].OnSetText := @ConvertToDB;
439+ end;
440+ end;
441+ end;
442+
443+ procedure TForm1.ConvertFromDB(Sender: TField; var aText: string; DisplayText: Boolean);
444+ begin
445+ if not Sender.IsNull then
446+ aText := WinCPToUTF8(Sender.AsString); // もしWindowsのデフォルトコードページの場合
447+ end;
448+
449+ procedure TForm1.ConvertToDB(Sender: TField; const aText: string);
450+ begin
451+ if aText <> '' then
452+ Sender.Value := UTF8ToWinCP(aText);
453+ end;
454+```
455+
456+## 作例データベース
457+
458+Microsoft AccessにはNorthwindデータベースが付属する
459+
460+もし、Access Runtimeがインストールされていれば、この別のデータベースをテストデータベースとして利用できる: If you only have the Access Runtime installed, you can use this alternative database from the Mondial project as a test database: [databases.about.com/od/sampleaccessdatabases/a/Microsoft-Access-Sample-Database-Countries-Cities-And-Provinces.htm] _[2020年11月時点でこのリンクは切れている]_
461+
462+## 以下も参照のこと
463+
464+ * [[ODBCConn/ja]] The ODBC connector this article uses
465+
466+---
467+*From the Free Pascal wiki, page "MS Access/ja", as the Internet Archive kept it on 2025-01-17, last changed on 2024-09-25. 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).*

Back to history