【A3】Delphiテクニカルセッション

DBGridの罠
アナハイムテクノロジー株式会社・代表取締役
はやし つとむ

アジェンダ• Delphiデータベースプログラミング• DBGridのTips集• DBGridで複合インデックスを実現する• 参考図書• Delphiが他の開発環境と一線を画して来たのは、そのデータベースとの親和性の高さからだと思います。
• BDEからIBX、ADOExpress、 dbGo、dbExpressと付属のフレームワー
クも充実してきました• DBGridは、MS製品ですらろくなGridの無い時期に画期的なコンポーネン
トでした• とはいえ、帯に短したすきに長しというところが・・・

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

2

Delphiデータベースプログラミング

データベースプログラミングフレームワーク• Delphiは以下のデータベースプログラミングフレームワークをサポートしています••••

BDE（Borland Database Engine）
InterBaseExpressdbGo（ADO/OLEDB）
dbExpress4• その他サードパーティ製品、オープンソース製品• ZeosLib• FIBPlus• IBObjects

http://zeos.firmos.at/
http://www.devrace.com/en/fibplus/
http://www.ibobjects.com/

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

4

BDE（Borland Database Engine）• BDE は、Paradoxをベースとしたフレームワーク。異種DB間でのクエリーのサポートなど、高度な機能もあるが、すでに開発は中止。とはいえ、結構使われている

TDataSource

TDatabase

TDBGrid

TTable

RDBMS
本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

5

InterBaseExpress• InterBaseExpress は、InterBaseと接続するためのフレームワーク。InterBaseAPIを直接利用するコンポーネントで構成されている• TIBTransactionコンポーネントが分離しているのが特徴• 複数のデータベースへの二相コミットに対応出来る

TDataSource

TIBTransaction

TIBDatabase

TDBGrid

TIBTable

RDBMS
本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

6

dbGo

• dbGo は、ADO（ActiveX Data Object）をベースとしたフレームワーク。Delphi5でADOExpressとして導入されて、Delphi6からdbGoという名前になった• InterBaseに接続するためには、ibProvider が利用できる• ibProvider
http://www.ibprovider.com/eng/• Free Edition は、InterBase6まで。有償版では IB2009まで対応
TDataSource

OLEDB Provider

TADOConnection

TDBGrid

TADOTable

RDBMS
本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

7

dbExpress4• dbExpress4 は、Delphi6から導入されたdbExpressの最新版。
Delphi2007でversion 4.0になったが、これまでのドライバも使うことは出来る

TDataSource

dbExpress Driver

TDataSetProvider

TDataSetProvider

TSQLConnection

TSQLTable

TDBGrid

RDBMS
本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

8ZeosLib• ZeosLib は、Delphi/C++Builder/Kylix/Lazarus に対応したオー
プンソースのライブラリ••••

http://zeos.firmos.at/
現在の最新版は、6.6.4で、Delphi2007まで対応
Delphi2009対応は、今後出る予定のver.7までお預け
対応するデータベースが多いのが特徴–––––––––MySQL (normal and embedded)
PostgreSQL
Firebird (normal and embedded)
Interbase
SQLiteMS SQL Server
OracleSybaseADO Connections

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

9

DBGridのTips集

DBGridを使う• データベースへ接続して、DBGridを使うにために以下のように接続します。サンプルとして、InterBase2009にdbExpressで接続してみます• dbExpress は、単方向データセットなので、DBGridに接続する
場合には、TClientDatasetを利用します• InterXpress は、現状ではDelphi2007までの対応
http://www.upscene.com/products.dbx.dbx_fb.php接続は可能だが、クエリーかけるとこける• pgExpressも同様
http://www.vitavoom.com/products/pgedriver/

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

11

ClientDataset• ClientDatasetは、TDataSetを継承したある種のオンメモリデー
タベースです• ソート、フィルタ、グループ化、集合体(Aggregates)などを利用することが出来る

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

12

DBGrid頻出メソッド/プロパティ/イベント(1)• OnKeyDownイベント• Ctrl+Deleteキーでレコードが削除されるが、これを無効にしたい• FocusControlメソッド• 特定のフィールドにフォーカスを移動したい• SelectedFieldプロパティ• 特定の列を飛ばしてフォーカスを移動したい• FieldCountプロパティ• 表示列数を取得する• CurrentRowSelectedプロパティ• Grid上のすべての行を選択状態にする

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

13

DBGrid頻出メソッド/プロパティ/イベント(2)• LeftColプロパティ• 特定の列を一番左側に表示する• Columns.ReadOnlyプロパティ• 特定のフィールドだけ入力したい• OnDrawColumnCellイベント• 特定のセルに色を付けたい• InplaceEditor• 編集状態で文字列を選択状態にしたい• ドロップダウンリストを自動的にドロップダウンさせたい

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

14

DBGridに色を付ける• 各レコードのデータに従って、DBGridの行に色を付ける• キーになるフィールド（状態）などによって、レコード全体を色付する• DBGrid1.DataSource.DataSet.FindField(‘hogehoge’); と辿る

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

15

DBGridにチェックボックスを表示する• Boolean型のデータで、値を選ぶためにチェックボックスを表示する• TDBCheckBoxをコントロールして、DBGridの上に描画する• 非選択状態の時は、TImageListから画像を描画する

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

16

DBGridでグループ化を行う• ClientDataSetを利用して、グループ化された表示を行う。
••••

IndexDefs プロパティに、TIndexDef を追加する
Aggregates プロパティに、TAggregate を追加する
AggregatesActive プロパティを、Trueにする
GetTextで TClientDataSet.GetGroupState を使って判断する

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

17

DBGridのカラムの状態を保存/復元する• DBGridのカラムはユーザーが幅や位置を変更出来る。その操作状態を保存・復元出来るようにする• TDBGridColumns のメソッドを利用する• TDBGrid.Columns.SaveToStream()• TDBGrid.Columns.LoadFromStream()• TDBGrid.Columns.RestoreDefaults はうまく動いてない？

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

18

DBGridで複合インデックスを実現する

DBGridの指定カラムでソートする• ClientDataSetを利用すると、オンメモリでのソートが可能。
DBGridのカラムをクリックして、ソートさせてみる

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

20

DBGridの指定カラムでソートする• ClientDataSetには、IndexDefsというインデックスのコレクションがあるが、これには動的にインデックスを追加できない・・・• Help: AddIndexDef メソッドは，CreateTableまたは CreateDataSet メ
ソッドを後で呼び出してテーブルのインデックス定義を作成する場合にのみ有効です。既存のテーブルにインデックスを追加する場合は使用できません。
• TClientDataSet.IndexDefs.AddIndexDef と、.Addは同じ処理
TClientDataSet

TIndexDefs

function TIndexDefs.AddIndexDef: TIndexDef;
begin
Result := TIndexDef(inherited Add);
end;

AddIndexDef
Add

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

21

DBGridの指定カラムでソートする• ClientDataSetのAddIndexメソッドを利用しても、IndexDefsには追加されない。つまり、この一本を使いまわすしかない。
• AddIndexで追加したインデックスをオブジェクトとして取得したり、設定を動的に変更したりということは出来ないので、変更する時にはDeleteIndex→AddIndexが必要となる。
TClientDataSet

AddIndex
IndexName

インデックス名

DeleteIndex

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

22

DBGridの指定カラムでソートする
procedure TCustomClientDataSet.AddIndex(const Name, Fields: string;
AddIndexの結果をIndexDef
Options: TIndexOptions; const DescFields, CaseInsFields: string;
const GroupingLevel: Integer);
でもらえると嬉しいが、ここから先はDLLの内部ルーチンにvarなってしまう・・・
IndexDesc: DSIDXDesc;
IndexDef: TIndexDef;
begin
CheckBrowseMode;
FieldDefs.Update;
EncodeIndexDesc(IndexDesc, Name, Fields, DescFields, CaseInsFields, Options);
CursorPosChanged;
Check(FDSBase.CreateIndex(IndexDesc));
if GroupingLevel > 0 thenbegin
IndexDefs.Update;IndexDef := IndexDefs.Find(Name);
if IndexDef <> nil thenIndexDef.GroupingLevel := GroupingLevel;function CreateIndex({ Create, and add an index }endconst IdxDesc : DSIDXDesc
else): DBResult; stdcall;IndexDefs.Updated := False;end;

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

23

DBGridを複数カラムでソートする• さらに、複合Index用のクラスを作成し、複数のカラムで複合的にソートするようにしてみる• タイトル行を、Ctrl+クリックするとORDERに追加される• すでに追加されている列をクリックすると、ORDERが切り替わる

COL1

COL2

COL3

COL4

※例えば、 ORDER BY COL1, COL2, COL3 DESC としたい
COL1

COL2

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

COL3

COL424DBGridを複数カラムでソートする• TSotrType:インデックスのオーダー（昇順/降順）を列挙型で定義• TIndexObject:各カラムのインデックスを保持• TListIndexes:複数のTIndexObjectを保持

TIndexObject

TListIndexes

TClientDataSet

TIndexObject
TIndexObject

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

25

参考図書

参考図書

• Delphi6プログラミングバイブル Marco Cantu著/インプレス刊• Mastering Delphi2005 Marco Cnatu著/SYBEX刊• Delphi2007 HANDBOOK Marco Cantu著/自費出版?
• Delphi6プログラミングテクニック裏技180選 金井利美男著/エーアイ出版刊• InsideDelphi Ray Lischner著/アスキー出版局刊• InsideDELPHI2006 Ivan Hladni/Wordware刊• Delphi2009HANDBOOK Marco Cantu著 日本語版が3月に刊行予定！

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

27

アナハイムテクノロジーについて• アナハイムテクノロジー株式会社• 〒157-0072 世田谷区祖師谷1-22-26-S-208• TEL 03-5787-7791 FAX 03-5787-7792• http://www.anaheim-tech.com/• Delphiとオープンソースの技術支援を行っています• InterBase/Firebirdのご相談もぜひ当社へ！
本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

28