|
データベース【TIBTableでDataControlsを使わない】 |
前回はTIBTableとTDBGrid、TDBNavigator、TDBEditを使って簡単なDBを作ってみましたが、この [DataControls]内の TDBNavigator や TDBEdit を使わずにプログラミングする事も出来ます。ボタンを押した時に自分の思う特定の処理をしたいような場合や TDBNavigator に拘束されたくない場合などでよく利用されるようです。
まずは、プロジェクト「d003」の準備を行います。「C:\DelphiProgram\jww」フォルダの中に「d003」というフォルダを作成し、前回の「d002」からファイルをがさっとコピーしてきます。その方が楽ですので。Delphi6を起動します。メニュー「プロジェクト」→「オプション」を実行し、下記の設定を行います。
[アプリケーション]頁
タイトル | d003−データベース作成 |
[ディレクトリ/条件]頁
パス及びディレクトリ | C:\DelphiProgram\db\d003 |
メニュー「ファイル」→「プロジェクトに名前を付けて保存」
「C:\DelphiProgram\db\d003」の中に「d003.dpr」として保存
メニュー「表示」→「プロジェクトマネージャ」
を実行し、コード画面の左側にドッキングさせておきます。
下記のように画面レイアウトを変更しました。
TDBNavigator、TDBEditをやめて普通のTButton、TEditに変えてみました。自動的にやってくれる部分が無くなり自分でプログラミングしないといけませんから手間のように思えるかもしれませんが、この方が扱いやすい場合もあります。
それでは[更新]ボタンから。
procedure IBTable1BeforeRefresh(DataSet: TDataSet);
の内容をそのまま使えますので。
// [更新]
procedure TForm1.Button3Click(Sender: TObject);
begin
// 更新前に一旦閉じて再度開く
IBTable1.Active := False ;
IBTransaction1.Active := False ;
IBTransaction1.Active := True ;
IBTable1.Active := True ;
end; |
前回の TIBTable のイベント
procedure IBTable1AfterPost(DataSet: TDataSet);
procedure IBTable1AfterDelete(DataSet: TDataSet);
procedure IBTable1BeforeRefresh(DataSet: TDataSet);
は削除しておきます。
「procedure TForm1.Button1Click(Sender: TObject);」内の
DBEdit1.DataField := IBTable1.Fields[0].FieldName ;
DBEdit2.DataField := IBTable1.Fields[1].FieldName ;
も不要なので削除します。Edit3,Edi4にデータ内容は自動的に入りませんので、最初のクリア部分と、データ内容を入れるコードを入力します。
// 現在レコードのデータ参照
procedure TForm1.Displaydata;
begin
if not(IBTable1.Active) then exit ;
Edit3.Text := IBTable1.Fields[0].AsString ;
Edit4.Text := IBTable1.Fields[1].AsString ;
end; |
この手続きは TForm1のPrivate宣言の所に記述して下さい。取りあえず DB接続した時と、DBGrid1 のセルのクリック時に、この手続きを実行するように記述します(セルのクリック時であってカーソルキーでの移動時には実行されませんが…)。
// セルをクリックした時
procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin
Displaydata;
end; |
それではレコード移動用のボタンのクリックイベントを記述していきます。
// [最初]
procedure TForm1.Button4Click(Sender: TObject);
begin
if not(IBTable1.Active) then exit ;
IBTable1.First ;
Displaydata;
end;
// [前へ]
procedure TForm1.Button5Click(Sender: TObject);
begin
f not(IBTable1.Active) then exit ;
IBTable1.Prior ;
Displaydata;
if (IBTable1.Bof) then
ShowMessage('もう最初まで来ていますので前には行けません');
end;
// [次へ]
procedure TForm1.Button6Click(Sender: TObject);
begin
if not(IBTable1.Active) then exit ;
IBTable1.Next ;
Displaydata;
if (IBTable1.Eof) then
ShowMessage('もう最後まで来ていますので次にはいけません');
end;
// [最後]
procedure TForm1.Button7Click(Sender: TObject);
begin
if not(IBTable1.Active) then exit ;
IBTable1.Last ;
Displaydata;
end; |
この First、Last、Prior、Next メソッドとBOF・EOFプロパティは、SQLを使う際にも特に利用しますので重要です。テーブル操作での現在のレコードがどこなのか、現在のレコードはどんなデータを指しているのかを意識する事は大切になってきます。
次に、追加登録、挿入登録、編集登録です。
追加登録は
try
IBTable1.Append ;
IBTable1.Fields[0].AsInteger := 〜;
IBTable1.Fields[1].AsString := 〜;
IBTable1.Post ;
IBDatabase1.ApplyUpdates([IBTable1]);
except
;
end; |
挿入登録は
try
IBTable1.Insert ;
IBTable1.Fields[0].AsInteger := 〜;
IBTable1.Fields[1].AsString := 〜;
IBTable1.Post ;
IBDatabase1.ApplyUpdates([IBTable1]);
except
;
end; |
編集登録は
try
IBTable1.Edit ;
IBTable1.Fields[0].AsInteger := 〜;
IBTable1.Fields[1].AsString := 〜;
IBTable1.Post ;
IBDatabase1.ApplyUpdates([IBTable1]);
except
;
end; |
という具合になりますが、[追加登録]ボタン、[挿入登録]ボタン、[編集登録]ボタン、それぞれ1クリックで行う場合であればこれで良いのですが、ここでは、[追加]→〜〜入力→[登録]ボタン、という具合にしていますので少しややこしい状態になっています。[追加]や[挿入]をクリックした時点でダミー登録を行い、それに対して編集登録を行うようにしています。そうしておかないと編集登録を行う際に困った事になってしまうからですが、こういった操作方法によるプログラミングの仕方や、どうやれば使う人にとって使いやすいか等も関わってきますので注意して下さい。
// [追加]
procedure TForm1.Button8Click(Sender: TObject);
begin
if not(IBTable1.Active) then exit ;
// 追加登録(ダミー登録)
try
IBTable1.Append ;
IBTable1.Fields[0].AsInteger := 0 ;
IBTable1.Fields[1].AsString := '-' ;
IBTable1.Post ;
Edit3.SetFocus ;
except
;
end;
end;
// [挿入]
procedure TForm1.Button9Click(Sender: TObject);
begin
if not(IBTable1.Active) then exit ;
// 挿入登録(ダミー登録)
try
IBTable1.Insert ;
IBTable1.Fields[0].AsInteger := 0 ;
IBTable1.Fields[1].AsString := '-' ;
IBTable1.Post ;
Edit3.SetFocus ;
except
;
end;
end;
// [登録]
procedure TForm1.Button11Click(Sender: TObject);
var
n,i : integer ;
s : string ;
begin
if not(IBTable1.Active) then exit ;
// 入力チェック
n := 0 ;
if (Edit3.Text <> '') then Val(Edit3.Text,n,i);
if (i <> 0)or(n < 0) then begin
ShowMessage('Nには0より大きい整数値を入れてね');
Edit3.SetFocus;
exit;
end;
s := Edit4.Text ;
if (s = '') then begin
ShowMessage('何か入力してね');
Edit4.SetFocus;
exit;
end;
if (AnsiPos('''',s) > 0)or(AnsiPos('"',s) > 0) then begin
ShowMessage('単一引用符('')と二重引用符(")は使わないで');
Edit4.SetFocus;
exit;
end;
// 登録
try
IBTable1.Edit ;
IBTable1.Fields[0].AsInteger := n ;
IBTable1.Fields[1].AsString := s ;
IBTable1.Post ;
IBDatabase1.ApplyUpdates([IBTable1]);
ShowMessage('登録OK');
except
Button3Click(Sender); // 更新
ShowMessage('登録失敗');
end;
end; |
というように多少ややこしくなってしまいます。また、ダミー登録をする事で C/S型の場合にはデータ登録が失敗してダミー状態のデータが残る可能性もありますから注意して下さい。それよりは
のようにしたり
のような切替パターンも考えられますし、その他、メニューから選択してきて、それぞれの入力画面で操作を行う、というような手法もあると思います。
次に[削除]ボタンの実装を行います。
// [削除]
procedure TForm1.Button10Click(Sender: TObject);
var
m,n : integer ;
begin
if not(IBTable1.Active) then exit ;
if (IBTable1.RecordCount = 0) then begin
ShowMessage('データがありません');
exit ;
end;
m := IBTable1.RecNo ;
n := IBTable1.Fields[0].AsInteger ;
if MessageDlg('データ(Record:'+IntToStr(m)+' N='+IntToStr(n)+' を削除してもよろしいですか?',
mtConfirmation, [mbYes, mbNo], 0) = mrNo then exit ;
// 削除
try
IBTable1.Delete ;
IBDatabase1.ApplyUpdates([IBTable1]);
ShowMessage('削除OK');
except
Button3Click(Sender); // 更新
ShowMessage('削除失敗');
end;
end; |
のように、削除は Deleteメソッドで可能です。現在レコードのデータが削除されます。
なお、複数PCで同じレコードを同時アクセスすると(参照だけなら大丈夫です)、片方は例外(エラー)を発生する場合があります。例外が発生するとソフトがエラーメッセージを表示して止まってしまいますので、必ず、例外処理を入れる必要があります。
そのほか、フィールドの数を取得する FieldCountプロパティ、フィールド名を取得する際の、IBTable1.Fields[〜].FieldName、Fields[〜]の代わりにフィールド名で指定する際の、IBTable1.FieldByName('〜').〜、、検索(というよりはそのレコードへジャンプ)する際の SetKey & GotoKey、絞り込み表示を行う際の、SetRangeStart〜SetRangeEnd〜ApplyRangeとそのキャンセルの CancelRange、等々はありますが、これでおおよそのプログラムは作成出来るであろうと思われます。検索については、SetKeyではなく、結局、データの最初から最後までを見て、AnsiPos関数などで検索を行う、というような事になる場合も多いです。
ただ、TIBTableを使うとどうしても、TDBGrid を使いたがる傾向はあるように思います。勿論、TStringGrid 等を使用して表示させる事も出来ますが、TStringGridの機能と操作性は「いまいち」という事もあって避けたい場合もあるようです。
TIBTableとTDBGrid を使用すると、つまりそれは、テーブルをずっと開けっぱなし状態、という事になり、クライアント数が増えれば増える程、サーバーの負荷が高くなっていきます。やはり、常時開きっぱなし状態をやめて、普段は閉じた状態、必要な時にのみ開いて、すぐに閉じる、という方が良いようです。そうなると TIBTable&TDBGridという状況は使いにくい/使えない、仕方なしに TIBTable&TStringGrid 等という状況になるにしても、データの検索や並び替え表示・絞り込み表示がなかなか難しい。
そこで SQLを利用する TIBQuery の登場となります。勿論これもTDBGridを使う事は出来ますが上記の理由でTStringGrid等を利用したりするのですが、SQLを使えば色々と面白い事も出来ますし、データベースといえばSQL、というのが現在の定番ですから、是非とも、SQLに慣れておくのが良いと思われます。
|
|
バッチファイル
BASIC
C言語のお勉強
拡張子な話
DOSプログラム
Delphi
シェアウェア
Script!World
データベース
A B C D
E F G H
I J K L
M N O P
Q R S T
U V W X
Y Z
|