はじめまして。limlと申します。
現在、Delphi6 + paradox でアプリケーションを作成しています。
paradox形式のデータベース(拡張子.DB)のあるテーブルから
各列の型情報を取得するにはどうすればよいかと悩んでいます。
手動であれば、SQL Explorerで該当テーブルを開くと
以下のような型情報を取得できます。
名前 | Type | Size | Scale | Physical Length
--------------------------------------------------------
フィールド1 | SHORT | | | 2
フィールド2 | ALPHA | 20 | | 20
この情報を手で書き写しても良いのですが、テーブル数が多いため、
できればプログラムで処理できないかと考えています。
プログラム(Delphiもしくは他の言語で)からこれらの取得するには、
どのようなコードを書けばよいでしょうか。
ちなみに、以下の事は試しています
・Paradoxのエクスポート機能でschファイルを出力
→型情報取得可能。ただし、複数テーブルの型情報を
一括エクスポートができないため時間がかかる。
・ADO(Jet)経由でスキーマ情報の読み込み
→型情報は取得できず。
不明な点などあれば指摘お願いします。
よろしくお願いします。
BDE でも dbGo でも IBX でも DBX4 でも似たような感じでフィールド定義は取得できます。
以下は Paradox 形式ファイルのフィールド定義取得コードです。
uses
... , DB, DBTables;
procedure TForm1.Button1Click(Sender: TObject);
var
Table: TTable;
i: Integer;
dFieldName: string;
dFieldType: TFieldType;
dFieldSize: Integer;
begin
Memo1.Lines.Clear;
Table := TTable.Create(nil);
try
Table.TableName := 'animals.dbf';
Table.Open;
for i:=0 to Table.FieldCount-1 do
begin
// フィールド名
dFieldName := Table.Fields[i].FieldName;
// フィールドの型
dFieldType := Table.Fields[i].DataType;
// フィールドのサイズ
dFieldSize := Table.Fields[i].Size;
// TMemo に表示
Memo1.Lines.Add(Format('%s, %d, %d', [dFieldName, dFieldType, dFieldSize]));
end;
Table.Close;
finally
Table.Free;
end;
end;
誤: Memo1.Lines.Add(Format('%s, %d, %d', [dFieldName, dFieldType, dFieldSize]));
↓
正: Memo1.Lines.Add(Format('%s, %d, %d', [dFieldName, Integer(dFieldType), dFieldSize]));
Paradoxの管理ツールですが、フリーソフトとしてBDEManagerを作成しました。(Vectorに登録)
各データベースの管理に使用でき、フィールド定義表を紙に印刷できます。
機能として組み込みたい場合は、回答になりませんが?
>>DEKOさん
回答ありがとうございます。
今から試してみます。
>>かずさん
BDEManager使わせて頂きました。
今回はテキスト情報として書き出したいので、
ちょっと機能が異なるようです。
回答ありがとうございます。
DEKOさんの手法は、
Paradox型→Delphi型の変換後の型を出力するのですね。
参考になります。
この変換が1対1で対応していれば欲しい結果になるのですが、
結果から述べると1対他対応のものがあり、もう少し意見を頂きたいです。
Paradox型<->Delphi型の対応は以下となりました。
記号 | 項目型 | 対応Delphiクラス名 | サイズ取得
-----------------------------------------------------------
A | 文字型 | TWideStringField | ○
N | 実数型 | TFloatField | -
$ | 金額型 | TFloatField | -
S | 整数型 | TSmallintField | -
I | 倍長整数型 | TIntegerField | -
# | BCD 型 | TFloatField | -
D | 日付型 | TDateTimeField | -
T | 時間型 | TDateTimeField | -
@ | 日付時間型 | TDateTimeField | -
M | メモ型 | TMemoField | ×
F | 書式付きメモ型| ? | ?
G | グラフィック型| ? | ?
O | OLE 型 | TBlobField | -
L | 論理型 | TBooleanField | -
+ | カウンタ型 | TAutoIncField | -
B | バイナリ型 | ? | ?
Y | バイト型 | TVarBytesField | ○
※?は未確認
※記号/項目型…Paradox型情報
※サイズ…「○」で取得可能
結果、以下で1対他対応になってしまっていました。
a. 実数型(N),金額型($),BCD型(#)→TFloatField
b. 日付型(D),時間型(T),日付時間型(@)→TDateTimeField
以上の二組に関しても、峻別したいと考えています。
b.に関しては、出力データを見ると以下で表示されたので、
ある程度は判別可能なのかなと感じています。
日付型(D) →西暦/月/日
時間型(T) →1899/12/30 時間/分/秒
日付時間型(@)→西暦/月/日 時間/分/秒
a.に関しては、値域が重なるため判別が困難と感じています。
判別の方法はあるのでしょうか。
ここまで厳密に分ける必要があるのかなどの意見もあるかと
思いますが、必要性を感じています。
宜しくお願いします。
先述のコードをちょっと変更して...
Memo1.Lines.Add(Format('%s, %d, %d', [dFieldName, Integer(dFieldType), dFieldSize]));
↓
Memo1.Lines.Add(Format('%s, %s, %d', [dFieldName, DB.FieldTypeNames[dFieldType], dFieldSize]));
events.db を読み込ませると以下のように返ってきますが...?
EventNo, AutoInc, 0
VenueNo, Integer, 0
Event_Name, String, 30
Event_Date, Date, 0
Event_Time, Time, 0
Event_Description, Memo, 100
Ticket_price, Currency, 0
Event_Photo, Graphic, 0
# animals.dbf は dBASE 形式でしたね、スミマセン。
liml さんの結果は Paradox ファイルを ODBC 経由で接続した時の挙動に似ています。
[Paradox Data Types]
http://msdn.microsoft.com/ja-jp/library/windows/desktop/ms709362%28v=vs.85%29.aspx
本当に "私が提示したテストコードでの検証結果" ですか?
>本当に "私が提示したテストコードでの検証結果" ですか?
…そう言われると、自信がなくなってきました。
既存プロジェクトを一部変更してテストしたので、間違った可能性があります。
その既存プロジェクトは、TADOTableを利用したもので、ご指摘のとおり
の可能性が高いと感じています。
手元に環境がないので、いますぐは確認できないのですが、
また確認して報告させてもらいます。
# 認証キーが手元になく、異なる書込者IDになっています
> TADOTableを利用したもので、
dbGo(ADO)、或いは BDE でも ODBC 経由だと、先の URL にあったように、
型が別のものになってしまう事があります。
(BDE でも dBASE 形式は Float と Number を区別できなかった気がします)
折角ですので、Paradox / Database Desktop のフィールド定義表示準拠なコードを置いておきますね。
uses
... , StrUtils, DB, DBTables;
procedure TForm1.Button1Click(Sender: TObject);
const
ParadoxFieldTypeChars: array[TFieldType] of string = (
'' , 'A', 'S', 'I', '' , 'L', 'N', '$', '#', 'D',
'T', '@', 'Y', '' , '+', 'B', 'M', 'G', 'F', 'O',
'' , '' , '' , '' , '' , '' , '' , '' , '' , '' ,
'' , '' , '' , '' , '' , '' , '' , '');
ParadoxFieldTypeStrings: array[TFieldType] of string = (
'', 'Alpha', 'Short', 'Long Integer', '', 'Logical', 'Number', 'Money',
'BCD', 'Date', 'Time', 'TimeStamp', 'Bytes', '', 'AutoIncrement', 'Binary',
'Memo', 'Graphic', 'Formatted Memo', 'OLE', '', '', '', '', '', '', '', '',
'', '', '', '', '', '', '', '', '', '');
var
Table: TTable;
i: Integer;
dFieldName, dStrDataSize, dFieldTypeStr, dIndexField: string;
dFieldType: TFieldType;
dFieldNo, dFieldSize: Integer;
begin
Memo1.Lines.Clear;
Table := TTable.Create(nil);
try
Table.TableName := 'paradoxtest.db';
Table.Open;
for i:=0 to Table.FieldCount-1 do
begin
// フィールド No
dFieldNo := Table.Fields[i].FieldNo;
// フィールド名
dFieldName := Table.Fields[i].FieldName;
// フィールドの型
dFieldType := Table.Fields[i].DataType;
dFieldTypeStr := ParadoxFieldTypeChars[dFieldType];
// dFieldTypeStr := ParadoxFieldTypeStrings[dFieldType];
// フィールドのサイズ
dFieldSize := Table.Fields[i].Size;
dStrDataSize := ifthen(dFieldSize = 0, '', IntToStr(dFieldSize));
// インデックス
dIndexField := ifthen(Table.Fields[i].IsIndexField, '*', '');
// TMemo に表示
Memo1.Lines.Add(Format('%d, %s, %s, %s, %s', [dFieldNo, dFieldName, dFieldTypeStr, dStrDataSize, dIndexField]));
end;
Table.Close;
finally
Table.Free;
end;
end;
>折角ですので、Paradox / Database Desktop のフィールド定義表示準拠なコードを置いておきますね。
追加のコードありがとうございます。
再度プログラムを確認したところ、やはりTADOTableを使っていました。
# 確認が足りませんでした。すみません。
頂いたコードを試したところ、17個すべての型で所望の型情報を
取り出せました。
ご教授ありがとうございました!
ツイート | ![]() |