SWS
[ 上へ ] [ Visual C++ MDB その1 ] [ Visual C++ MDB その2 ] [ 本当の雑記帳 ]

●Visual C++におけるmdbファイルの扱いについて、その1

注)この記事はWindows98 + Visual C++(SP2)上のみで確認しています。

ふと思い立ち、mdbファイルを扱う実験をしてみようと思った。マニュアルを読んでみると、VCのクラスを使ってmdbファイルを扱うには2通りの方法があって一つはODBCドライバ経由、もう一つはDAOを使うとのことだった。だた、mdb形式の場合はDAOの方が高速らしいのでCDao***関連を使ってみようと思う。
*下記のサンプルでは例外処理は全く行っていない。データベース関連では例外処理は必ず必要なので、自分で確認していただきたい。

テーブル生成

CDaoDatabase db;
db.Create("Database");
CDaoTableDef table(&db);
table.Create("MyTable");
table.CreateField("ID", dbLong, 0);
table.CreateField("IDNAME", dbText, 255, dbVariableField);
table.CreateField("NAME", dbText, 255, dbVariableField);
table.CreateField("DATE", dbDate, 0);
table.Append();
db.Close();

テーブル生成は上記のような形でおこなう。CDaoDatabase::Createで作成するデータベース名を指定し、CDaoTableDef::Createでテーブル名を書く。実際のフィールドは、CDaoTableDef::CreateFieldで行い、最後にCDaoTableDef::Appendのコールする。すると、上記のサンプルの場合はカレントフォルダにDatabase.mdbというファイルが作成されるので、Access辺りで内容を確認して欲しい。CreateFieldで指定した、フィールド名、型、アトリビュートにしたがってデータベースが作成されているはずである。

データの追加

CDaoDatabase db;
db.Open("Database");
CDaoTableDef table(&db);
table.Open("Table");
CDaoRecordset rs(&db);
rs.Open(&table,dbOpenDynaset,0);
rs.AddNew();
COleVariantArray var;        // typedef CArray<COleVariant,COleVariant>    COleVariantArray;
var.SetSize(3);
CStringArray FieldArray;
FieldArray.Add("ID");
FieldArray.Add("IDNAME");
FieldArray.Add("DATE");
{
    CString s="001"; var[0] = s; var[0].ChangeType(VT_I4);
}
{
    CString s="データ"; var[1] = s; var[1].SetString(s, VT_BSTRT);
}
{
    CTime time( 1999, 8, 27, 0, 0, 0 ); COleDateTime dtm(time.GetTime()); var[2]=dtm;
}
for(int i=0;i<FieldArray.GetSize();i++){
rs.SetFieldValue(FieldArray[i],var[i]);
}
rs.Update();
rs.Close();
db.Close();

上記のサンプルでは、IDに1を、IDNAMEにデータ、DATEに1999年8月27日というデータを追加している。ソースを上から見てみると、まず最初にCDaoRecordset::Openでカレントの"Database.mdb"というファイルをオープンする。次にCDaoTableDef::Openでテーブル"Table"を開く。CDaoRecordset::OpenにてダイナセットでレコードをオープンしAddNewで追加準備に入る。実際に値をセットするのはCDaoRecordset::SetFieldValueである。最後にアップデートを行い(Update)追加完了である。正常にデータが追加されたかどうかをAccess等でチェックしていただきたい。

クエリー発行(検索)
mdbのレコードセットではSQLを直接発行することが出来る。下記のソースは検索の例です。

CDaoDatabase db;
db.Open("Database");
CString strquery = "select * from Table";
CDaoRecordset rs(&db);
rs.Open(dbOpenSnapshot,strquery, dbReadOnly);
int nFields = 0;
// レコード件数を取得するために最後のレコードに移動
if (!rs.IsBOF()) {
    rs.MoveLast();
}   
nFields = rs.GetAbsolutePosition() + 1;
COleVariantArray var;
var.SetSize(1);
// 最初のレコードに移動
rs.MoveFirst();
for(int i=0;i<nFields;i++){
    rs.GetFieldValue( _T("IDNAME"), var[0] );
    CString sStr = V_BSTRT(&(var[0]));
    AfxMessageBox(sStr);
}
rs.Close();
db.Close();

データベースやテーブルを開くのは追加のときと同様です。レコードセットを開くときにSQL文を指定し、スナップショットで開く。すると、GetFieldValue等のメソッドでレコードの値が入手できます。例では、全レコードのIDNAMEの値をメッセージボックスで表示しいる。ここでミソなのが、レコードの件数を調べるためにMoveListでデータベースの最後に移動するところ。こうしておいてからGetAbsolutePositionをコールし現状の位置を調べることにより、全レコードの件数を調べることができるのです。あとは、先頭に戻り順々にナメテいくだけです。