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

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

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

その1ではレアにmdbを指定しレコードセットの操作も手作業的におこなったが、通常このようなときはCDaoRecordsetを専用に派生させて使うらしい。たまたま簡単なSDIプロジェクトが転がっていたので、派生させてみた(笑)。

▼CDaoRecordsetの派生クラス作成
通常通りクラスウィザードでMFCの派生クラスとして作成する。

mdb1.jpg (32230 バイト)

OKすると以下のようにデータソースを入れる画面になります。ここで、その1で作成したmdbファイルを指定する。次にテーブル名を聞いてくるので、適当に選択します。

mdb2.jpg (23984 バイト)

mdb3.jpg (12278 バイト)

これでOK!!専用のレコードセットクラスが完成しました。

▼ソースファイルを見てみてみる

・TestRecSet.h

// フィールド/パラメータ データ
    //{{AFX_FIELD(CTestRecSet, CDaoRecordset)
    long    m_ID;
    CString    m_IDNAME;
    CString    m_NAME;
    COleDateTime    m_DATE;
//}}AFX_FIELD

このような形で、データベースのフィールドにしたがった変数が自動的に定義されています。

・TestRecSet.h

CTestRecSet::CTestRecSet(CDaoDatabase* pdb)
    : CDaoRecordset(pdb)
{
    //{{AFX_FIELD_INIT(CTestRecSet)
    m_ID = 0;
    m_IDNAME = _T("");
    m_NAME = _T("");
    m_DATE = (DATE)0;
    m_nFields = 4;
    //}}AFX_FIELD_INIT
    m_nDefaultType = dbOpenDynaset;
}

コンストラクタで、初期化しているようです。

CString CTestRecSet::GetDefaultDBName()
{
    return _T("D:\\Database\\Database.mdb");
}

ここで、mdbファイル名の指定をしています。きっと仮想関数なんでしょう。mdbファイル自身を移動させたいときは、ここのパスを変えれば良いのでは無いかと思われます。

CString CTestRecSet::GetDefaultSQL()
{
    return _T("[Table]");
}

そしてテーブル名がこれです。うまくできていますね。今回は元のプロジェクトを作成する際にデータベース関連のオプションをすべてOFFにして作成しました。このままですと、コンパイル時にDAO関連が無いといってこけてしまいます。stdafx.h#include <afxdao.h>を追加しましょう。

▼テーブルの変更時は?
ここで一つ疑問がわいてきます。データベースのフィールド定義にに変更があったときはどうするのか?ありがちですよね、途中にフィールドを追加することとか。ちょっと試してみましょう。Databse.mdbにNEWDATA(dbText型)を追加してみます。この作業はAccess辺りで簡単に出来ますね。さて、プロジェクト側です。クラスウィザードの変数タブに"列の更新"というボタンがあると思います。これを押してみると、

mdb2.jpg (23984 バイト)

先ほども出てきたデータベースのオプションダイアログが出てきますね。ここで、再びmdbファイルを指定してOKすると、

mdb4.jpg (42391 バイト)

のように自動的に変数が追加されます。ここで、"すべてバインド"ボタンを押下と、メンバ変数を定義してくれます。

mdb5.jpg (42085 バイト)

本当に追加されたかどうかをソースの中身を見てチェックしてみましょう。

・TestRecSet.h

    //{{AFX_FIELD(CTestRecSet, CDaoRecordset)
    long    m_ID;
    CString    m_IDNAME;
    CString    m_NAME;
    COleDateTime    m_DATE;
    CString    m_NEWDATA;
    //}}AFX_FIELD

確かに、m_NEWDATAが追加されています。

・TestRecSet.cpp

    //{{AFX_FIELD_INIT(CTestRecSet)
    m_ID = 0;
    m_IDNAME = _T("");
    m_NAME = _T("");
    m_DATE = (DATE)0;
    m_NEWDATA = _T("");
    m_nFields = 5;
    //}}AFX_FIELD_INIT

こちらもばっちりです。やるなゲ●ツ!!青い画面ばかり出してるわけじゃないんだな。というわけで、データベースのフィールド追加、削除などをおこなったときも、プロジェクト側で簡単に変数定義を変更することができます(削除時は同様の手順で、バインドする前に"変数の削除"をおこなえばOK)。これで安心してレコード操作の実験に入れます。。。では、今回はこの辺で。