|
Delphi Programming / Object Pascal
[掲載 2007年09月09日] [更新 2017年02月04日] Delphi サンプルプログラム集 |
630_ADO で JET データベースの新規作成と最適化 |
動作確認等 |
Windows 7 U64(SP1) + Delphi XE(UP1) Pro + msadox.dll 6.1.7600.16385 |
|
630_CreateMDB.zip [2,990 KB] 2017年02月04日版 (EXE 同梱) |
- 2008年12月01日
- デーベースの新規作成と最適化のプログラムを別々にした
- 2010年05月30日
- JET データベースのインデックスを取得するサンプルを追加
- Delphi 2010(UP5) で動作確認と記事の修正等
- 2011年05月13日
- データベースの表名の変更のサンプルとパスワード関係の記事を追加
- 2017年02月04日
- 最適化とインデックス取得に Access 2007/2010 用 JET の処理コードを追加
|
ADO で JET データベースの新規作成と最適化 - ADOX と JRO |
JET データベースは面倒なインストール作業等が必要ありません.可搬型のデータベースとして使用可能です.パーソナルなデータベースとしての利用価値はあるでしょう.そんな時の参考コードです.
JET データベースエンジンは,特にインデックスを作成しなくても,そこそこのパフォーマンスが得られるようですが,一般的に,データベースはインデックスがないとクエリー等の実行に十分なパフォーマンスが得られません.インデックスは SQL 文で操作可能です.
このページのサンプルでは,[タイプライブラリの取り込み] で ADOX_TLB.pas と JRO_TLB.pas というファイルを作成して,ADOX オブジェクトを使用しています.この作業をしなくても動作可能なプログラムは作成できますが,各オブジェクトを OleVariant で扱うことになります.OleVariant では Delphi の特徴である入力支援機能等が利用できません.入力支援機能が利用できればメソッド類の動作の目安ともなります. |
以下は,サンプルプログラム集の ADO 関係の記事へのリンクです. |
- 図1
- ADOX_TLB.pas の作成
- これは Windows 7 U64 の場合.2.8 でも動作確認済み
- 本サンプルでは [コンポーネントラッパーの作成] は不要.ユニットだけ作成すればよい
|
|
- 図2
- JRO_TLB.pas の作成
- 本サンプルでは [コンポーネントラッパーの作成] は不要.ユニットだけ作成すればよい
|
|
JET データベースのファイルである mdb ファイルを新規に作成して,項目が 3 つだけの表を1つ,インデックス付きで作成します.作成後にその表を表示します.既に作成済みの場合は,単にその表を表示するだけです. |
|
図3
設計時画面
- 以下のコンポーネントを配置 (各 1)
TButton
TADOConnection
TADOQuery
TDataSource
TDBGrid (予めカラムを 3 つ作成)
|
|
図4
実行時画面
- .mdb ファイルがあったら手動で削除してから実行
- 作成直後の表は空
- TDBGrid に入力しているところ
|
|
図5
作成されたデータベースファイル |
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Grids, DBGrids, DB, ADODB, Buttons, ExtCtrls, ADOX_TLB;
type
TForm1 = class(TForm)
DBGrid1: TDBGrid;
Panel1: TPanel;
btnCreate: TButton;
ADOConnection1: TADOConnection;
ADOQuery1: TADOQuery;
DataSource1: TDataSource;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure btnCreateClick(Sender: TObject);
private
{ Private 宣言 }
FDatabaseName : String;
function MakeConnectString(DBName, APass: String): String;
function CreateTable : Boolean;
procedure OpenJETDBTable;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
uses
ComObj;
{$R *.dfm}
//=============================================================================
// データベース切断
//=============================================================================
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ADOConnection1.Connected := False;
end;
//=============================================================================
// JETデータベースが存在して表があればそれを開いてDBGridに表示
// なければデータベースと表を作成してから開く
//
// オブジェクト・インスペクタの設定は以下の通り
// ADOConnection1 デフォルトのまま
// ADOQuery1 Connection := ADOConnection1;
// DataSource1 DataSet := ADOQuery1;
// DBGrid1 DataSource := DataSource1;
//=============================================================================
procedure TForm1.btnCreateClick(Sender: TObject);
var
LUserName : String;
LPassWord : String;
LTableList : TStringList;
LConnectStr : String;
LJET_Catalog : ADOX_TLB.Catalog;
begin
btnCreate.Enabled := False;
//ユーザ名とパスワード
LUserName := 'Mr.XRAY';
LPassWord := '123';
//データベース名
//作成するデータベース(ファイル)名はTEST.mdbとする
//場所はこのプロジェクトのルート
FDatabaseName := '..\TEST.mdb';
//既にデータベースのファイルがある場合
if FileExists(FDatabaseName) then begin
ADOConnection1.Connected := False;
ADOConnection1.Mode := cmReadWrite;
ADOConnection1.LoginPrompt := False;
//接続文字列を作成して接続
LConnectStr := MakeConnectString(FDatabaseName, LPassWord);
ADOConnection1.ConnectionString := LConnectStr;
ADOConnection1.Connected := True;
LTableList := TStringList.Create;
try
//表の名前はPETSONとする
//表の一覧をTableListに取得
ADOConnection1.GetTableNames(LTableList);
//表がなければ作成して開く
if LTableList.IndexOf('PERSON') >= 0 then begin
OpenJETDBTable;
end else begin
if CreateTable then OpenJETDBTable;
end;
finally
FreeAndNil(LTableList);
end;
//データベースが存在しない場合は新規作成
end else begin
//ADOXのCatalogオブジェクトを生成
LJET_Catalog := ADOX_TLB.CoCatalog.Create;
try
ADOConnection1.Connected := False;
ADOConnection1.Mode := cmReadWrite;
ADOConnection1.LoginPrompt := False;
//接続文字列
LConnectStr := MakeConnectString(FDatabaseName,LPassWord);
//データベース作成
LJET_Catalog.Create(LConnectStr);
//接続文字列を設定して接続
ADOConnection1.ConnectionString := LConnectStr;
ADOConnection1.Connected := True;
//表を作成して開く
if CreateTable then OpenJETDBTable;
finally
LJET_Catalog := nil;
end;
end;
btnCreate.Enabled := True;
end;
//=============================================================================
// 接続用の文字列を生成
// パスワードなしのMDBにも使用可能(パスワードの文字列を空文字にする)
// ユーザ名の設定は無効なので設定していない
//
// 以下の順
// プロバイダ
// データベース名
// パスワードが必要な場合の設定
// パスワード
//=============================================================================
function TForm1.MakeConnectString(DBName, APass: String): String;
begin
Result := 'Provider=Microsoft.Jet.OLEDB.4.0'
+ ';Data Source=' + DBName
+ ';Jet OLEDB:Database '
+ 'Password=' + APass;
end;
//=============================================================================
// PERSONという名前の表を作成
// 同名の表があれば削除して新規に作成
//=============================================================================
function TForm1.CreateTable : Boolean;
var
LTableList : TStringList;
begin
Result := False;
LTableList := TStringList.Create;
try
//トランザクション開始
ADOConnection1.BeginTrans;
try
ADOQuery1.Close;
ADOConnection1.GetTableNames(LTableList);
//表は既にあるのでその表を削除
if LTableList.IndexOf('PERSON') >= 0 then begin
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add ('DROP TABLE PERSON ');
ADOQuery1.ExecSQL;
end;
//表作成.項目IDをPrimaryインデックスとする
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add ('CREATE TABLE PERSON ');
ADOQuery1.SQL.Add ('( ');
ADOQuery1.SQL.Add (' ID INT CONSTRAINT IDX_NO PRIMARY KEY, ');
ADOQuery1.SQL.Add (' SHIMEI VARCHAR, ');
ADOQuery1.SQL.Add (' ADDRESS VARCHAR ');
ADOQuery1.SQL.Add (') ');
ADOQuery1.ExecSQL;
//項目SHIMEIにインデックスを作成
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add ('CREATE INDEX IDX_SHIMEI ON PERSON ');
ADOQuery1.SQL.Add (' (SHIMEI) ');
ADOQuery1.ExecSQL;
//コミット
ADOConnection1.CommitTrans;
Result := True;
except
//失敗したら元に戻す(ロールバック)
ADOConnection1.RollbackTrans;
MessageDlg('表の作成に失敗しました.', mtWarning, [mbOK], 0);
end;
finally
FreeAndNil(LTableList);
end;
end;
//=============================================================================
// 表を開くクエリーを実行
// DBGrid1にはあらかじめカラムを作成しておく
//=============================================================================
procedure TForm1.OpenJETDBTable;
begin
ADOQuery1.DisableControls;
ADOQuery1.Close;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('SELECT ID, SHIMEI, ADDRESS FROM PERSON ');
ADOQuery1.Open;
ADOQuery1.EnableControls;
//DBGridへの表示を設定
DBGrid1.Columns[0].FieldName := 'ID';
DBGrid1.Columns[1].FieldName := 'SHIMEI';
DBGrid1.Columns[2].FieldName := 'ADDRESS';
DBGrid1.Columns[0].Title.Caption := 'ID';
DBGrid1.Columns[1].Title.Caption := '氏名';
DBGrid1.Columns[2].Title.Caption := '住所';
DBGrid1.Columns[0].Width := 50;
DBGrid1.Columns[1].Width := 90;
DBGrid1.Columns[2].Width := 210;
end;
end.
02_JET データベースの最適化とパスワードの変更 |
JET データベースのファイルは使用しているとそのサイズが肥大化し,パフォーマンスも低下してきます.それを「最適化」します.いつどんなタイミングで最適化したらいいのかはよくわかりませんが,筆者の使用しているアプリで,起動時または終了時に最適化を選択できるものがあります.
このサンプルでは Access 98 /2000 用の JET データベースの最適化には JRO (Microsoft Jet and Replication Objects) を使用しています.Access 2007 / 2010 用の JET データベースの最適化には DAO オブジェクトの CompactDatabase メソッドを使用しています.
新しいパスワードの入力コントロールを追加すれば,パスワードの変更もできます.
また,DAO オブジェクトの CompactDatabase メソッドの第 4 引数の値を,JET エンジン 4.0 に該当する dbVersion40 にすれば,Access 2007 / 2010 用のデータベースを Access 2000 用のデータベースに変換することができます.
|
|
図6
設計時画面
- ファイルを選択後,パスワード入力ダイアログ
- パスワードが不要の場合は空のままとする
- 前のサンプルの DB のパスワードは 123
|
|
図7
最適化終了 |
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ExtCtrls, JRO_TLB;
type
TForm1 = class(TForm)
OpenDialog1: TOpenDialog;
btnRefresh: TButton;
procedure btnRefreshClick(Sender: TObject);
private
{ Private 宣言 }
function GetJETVersionText(ADBName: string): string;
function MakeConnectString(ADBName, APass: String): string;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
uses
DBLogDlg,
ComObj;
{$R *.dfm}
//=============================================================================
// JETデータベース最適化
// 元のファイルの複製を作成しそれを最適化する
// パスワードの変更にも使用できる
//
// LoginDilaogEx関数の使用にはusesにDBLogDlgが必要
//=============================================================================
procedure TForm1.btnRefreshClick(Sender: TObject);
const
dbLangJapanese = ';LANGID=0x0411;CP=932;COUNTRY=0';
dbVersion120 = 128;
dbVersion40 = 64;
var
LJETVerText : string;
LDatabaseName : string;
LUserName : String;
LPassWord : string;
LPassWordArg : string;
LPassWordNew : string;
LCompDBName : string;
LSrcConnectStr : string;
LDestConnectStr : string;
LJETEngine : JRO_TLB.JetEngine;
LACE_JETEngine : OleVariant;
LResultBool : Boolean;
begin
OpenDialog1.Filter:= 'mdb ファイル(*.mdb)|*.mdb';
if OpenDialog1.InitialDir='' then begin
OpenDialog1.InitialDir := ExtractFilePath(ExtractFileDir(Application.ExeName));
end;
if OpenDialog1.Execute = False then exit;
OpenDialog1.InitialDir := ExtractFileDir(OpenDialog1.FileName);
Update;
//最適化するデータベース名
LDatabaseName := OpenDialog1.FileName;
//最適化後のデータベース名
LCompDBName := ExtractFilePath(LDatabaseName) + 'COMP.mdb';
//もし前の作業で残っていれば削除
DeleteFile(LCompDBName);
//JETのバージョン文字列を取得
LJETVerText := GetJETVersionText(LDatabaseName);
if LJETVerText = '' then exit;
//ユーザ名とパスワード(ユーザ名は実際には不要)
LUserName := 'Mr.XRAY';
LPassWord := '';
if LoginDialogEx('JETデータベース', LUserName, LPassWord, False) then begin
Update;
Screen.Cursor := crSQLWait;
LResultBool := False;
//JET 2000用
if LowerCase(LJETVerText) = 'standard jet db' then begin
//JetEngineオブジェクトを生成
//LJETEngine := CreateComObject(CLASS_JetEngine) as IJetEngine;でも同じ
LJETEngine := JRO_TLB.CoJetEngine.Create;
try
//接続文字列を作成
LSrcConnectStr := MakeConnectString(LDatabaseName, LPassWord);
//パスワードを変更する場合はここのLPassWordを変更する
LDestConnectStr := MakeConnectString(LCompDBName, LPassWord);
//最適化
LJETEngine.CompactDatabase(LSrcConnectStr, LDestConnectStr);
LResultBool := True;
except
end;
LJETEngine := nil;
end else
//JET 2007/2010用
if LowerCase(LJETVerText) = 'standard ace db' then begin
//JetEngineオブジェクトを生成
LACE_JETEngine := CreateOleObject('DAO.DBEngine.120');
try
//パスワードを変更する場合は,LPassWordNew := ';pwd=abc';のように指定する
LPassWordNew := '';
LPassWordArg := '';
if LPassWord <> '' then LPassWordArg := ';pwd=' + LPassWord;
//最適化
LACE_JETEngine.CompactDatabase(LDatabaseName,
LCompDBName,
dbLangJapanese + LPassWordNew,
dbVersion120,
LPassWordArg);
LResultBool := True;
except
end;
LACE_JETEngine := Unassigned;
end;
if LResultBool then begin
//元のmdbファイルを削除して最適化したmdbを元の名前にする
DeleteFile(LDatabaseName);
RenameFile(LCompDBName, LDatabaseName);
Application.ProcessMessages;
MessageBox(Handle, '最適化が終了しました', '情報', MB_ICONINFORMATION);
end else begin
//パスワードが違う場合も失敗
MessageBox(Handle, '最適化に失敗しました', '情報', MB_ICONWARNING);
end;
end;
Screen.Cursor := crDefault;
end;
//-----------------------------------------------------------------------------
// mdbファイル内のJETバージョン文字列を取得
//-----------------------------------------------------------------------------
function TForm1.GetJETVersionText(ADBName: string): string;
var
LFileStream : TFileStream;
LBuffer : array [0..15] of AnsiChar;
begin
Result := '';
if not FileExists(ADBName) then exit;
//JETのバージョン文字列を取得
LFileStream := TFileStream.Create(ADBName, fmOpenRead);
try
LFileStream.Position := 4;
LFileStream.Read(LBuffer, Length(LBuffer));
Result := Trim(string(LBuffer));
finally
FreeAndNil(LFileStream);
end;
end;
//-----------------------------------------------------------------------------
// 接続用の文字列を生成
// パスワードなしのMDBにも使用可能(パスワードの文字列を空文字にする)
// ユーザ名の設定は無効なので設定していない
//
// 以下の順
// プロバイダ
// データベース名
// パスワードが必要な場合の設定
// パスワード
//-----------------------------------------------------------------------------
function TForm1.MakeConnectString(ADBName, APass: string): string;
begin
Result := 'Provider=Microsoft.Jet.OLEDB.4.0'
+ ';Data Source=' + ADBName
+ ';Jet OLEDB:Database '
+ 'Password=' + APass;
end;
end.
03_JET データベースのインデックスを取得して表示 |
表のインデックスは SQL 文でも操作できますが,インデックスの取得機能はないようです.そこで,インデックスの一覧を表示するコードを作成してみました.ADOX_TLB.pas 内のオブジェクトを使用しています. |
|
図8
設計時画面 |
|
図9
実行時画面
- 前のサンプルで作成したデータベースの場合 (パスワードは 123)
- * 印は Primary インデックスの意味
- システム関係の表も表示されている
|
リスト3
JET データベースのインデックスを取得して表示 |
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ExtCtrls, ADOX_TLB, ComCtrls;
type
TForm1 = class(TForm)
Panel1: TPanel;
ListBox1: TListBox;
Splitter1: TSplitter;
ListView1: TListView;
Button1: TButton;
OpenDialog1: TOpenDialog;
procedure Button1Click(Sender: TObject);
procedure ListBox1Click(Sender: TObject);
private
{ Private 宣言 }
FConnectStr : String;
FDatabaseName : String;
function GetJETVersionText(DBName: string): string;
function MakeConnectString(AJETVerText, ADBName, APass: string): string;
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
uses DBLogDlg;
{$R *.dfm}
//=============================================================================
// JETデータベースの表名リストを作成
//
// LoginDilaogEx関数の使用にはusesにDBLogDlgが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LJETVerText : string;
LUserName : string;
LPassWord : string;
LJET_Catalog : ADOX_TLB.Catalog;
LJET_Table : ADOX_TLB.Table;
i : Integer;
begin
OpenDialog1.Filter:='JETデータベースファイル(*.mdb)|*.mdb';
if OpenDialog1.InitialDir='' then OpenDialog1.InitialDir:= '../';
if OpenDialog1.Execute = False then exit;
Update;
ListBox1.Items.Clear;
ListBox1.Items.BeginUpdate;
//データベース名
FDatabaseName := OpenDialog1.FileName;
//JETのバージョン文字列を取得
LJETVerText := GetJETVersionText(FDatabaseName);
if LJETVerText = '' then exit;
//ユーザ名とパスワード(ユーザ名は実際には不要)
LUserName := 'Mr.XRAY';
LPassWord := '';
if LoginDialogEx('JETデータベース', LUserName, LPassWord, False) then begin
//ADOXのCatalogオブジェクトとTableオブジェクトを生成
LJET_Catalog := ADOX_TLB.CoCatalog.Create;
LJET_Table := ADOX_TLB.CoTable.Create;
//接続文字列を作成
FConnectStr := MakeConnectString(LJETVerText, FDatabaseName, LPassWord);
try
//接続してCatalogオブジェクトを取得
LJET_Catalog.Set_ActiveConnection(FConnectStr);
//表のリストをListBox1に表示
for i := 0 to LJET_Catalog.Tables.Count -1 do begin
LJET_Table := LJET_Catalog.Tables[i];
ListBox1.Items.Add(LJET_Table.Name);
end;
except
raise;
end;
end;
ListBox1.Items.EndUpdate;
LJET_Catalog := nil;
LJET_Table := nil;
end;
//=============================================================================
// ListBox1のOnClickイベント処理
// 選択した表に設定されているインデックスとインデックスが定義されている項目
// 名(フィールド名)をリスト
//
// ListView1の設定
// ViewStyle = vsReport
// カラムを(Columnsプロパティで)2つ作成
//=============================================================================
procedure TForm1.ListBox1Click(Sender: TObject);
var
LJET_Catalog : ADOX_TLB.Catalog;
LJET_Table : ADOX_TLB.Table;
LJET_Index : ADOX_TLB.Index;
LItem : TListItem;
i : Integer;
j : Integer;
begin
if ListBox1.SelCount = 0 then exit;
//処理に必要なオブジェクトを生成
LJET_Catalog := ADOX_TLB.CoCatalog.Create;
LJET_Table := ADOX_TLB.CoTable.Create;
LJET_Index := ADOX_TLB.CoIndex.Create;
//表一覧を取得する際に作成した接続文字列ConnectStrを使用して接続
//その際にLJET_Catalogをnilにしないで,グローバル変数にしておけばこの行と
//CoCatalog.Createは不要
LJET_Catalog.Set_ActiveConnection(FConnectStr);
//ListBox1の選択した表名のTableオブジェクトを取得
LJET_Table := LJET_Catalog.Tables[ListBox1.Items[ListBox1.ItemIndex]];
ListView1.Items.Clear;
ListView1.Items.BeginUpdate;
//表に設定されているインデックスとインデックスが定義されている項目名をリスト
for i := 0 to LJET_Table.Indexes.Count - 1 do begin
LJET_Index := LJET_Table.Indexes[i];
for j := 0 to LJET_Index.Columns.Count - 1 do begin
LItem := ListView1.Items.Add;
//PrimaryKeyの時は先頭に*を付加
if LJET_Index.PrimaryKey then begin
LItem.Caption := '* ' + LJET_Index.Name;
end else begin
LItem.Caption := LJET_Index.Name;
end;
LItem.SubItems.Add(LJET_Index.Columns[j].Name);
end;
end;
ListView1.Items.EndUpdate;
LJET_Catalog := nil;
LJET_Table := nil;
LJET_Index := nil;
end;
//-----------------------------------------------------------------------------
// mdbファイル内のJETバージョン文字列を取得
//-----------------------------------------------------------------------------
function TForm1.GetJETVersionText(DBName: string): string;
var
LFileStream : TFileStream;
LBuffer : array [0..15] of AnsiChar;
begin
Result := '';
if not FileExists(DBName) then exit;
//JETのバージョン文字列を取得
LFileStream := TFileStream.Create(DBName, fmOpenRead);
try
LFileStream.Position := 4;
LFileStream.Read(LBuffer, Length(LBuffer));
Result := Trim(string(LBuffer));
finally
FreeAndNil(LFileStream);
end;
end;
//-----------------------------------------------------------------------------
// 接続用の文字列を生成
// パスワードなしのMDBにも使用可能(パスワードの文字列を空文字にする)
// ユーザ名の設定は無効なので設定していない
//
// 以下の順
// プロバイダ
// データベース名
// パスワードが必要な場合の設定
// パスワード
//
// Microsoft Access 98/2000 のJETはMicrosoft.ACE.OLEDB.12でも接続可能
//-----------------------------------------------------------------------------
function TForm1.MakeConnectString(AJETVerText, ADBName, APass: string): string;
begin
if LowerCase(AJETVerText) = 'standard jet db' then begin
Result := 'Provider=Microsoft.Jet.OLEDB.4.0'
+ ';Data Source=' + ADBName
+ ';Jet OLEDB:Database '
+ 'Password=' + APass;
end else
if LowerCase(AJETVerText) = 'standard ace db' then begin
Result := 'Provider=Microsoft.ACE.OLEDB.12.0'
+ ';Data Source=' + ADBName
+ ';Jet OLEDB:Database '
+ 'Password=' + APass;
end;
end;
end.
JET データベースでは,表名 (テーブル名)を 変更する SQL 文は使用できません.
以下のサンプルでは,ADOX の Catalog オブジェクトの Tablesコ レクションから,対象となる表に対して,表名変更を実行します.
ここでは,本ページの最初のサンプルで作成した PERSON という表の名前を PERSON_ABC という名前に変更します. |
|
図10
設計時画面 |
|
図11
実行時画面
|
リスト4
JET データベースの表の名前を変更する例 |
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Grids, DBGrids, DB, ADODB, Buttons, ExtCtrls, ADOX_TLB;
type
TForm1 = class(TForm)
DBGrid1: TDBGrid;
Panel1: TPanel;
ADOConnection1: TADOConnection;
ADOQuery1: TADOQuery;
DataSource1: TDataSource;
Button1: TButton;
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
FDatabaseName : String;
function MakeConnectString(DBName, APass: String): String;
procedure OpenJETDBTable(TableName: String);
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
//=============================================================================
// データベース切断
//=============================================================================
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ADOConnection1.Connected := False;
end;
//=============================================================================
// テーブル名(表名)を変更する
// TEST.mdbというデータベースが存在してPERSONという名前の表もあると仮定
//
// ADOX_TLB.Catalogの使用にはusesにADOX_TLBが必要
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
var
LBeforeTblName : String;
LAfterTblName : String;
LUserName : String;
LPassWord : String;
LConnectStr : String;
LTableList : TStringList;
LJET_Catalog : ADOX_TLB.Catalog;
begin
//変更前と変更後の表名
LBeforeTblName := 'PERSON';
LAfterTblName := 'PERSON_ABC';
//ユーザ名とパスワード
LUserName := 'Mr.XRAY';
LPassWord := '123';
//データベース名
//開くデータベース(ファイル)名はTEST.mdb
//場所はこのプロジェクトのフォルダの1つ上のフォルダ
FDatabaseName := '..\TEST.mdb';
//データベースのファイルがなければ終了
if not FileExists(FDatabaseName) then exit;
ADOConnection1.Connected := False;
ADOConnection1.Mode := cmReadWrite;
ADOConnection1.LoginPrompt := False;
//接続文字列を作成
LConnectStr := MakeConnectString(FDatabaseName, LPassWord);
ADOConnection1.ConnectionString := LConnectStr;
ADOConnection1.Connected := True;
//表名のリストを作成して,目的の表があるかを確認
LTableList := TStringList.Create;
try
ADOConnection1.GetTableNames(LTableList);
//変更前の表があって,変更後の表名がなければ表名の変更を実行
if (LTableList.IndexOf(LBeforeTblName) >= 0) then begin
if (LTableList.IndexOf(LAfterTblName) < 0) then begin
ADOConnection1.Connected := False;
//ADOXのCatalogオブジェクトを生成
LJET_Catalog := ADOX_TLB.CoCatalog.Create;
try
//ADOXのCatalog接続(アクティブ化)
LJET_Catalog.Set_ActiveConnection(LConnectStr);
//テーブル名変更
LJET_Catalog.Tables.Item[LBeforeTblName].Name := LAfterTblName;
finally
LJET_Catalog := nil;
end;
end;
end;
//表を開く
if (LTableList.IndexOf(LAfterTblName) >= 0) then begin
OpenJETDBTable(LAfterTblName);
end;
finally
FreeAndNil(LTableList);
end;
end;
//=============================================================================
// 表を開くクエリーを実行
// DBGrid1にはあらかじめカラムを作成してあるものとする
//=============================================================================
procedure TForm1.OpenJETDBTable(TableName: String);
begin
ADOQuery1.Close;
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('SELECT ID, SHIMEI, ADDRESS FROM ' + TableName);
ADOQuery1.Open;
//DBGridへの表示を設定
DBGrid1.Columns[0].FieldName := 'ID';
DBGrid1.Columns[1].FieldName := 'SHIMEI';
DBGrid1.Columns[2].FieldName := 'ADDRESS';
DBGrid1.Columns[0].Title.Caption := 'ID';
DBGrid1.Columns[1].Title.Caption := '氏名';
DBGrid1.Columns[2].Title.Caption := '住所';
DBGrid1.Columns[0].Width := 50;
DBGrid1.Columns[1].Width := 90;
DBGrid1.Columns[2].Width := 210;
end;
//=============================================================================
// 接続用の文字列を生成
// パスワードなしのMDBにも使用可能(パスワードの文字列を空文字にする)
// ユーザ名の設定は無効なので設定していない
//
// 以下の順
// プロバイダ
// データベース名
// パスワードが必要な場合の設定
// パスワード
//=============================================================================
function TForm1.MakeConnectString(DBName, APass: String): String;
begin
Result := 'Provider=Microsoft.Jet.OLEDB.4.0'
+ ';Data Source=' + DBName
+ ';Jet OLEDB:Database '
+ 'Password=' + APass;
end;
end.
データベースのパスワードを忘れると,データベースを操作することができません.
そのような場合は,例えば Rixler Software の Access Password Recovery Master というユーティリティを使用すると解析できます.
ネットで検索すると,この他にもこの種のアプリケーションがあるようです. |
|