■動作環境 : WindowsNT4.0
■開発環境 :Visual C++6.0(SDI形式)
■データベース:Access2000(ODBC接続)
質問します。
[ファイル]:???View.cpp
[ク ラ ス]:void C???View::OnInitialUpdate()
// レコードを開く(双方向非同期,データソース名,読取専用)
レコードセット.Open(CRecordset::snapshot,データソース,CRecordset::readOnly);
あらかじめAccessで作成したMDBをODBCのデータソースに設定した上で、
レコードを操作しようとしているのですが、これを実行させると
データソースの指定を求めるダイアログが現れます。
そこで該当するMDBファイルを指定してOKすると
「パラメータが少な過ぎます。3を指定して下さい。」という警告ダイアログが出ます。
これは一体何のパラメータが少ないと言っているのでしょうか?
また、ODBCの設定時にデータソース(MDBファイル)を指定したはずなのに、
再度実行時に聞かれるのはどういう事でしょうか?
宜しくお願いします。
> // レコードを開く(双方向非同期,データソース名,読取専用)
> レコードセット.Open(CRecordset::snapshot,データソース,CRecordset::readOnly);
レコードセットのOpen関数の第2パラメータは、SQL文字列ですよ。
お世話になっております。
MicrosoftのHPにある MSDNライブラリ の中に
MFCの関数一覧があるんですが、そこを参考にしました。
http://www.microsoft.com/japan/developer/library/default.asp?
URL=/japan/developer/library/vcmfc/_mfc_crecordset.3a3a.open.htm
これによると、CRecordset::Open の引数っていうのは
CRecordset::Open(オープン形式,文字列へのポインタ,オプション)
それで第二引数の 文字列へのポインタ は、
・NULL
・テーブル名
・SQL文
・組込みクエリの名前を指定するCALL文
のいづれかになっていたので、テーブル名(データソース)を入れたのですが。
間違っているんでしょうかね?
なるほど、テーブル名も可能なのですね。
しかし、テーブル名とデータソース名は違います。
テーブル名は、mdbの中にあるテーブルの名前です。
データソースが固定ならば、クラスウィザードで
CRecordsetの派生クラスを作れば勝手にデータソースと関連付けてくれます。
データソースが可変の場合は、
先にCDatabaseをOpenし(このときにデータソースを指定)、
CRecordsetのコンストラクタにそれを渡す必要があります。
CDatabaseがデータソースを表すクラスで、
CRecordsetは検索結果一覧を表すクラスです。
お世話になりまする。
そうですね、テーブル名とデータソース名を勘違いしていたかも知れません。
ですがテーブル名に変更したら、警告メッセージの内容が変わりました。
「パラメータが少な過ぎます。14を指定して下さい。」という警告ダイアログが出ます。
前は 3 で今度は 14 。一体何を指している数字なのでしょうか?
ちなみに、CRecordset型のクラスは ClassWizard で既に追加しています。
ただ、CRecordset.cpp にも CRecordset.h にもデータソース名は記載されてませんでした。
この状態でもちゃんと関連付けがなされているのでしょうかね?
今はデータソースは一個だけで固定です。
う~ん。
以下はOKですか?
・追加したクラスのGetDefaultConnectが返すデータソース名
・同じくGetDefaultSQLが返すテーブル名
・上記テーブル名と開こうとしているテーブルが一致しているか
お世話になっておりまする。
追加したクラス(CXxxRecordset)の内容はこうです。
CString CXxxRecordset::GetDefaultConnect()
{
return _T(ODBC;DSN=);
}
CString CXxxRecordset::GetDefaultSQL()
{
return _T(");
}
なぜか DSN も _T も空白でした。
DSN = データソースファイル名
_T = 開きたいテーブル名
を設定してやってみます。
ありがとうございました。
残念ながら解決とは行きませんでした。
それぞれに値を入れて実行してみましたが、
「データソース名および指定された既定のドライバが見つかりません。」となります。
データソース名、データソース名.dsnの両方試しましたが、駄目でした。
ファイルをVC++のプロジェクトのあるフォルダ(Debug)に入れてみましたが結果は同様でした。
もう後はどこをチェックすればいいのか、分からなくなってきました。
>CString CXxxRecordset::GetDefaultConnect()
>{
> return _T(ODBC;DSN=);
return _T(ODBC;DSN=MS Access Database);
>}
>CString CXxxRecordset::GetDefaultSQL()
>{
> return _T(");
return _T([テーブル名]);
>}
では?
追加です
ファイル名も指定できます。
>return _T(ODBC;DSN=MS Access Database);
return _T(ODBC;DSN=MS Access Database;DBQ=データベース.mdb);
お世話になります。
テーブル名を[]で閉じるってところで、これかなと思いましたが駄目でした。
データソース名、ファイル名も試しました。
「データソース名および指定された既定のドライバが見つかりません。」
のダイアログが表示されるままです。なかなか難しいですね。
私も色々試しているのですが・・・。
>レコードセット.Open(CRecordset::snapshot,データソース,CRecordset::readOnly);
レコードセット.Open(CRecordset::snapshot,NULL,CRecordset::readOnly);
これでも駄目です?
実際にどのようなコードを書いてますか?
一度、記述したコードを全部ここに載せますね。ひょっとしたら私の気づいていない
基本的な穴が空いているかも知れませんし。
まずは、ClassWizardで作成したCRecordsetのクラスです。
Xxxはプロジェクトの名前が入ります。
------------------------------------------
■ファイル名:XxxRecordset.cpp
CString CXxxRecordset::GetDefaultConnect()
{
return _T(ODBC;DSN=MS Access Database;DBQ=XxxDataSource.mdb);
}
CString CXxxRecordset::GetDefaultSQL()
{
return _T([TableName]);
}
------------------------------------------
■ファイル名:XxxView.cpp
void CXxxtView::OnInitialUpdate()
{
CFormView::OnInitialUpdate();
GetParentFrame()->RecalcLayout();
ResizeParentToFit();
// ここから
// 文字列型OBJを宣言
CString string_CS;
// レコードセット型OBJを宣言
CXxxRecordset record_RS;
// コントロールのポインタを宣言
CComboBox* ComboBox_ctrl;
// コントロール(IDC_COMBO_AP)を取得してポインタに設定
ComboBox_ctrl = (CComboBox*)GetDlgItem(IDC_COMBO_AP);
// テーブルを開く(双方向非同期,データソース,読取専用)
record_RS.Open(CRecordset::snapshot,[LANGUAGE],CRecordset::readOnly);
// 先頭レコードに移動
record_RS.MoveFirst();
// レコードの終端までループ
while(record_RS.IsEOF() == 0)
{
// カレントレコードを文字列型OBJに取得
record_RS.GetFieldValue([TableName],string_CS);
// 文字列型OBJからコントロール(IDC_COMBO_AP)にレコードを追加
ComboBox_ctrl ->AddString(string_CS);
// 次レコードに移動
record_RS.MoveNext();
}
// テーブルを閉じる
record_RS.Close();
// ここまで
------------------------------------------
これで記述は全部です。
フォームの表示と同時に、テーブルからレコードを読み込んでコンボボックスに
追加しています。レコードの終端まで追加したら終わりです。
宜しくお願いします。
先ほどの、
record_RS.Open(CRecordset::snapshot,NULL,CRecordset::readOnly);
これもやりましたけど、同じ警告メッセージですね。
※コード全文のところで、訂正です。
// テーブルを開く(双方向非同期,データソース,読取専用)
record_RS.Open(CRecordset::snapshot,[LANGUAGE],CRecordset::readOnly);
↓
record_RS.Open(CRecordset::snapshot,[TableName],CRecordset::readOnly);
が正解です。[LANGUAGE]と[TableName]は、[TableName]で統一は取れています。
そこの相違が原因ではないです。