Access のデータを VCのコンボボックスに表示 – プログラミング – Home

Access のデータを VCのコンボ...
 
通知
すべてクリア

[解決済] Access のデータを VCのコンボボックスに表示

固定ページ 1 / 2

こまったちゃん
 こまったちゃん
(@こまったちゃん)
ゲスト
結合: 18年前
投稿: 39
Topic starter  

■動作環境 :WindowsXP
■開発環境 :Visual C++6.0
■データベース:Access2000(ADO接続)

お世話になります。
Access2000で作成した ファイル名db1.mdbにある
社員マスタをVCのコンボボックスに表示させようとしています。

コンボボックスをダブルクリックして出来た関数の中でADOを介して
Accessに接続はしているのですがファイルへの接続方法以降
が分かりません。アドバイス助言よろしくお願い致します。

void CAppointmentDlg::OnEditchangeCombo1()
{
CAdoOperation AD; // ADOでアクセスを制御するクラスを AD で実
体化
AD.ConnectOpen(); // DBのコネクトを開く
}

/******************* ConnectOpen()の中身 *********************/
/ m_strProvider は以下をセット済み↓
/
/ Provider=Microsoft.Jet.OLEDB.4.0;Data Source = C:\\temp1\\db1.mdb; /
/
****************************************************************/
bool CAdoOperation::ConnectOpen()
{
try {
// COMの初期化処理
::CoInitialize(NULL);

// ADOオブジェクトの生成
m_pConnect.CreateInstance(__uuidof(Connection));
m_pCommand.CreateInstance(__uuidof(Command));
m_pRecordset.CreateInstance(__uuidof(Recordset));

// データベースへの接続
m_pConnect->Mode = adModeReadWrite;
m_pConnect->Open(m_strProvider, L", L", adConnectUnspecified);
}
catch(_com_error &e){
AfxMessageBox(e.Description());
return FALSE; // 失敗
}
return TRUE; // 成功
}
/******* Accessのテーブル 社員マスタの中身 ******************/

社員番号 氏名
001 田中
002 佐藤
003 井上

これをVCのコンボボックスに表示させようとしています。


引用未解決
トピックタグ
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

社員マスタのなにをコンボボックスに表示させるのでしょうか?
社員番号?氏名?

どちらにせよ、SELECT文をつかって、Recordsetを取得しなければ始まりませんが。
(m_pConnectのExecuteメソッドで取得できるはず。)


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

もしかして、
http://pegalabo.net/archives/VC/source/AdoOperation_cpp.html
を参考にされていますか?
そうでしたら、引用元を載せないとまずいですよ。


返信引用
こまったちゃん
 こまったちゃん
(@こまったちゃん)
ゲスト
結合: 18年前
投稿: 39
Topic starter  

Blueさんありがとうございます。
コンボボックスには社員名を表示させようとしています。

<<m_pConnectのExecuteメソッドで取得できるはず
調べてみます。


返信引用
こまったちゃん
 こまったちゃん
(@こまったちゃん)
ゲスト
結合: 18年前
投稿: 39
Topic starter  

こちらのHPを参考にしています。
http://pegalabo.net/archives/VC/source/AdoOperation_cpp.html

Executeを調べてみたのですが、詳しく載ってる箇所が見つからず
理解不十分なので参考になるHPがあればどなたか教えて下さい。

重ねて _bstr_t, _variant_t を調べたのですが
_bstr_tは  COMで文字列を使用する時に使うもの?
http://72.14.253.104/search?q=cache:C9-UEwZN19cJ:luvtechno.net/h/%3FVC%252B%
252B%25A4%25C7%25CA%25B8%25BB%25FA%25CE%
25F3+SysAllocString&hl=ja&gl=jp&ct=clnk&cd=4&lr=lang_ja

_variant_tは DBの値を取得するもの?
http://72.14.235.104/search?
q=cache:y9RWwzW17PEJ:hp.vector.co.jp/authors/VA014436/prg_memo/database/ms/009.
html+_variant_t&hl=ja&gl=jp&ct=clnk&cd=4

こんな理解では不安なので、アドバイスお願い致します。

Execute文も情報が少なく第一引数がSQL文とゆう事が分かったぐらいで
上記の絡みもあり第二,第三引数の意味が分かりませんでした・・・

中途半端な理解ですが下記の関数を作成したました。
/***************** ConnectOpen()の中身 *****************/
/ CString TableName は以下をセット済み    /
/ SELECT * FROM 社員マスタ                  /
/*************************************************************/
CString TableName
bool CAdoOperation::ComboSet(const CString TableName)
{
_bstr_t bstrQuery(TableName); // _bstr_t オブ
ジェクトに文字列を代入します。
_variant_t vRecsAffected(0L);
m_pRecordset = m_pConnect->Execute(bstrQuery, &vRecsAffected,
adOptionUnspecified);

while(!m_pRecordset->GetadoEOF())
 {

 }

return true;
}

コンパイル時に 'GetadoEOF' : '_Recordset' のメンバではありません。
が出てしまいます。
理由が分かりません誰か分かる方がいまいしたらよろしくお願い致します。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

> http://pegalabo.net/archives/VC/source/AdoOperation_cpp.html
  ↑
  このHP方法はADOオブジェクトを直接扱う方法でODBC初心者には難しいです。

 ADOにこだわるならMFCの「CAdoDatabase」、
こだわらないのなら「CRecordset」を薦めます。
それならもっと詳しいHPが「GooGle」で検索すれば多く見つかるはずですし、
VC6.0付属のMSDNのCDでも十分だと思います。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

>ADOにこだわるならMFCの「CAdoDatabase」、
は CDaoDatabase で DAOなのでは?(≒ADO)

>こだわらないのなら「CRecordset」を薦めます。
は ODBC です。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

間違えました。
>は CDaoDatabase で DAOなのでは?(≒ADO)
は CDaoDatabase で DAOなのでは?(≠ADO)


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

> _variant_t vRecsAffected(0L);
> m_pRecordset = m_pConnect->Execute(bstrQuery, &vRecsAffected,
> adOptionUnspecified);

m_pRecordset = m_pConnect->Execute(bstrQuery, NULL, adCmdText);

ではどうでしょうか?


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

一応試してみた。
ちゃんと、田中 佐藤 井上 という結果が得られました。

#include <windows.h>
#include <comdef.h>
#include <iostream>
#import C:\Program Files\Common Files\System\ADO\msado15.dll rename
( EOF, adoEOF )

HRESULT Test()
{
HRESULT hr = S_OK;

ADODB::_ConnectionPtr pConn = NULL;
ADODB::_RecordsetPtr pRec = NULL;

try
{
hr = pConn.CreateInstance( __uuidof( ADODB::Connection ) );
if ( FAILED( hr ) ) _com_issue_error( hr );

pConn->Mode = ADODB::adModeReadWrite;
pConn->Open( LProvider=Microsoft.Jet.OLEDB.4.0;Data Source=db1.mdb,
L", L", ADODB::adConnectUnspecified );

pRec = pConn->Execute( LSELECT 氏名 FROM 社員マスタ,
NULL, ADODB::adCmdText );

ADODB::FieldsPtr pFields;
ADODB::FieldPtr pField;
while ( pRec->GetadoEOF() != VARIANT_TRUE )
{
pFields = pRec->Fields;
pField = pFields->Item[ 0L ];

_bstr_t value( pField->Value.bstrVal );
printf( %s\n, ( const char* )value );

pRec->MoveNext();
}
pRec->Close();
pConn->Close();
}
catch ( _com_error& e )
{
hr = e.Error();
}

if ( pConn ) pConn.Release();
if ( pRec ) pRec.Release();

return hr;
}

int main()
{
if ( SUCCEEDED( ::CoInitialize( NULL ) ) )
{
Test();
::CoUninitialize();
}
return 0;
}


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

連投ですが、
> if ( pRec ) pRec.Release();
はいらないでした。
それと、
> ADODB::_RecordsetPtr pRec = NULL;
もtryブロックの中に入れてしまうほうがよかったです。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

> CDaoDatabase で DAOなのでは?(≒ADO)
そうですね、間違ってました。
>>こだわらないのなら「CRecordset」を薦めます。
>は ODBC です。
そうです、ODBCです。
「CRecordset」のほうが資料が多いし分りやすいと思いました。


返信引用
こまったちゃん
 こまったちゃん
(@こまったちゃん)
ゲスト
結合: 18年前
投稿: 39
Topic starter  

アドバイスありがとうございます。
教えて頂いたプログラムで不明点がありましたので教えて下さい。

コンパイル時に 'GetadoEOF' : '_Recordset' のメンバではありません。
は Blueさんと同じのを import しましたら解決しました。

下記の3点が不明です。

1. FieldsPtr, FieldPtrはCOMの時に使うのでしょうか?
webで調べても詳しく載っていないので分かりませんでした。
みなさんはこのようなポインタの知識はどこで身に付けられるのでしょうか?
(_ConnectionPtr, _CommandPtr, m_pRecordset これらのメンバー関数などの知識も)

2. pFields->Item[ 0L ];ここで 田中 佐藤 井上のあるアドレス
をpFieldをセットしていると思ってるのですが0Lが分かりません。
(DBの場所もアドレスと表現していいのか分かりません)

3. データベースから値を取得しているのですが エディットボックス には反映
  されないので調べて下記を参考にして SetWindowText を使用しました。
  http://72.14.235.104/search?q=cache:El-6x1_LPnMJ:www.oct-
net.ne.jp/~monmon_d/win32api/setwindowtext.html+SetWindowText()
&hl=ja&gl=jp&ct=clnk&cd=9&lr=lang_ja
  結果はエラーが3つ出ました。
  1.SetWindowTextA' : 1 番目の引数を 'const int' から 'struct HWND__ *' に変換
できません。
2.文字 '0x81' は認識できません。
3.文字 '0x40' は認識できません。
1番目の引数は IDC_COMBO2 はコンボボックスのIDです。
  ウィンドウまたはコントロールのハンドル・・・
  恥ずかしい事にハンドルを理解できていません。

 別のやり方でやるべきなのでしょうか。アドバイスよろしくお願い致します。

FieldsPtr pFields;
FieldPtr pField;

// データがなくなるまでループ
while ( m_pRecordset->GetadoEOF() != VARIANT_TRUE )
{
// データ取得
pFields = m_pRecordset->Fields;
pField = pFields->Item[ 0L ];

_bstr_t value( pField->Value.bstrVal );
     SetWindowText(IDC_COMBO2, value);
printf( %s\n, ( const char* )value );

m_pRecordset->MoveNext(); //カーソルを次のレコードに移動
}


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

> SetWindowText(IDC_COMBO2, value);
コンボボックスに追加するんじゃないの?
というか、MFCにおいてダイアログコントロールを操作するのは基本中の基本だと思
うのですが。(COMとか云々とかいえるレベルじゃない)

SetDlgItemTextを使ってください。(ただし、ループで上書きされますが。)

コンボボックスのリストに追加したいならば、
GetDlgItemでコンボボックスを取得して、AddStringで追加してください。

> 2.文字 '0x81' は認識できません。
> 3.文字 '0x40' は認識できません。
全角空白はいっていますよね?(この程度のエラーは調べてもらいたいが。)

> 2. pFields->Item[ 0L ];ここで 田中 佐藤 井上のあるアドレス
> をpFieldをセットしていると思ってるのですが0Lが分かりません。
アドレスではありません。
0L は単なる 0 の long型です。(末尾に L をつけることでlong型になる)
SELECT文の結果の1カラム目の結果を取得しているだけです。


返信引用
こまったちゃん
 こまったちゃん
(@こまったちゃん)
ゲスト
結合: 18年前
投稿: 39
Topic starter  

>コンボボックスに追加するんじゃないの?
その通りです間違えていました。申し訳ありません。

猫を参考にしてやったのですが
http://72.14.235.104/search?
q=cache:xNgyNHBZs5AJ:www.kumei.ne.jp/c_lang/mfc/mfc_14.htm+AddString&hl=ja&gl=j
p&ct=clnk&cd=1

GetDlgItem を調べた結果
 1. HWND GetDlgItem( int nIDDlgItem )
 ダイアログクラスのメンバ関数内でのみ使用可。
 2. HWND GetDlgItem(HWND hDlg , int nIDDlgItem)
 ダイアログクラスのメンバ関数外での場合使用。

とゆう事が分かったので、ダイアログクラスのメンバ関数内でコンボボックスの
ハンドルを取得して
hWnd = ( HWND* )GetDlgItem(IDC_COMBO2); hWnd を引数にしたのですが
ComboSet の中の pCombo = (CComboBox *)GetDlgItem(*hWnd, IDC_COMBO2);
で失敗してしまいます。

原因は GetDlgItem(*hWnd, IDC_COMBO2) の *hWnd で アドレスでなく
指し示す場所の値を渡してるからだと思うのですが・・・
回避方法が分かりません。よろしくお願い致します。

<プログラム (多少使用の変更しました)>
BOOL CAppointmentDlg::OnInitDialog()
{
 HWND* hWnd;
 AD.SetProvider(); // プロバイダー情報設定
 AD.ConnectOpen(); // DBのコネクトを開く
 CString TableName = SELECT 氏名 FROM 社員マスタ;
 // IDC_COMBO2 のハンドルを取得
 hWnd = ( HWND* )GetDlgItem(IDC_COMBO2);
 AD.ComboSet(TableName, hWnd);
}

ComboSet関数では下記のように受け取りました。
bool CAdoOperation::ComboSet(const CString TableName, HWND* hWnd)
{
 // 変数の宣言及び初期化
 HRESULT hr = S_OK;
 CComboBox *pCombo;

 _bstr_t bstrQuery(TableName);
 m_pRecordset = m_pConnect->Execute(bstrQuery, NULL, adCmdText);

 try
 {
  FieldsPtr pFields;
  FieldPtr pField;
 
   // データがなくなるまでループ
   while ( m_pRecordset->GetadoEOF() != VARIANT_TRUE )
   {
    // データ取得
    pFields = m_pRecordset->Fields;
    pField = pFields->Item[ 0L ];

    _bstr_t value( pField->Value.bstrVal );

    // この GetDlgItem で失敗する
    pCombo = (CComboBox *)GetDlgItem(*hWnd, IDC_COMBO2);
    pCombo->AddString(value);

    m_pRecordset->MoveNext(); //カーソルを次のレコードに移動
   }
   m_pRecordset->Close();
   m_pConnect->Close();
}
catch ( _com_error& e )
  {
   hr = e.Error();
   return false;
  }
  if ( m_pConnect ) m_pConnect.Release();
  return true;
}


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました