[BlueLeaf1336]> PROGRAM> Natural Born Junk>
| history | TOP |
2003/02/02:作成(参考:MSDNライブラリ)
| overview | TOP |
続きです。前回のページは、DAO36調査-1になります。
| Fieldsコレクション・Fieldオブジェクト | TOP |
これから、TableDef.FieldsコレクションとFieldオブジェクトについてループをまわすことにします。 Propertiesコレクションでループをまわす予定にしていますが、ついでですので、実際のプロパティについても調べておきます。
| Fieldsコレクション | ||
|---|---|---|
| プロパティ | Count | コレクションが持つオブジェクト数。整数型(Integer)。 |
| Fieldオブジェクト | ||
|---|---|---|
| プロパティ | AllowZeroLength | ブール型(Boolean) |
| Attributes | 長整数型(Long)の定数の組み合わせ(※1参照) | |
| CollatingOrder | 長整数型(Long)の値か、定数のいずれか(※2参照) | |
| DataUpdatable | ブール型(Boolean) | |
| DefaultValue | 半角255文字(255バイト)以内の文字列型(String) | |
| FieldSize | 長整数型(Long) | |
| ForeignName | 文字列型(String) | |
| Name | 文字列型(String) | |
| OrdinalPosition | 整数型(Integer)。既定値0 | |
| OriginalValue | バリアント式(ODBCDirectワークスペースでのみ使用可) | |
| Required | ブール型(Boolean) | |
| Size | 整数型(Integer) | |
| SourceField | 文字列型(String) | |
| SourceTable | 文字列型(String) | |
| Type | 操作の種類やデータ型を示す定数(前回のProperty.Typeに同じ) | |
| ValidateOnSet | ブール型(Boolean) | |
| ValidationRule | 文字列型(String) | |
| ValidationText | 文字列型(String) | |
| Value | バリアント型(Variant) | |
| VisibleValue | バリアント式(ODBCDirectワークスペースでのみ使用可) | |
これについては、タイプライブラリに載っている定数値もあわせて示しておきます。
| (※1)Field.Attributes | ||
|---|---|---|
| dbFixedField | $00000001 | フィールドサイズ固定。Numeric型(Numeric)フィールド既定値 |
| dbVariableField | $00000002 | フィールドサイズ可変(テキスト型(Text)フィールドのみ) |
| dbAutoIncrField | $00000010 | 自動的に増え一意な長整数型(Long)の値をとる。変更不可 |
| dbUpdatableField | $00000020 | フィールド値変更可 |
| dbSystemField | $00002000 | レプリカのレプリケーション情報を含む。削除不可 |
| dbHyperlinkField | $00008000 | ハイパーリンク情報を含む。(メモ型(Memo)フィールドのみ) |
| dbDescending | $00000001 | 降順(Z〜A、100〜0、ん〜あ)に並べ替えられる |
同じくこれも。多分ほとんど関係ないだろうとは思いますが。
| (※2)Field.CollatingOrder | ||
|---|---|---|
| dbSortNeutral | $00000400 | 上記以外 |
| dbSortArabic | $00000401 | アラビア語 |
| dbSortCyrillic | $00000419 | ロシア語 |
| dbSortCzech | $00000405 | チェコ語 |
| dbSortDutch | $00000413 | オランダ語 |
| dbSortGeneral | $00000409 | 欧米標準(英語、フランス語、ドイツ語、ポルトガル語、イタリア語、現代スペイン語) |
| dbSortGreek | $00000408 | ギリシャ語 |
| dbSortHebrew | $0000040D | ヘブライ語 |
| dbSortHungarian | $0000040E | ハンガリー語 |
| dbSortIcelandic | $0000040F | アイスランド語 |
| dbSortNorwDan | $00000406 | ノルウェー語、デンマーク語 |
| dbSortPDXIntl | $00000409 | ParadoxのInternationalの並べ替え順序 |
| dbSortPDXNor | $00000406 | Paradoxのノルウェー語とデンマーク語の並べ替え順序 |
| dbSortPDXSwe | $0000041D | Paradoxのスウェーデン語とフィンランド語の並べ替え順序 |
| dbSortPolish | $00000415 | ポーランド語 |
| dbSortSpanish | $0000040A | 古スペイン語 |
| dbSortSwedFin | $0000041D | スウェーデン語、フィンランド語 |
| dbSortTurkish | $0000041F | トルコ語 |
| dbSortJapanese | $00000411 | 日本語 |
| dbSortChineseSimplified | $00000804 | 中国語(中国) |
| dbSortChineseTraditional | $00000404 | 中国語(台湾) |
| dbSortKorean | $00000412 | 韓国語 |
| dbSortThai | $0000041E | タイ語 |
| dbSortSlovenian | $00000424 | スロベニア語 |
| dbSortUndefined | $FFFFFFFF | 未定義または不明な並べ替え順序 |
さて、これでまわす準備ができました。前回のコードにさらにひとつネストを加えていってみます。
var
i, j, k: integer;
begin
for i := 0 to daoDatabase.TableDefs.Count - 1 do
begin
for j := 0 to daoDatabase.TableDefs[i].Fields.Count - 1 do
begin
for k := 0 to daoDatabase.TableDefs[i].Fields[j].Properties.Count - 1 do
begin
try
Memo1.Lines.Add(
BoolToStr(daoDatabase.TableDefs[i].Fields[j].Properties[k].Inherited, True)
+ ' : '
+ daoDatabase.TableDefs[i].Fields[j].Properties[k].Name;
+ ' : '
+ PropertyTypeToStr(daoDatabase.TableDefs[i].Fields[j].Properties[k].Type)
+ ' : '
+ VarToStr(daoDatabase.TableDefs[i].Fields[j].Properties[k].Value)
);
except
on E:Exception do
begin
AStrings.Add(Format('%d : %s', [i, E.Message]));
end;
end;
end;
end;
end;
end;
こんなところですか。実行してみると、速い早い(前回の最後と比べてですが)。 ループネストが1段深くなっているので、もっと遅くなるだろうと思っていたんですが、そんなことなかったです。 あと、邪魔くさいのでココには乗せませんが、上のField.AttributesとField.CollatingOrderの文字列への変換関数は作っておくことにします。
| CreateXXXXXXXメソッド | TOP |
ところで、ループの中で、何度も同じ変数とインデックスでオブジェクトにアクセスしているのですが、 Variant変数に収めてすっきりさせたくなることがあります。 でも、実際にやってみると、エラーになります。
var
i, j, k: integer;
objTableDefs, objTableDef: Variant;
begin
objTableDefs := daoDatabase.TableDefs;
for i := 0 to objTableDefs.Count - 1 do
begin
for j := 0 to objTableDefs[i].Fields.Count - 1 do
begin
上のコードは、3段ネストプロパティアクセステスト用コードの、最初の一部分を勝手に変数に代入したものです。 このコード、実は、2行目の.Countはエラーにならずに通り抜けます。 しかし、4行目で、変数にインデックスをつけて各オブジェクトにアクセスしようとすると怒られます。 まああたりまえのような気もしますが...
これはおそらく、objTableDefs変数が、TableDefs型のコレクションであるということがもうひとつ示しきれていないところに原因があるように思います。 早い話全然だめということじゃないかと。 じゃあどうするか。うっとうしく長い長いプロパティアクセスを奈落ネストまでつなげるか。 というとそうでもないです。それが、...続きます。
いや、だめなようです。 OpenRecordSetというのがあるので、おんなじ感じで、既に存在しているテーブルやフィールドを参照するためのメソッドもあるだろうと勝手に考えていたのですが、甘かったです。 ひょっとしたらあるのかもしれないけども、わかりませんでした。 この長い長いプロパティアクセスで最後まで押し通すことにしましょう。
| mdb構造解析プログラムを作ってみよう | TOP |
というわけで、テーブル自体の情報、テーブルのフィールドの情報は取得できるようになりましたので、構造解析プログラム(というほどでもない?)を作ってみることにしましょう。 名前も決めてます。mdber(えむでばー)です。 「mdb」+「er(する人)」で、「mdbを解析するもの」ということにします。嘘っぱちな英語ですが。
で、何を出力するか?についてまず表にまとめておきます。
| テーブル自体(TableDefオブジェクトの贈り物) | |
|---|---|
| Attributes | テーブルの属性 |
| DateCreated | 作成された日付と時刻 |
| LastUpdated | 最後に変更された日付と時刻 |
| Name | テーブル名 |
| RecordCount | レコード総数 |
| SourceTableName | リンクテーブル名 |
| テーブルのフィールド(Fieldオブジェクトの贈り物) | |
|---|---|
| AllowZeroLength | 長さ 0 の文字列("")を設定できるかどうか |
| Attributes | フィールドの属性 |
| DefaultValue | 既定値 |
| FieldSize | メモ型(Memo)の文字数またはロングバイナリ型(LongBinary)のバイト数 |
| Name | フィールド名 |
| OrdinalPosition | フィールドの表示順序 |
| Required | Null値を使用できるか |
| Size | メモ型(Memo)以外の文字データからなるフィールドの場合は、保持できる最大の文字数。数値フィールド場合は、保存に必要なバイト数 |
| SourceField | データソースのフィールド名 |
| SourceTable | データソースのテーブル名 |
| Type | データ型 |
こんな感じにしておきます。 それから、上の表に挙げた項目を保持するための構造体の構造(?)も決めておきます。
type
//TableDef用構造体
TTableDef = record
Attributes : string;
DateCreated : TDateTime;
LastUpdated : TDateTime;
Name : string;
RecordCount : integer;
SourceTableName : string;
end;
//TableDef.Field用構造体
TTableDefField = record
AllowZeroLength : Boolean;
Attributes : string;
DefaultValue : string;
Name : string;
OrdinalPosition : integer;
Required : Boolean;
Size : integer;
SourceField : string:
SourceTable : string;
FieldType : string;
end;
また、TableDefオブジェクトは、TableDefsコレクションによって管理され、FieldオブジェクトがFieldsコレクションによって管理されていることから、それぞれTTableDefList、TTableDefFieldListを用意しといたほうがよいような気がします。 ココでのListがなんなのかについてはまだ考えていません。
今の段階では、本当の出力の方法(HTMLで吐き出すとか、画面上でタブごとに1テーブルのデータを表示するとか、Gridに表示するとか)については、まったく考えていません。 とりあえず、mdbの構造をとりだして、自分で定義した構造体(やその他)に格納しようとしている段階です。 データとして持っとけばどんな形だろうがいけるだろう、いけるんじゃないか、いけるかも、みたいに思っているわけです。
と、ここまで考えてきてひょっとしてクラスにしてしまったほうがいいかも、とも思ってきました。何の根拠もないですが。
....できました。スレッドにしたりいろいろしましたが、邪魔くさくなってしまってますが、とりあえず、HTMLに吐き出します。 せっかくなので、DOWNLOADページにおきました。
| EOF | TOP |