
*-- To Tell The Truth --*
Cruz
MAIL
HOME
|
 |
2001年12月25日(火) ■ |
 |
独自レコードセット作成 |
 |
今日は仕事。
半日かけてあれこれ悩んだ挙句、やはりMFCは断念。 とてもじゃないが、今日明日でできると思えなかったので。 うまく使えると簡単そうなんだけどなぁ。
・・で、SDK+ADOで作っていたプロトタイプにメスを入れる。 例のvariant型対策だ。
◆本に出ている方法 (LPCTSTR)_bstr_t(m_Rec->GetCollect(L"カラム名")));
GetCollectで取ってきた値をダイレクト(?)にBSTRにして、LPCTSTRにキャストしているんだけど、なんか上手く変換できていないんだよねぇ。
◆ネット&MSDNで発見した方法 _variant_t vStr; vStr = m_Rec->GetCollect(L"カラム名"); vStr.ChangeType(VT_BSTR); vStr.bstrVal ← に変換済み(?)文字列が入る
1つ1つデバックで値確認はできるんだけど、なぜかvStr.bstrValを(char *)でキャストして使用しようとすると、1文字目しかないんだよね。 vStr.bstrValそのものを覗いても、1文字分しかないし・・・。 ビミョーに使用方法を間違っているだけのような気もするんだけど??
◆独自レコードセット作成 詳しくはこちらとMSDNのADO VC++エクステンションの使用を参考にするとわかる。
SDKで書いているものの・・・レコードセットクラスとして、GenericクラスでCADORecordBindingを作成した。 connectしたりselectするクラスにしっかりインクルードさせて。
#define INITGUID // ADO使用 #import "C:\program files\common files\system\ado\msado15.dll" \ no_namespace \ rename( "EOF", "adoEOF") #include
class CRecordSet : public CADORecordBinding { // レコードセット設定マクロ BEGIN_ADO_BINDING(CRecordSet) ADO_FIXED_LENGTH_ENTRY(1, adChar, stFdsData.cpCardNo, lau_lCardNoStatus, FALSE) ADO_FIXED_LENGTH_ENTRY(2, adChar, stFdsData.cpRiyouYMD, lau_lRiyouYMDStatus, FALSE) ADO_FIXED_LENGTH_ENTRY(3, adInteger, stFdsData.iRiyouAmt, lau_lRiyouAmtStatus, FALSE) END_ADO_BINDING() public: USERDATA stData; ULONG lau_lCardNoStatus; ULONG lau_lRiyouYMDStatus; ULONG lau_lRiyouAmtStatus; };
ここまでが、独自レコードセットクラス 次は、使用しているconnectやらselectをするクラス
#include "RecordSet.h" // 独自レコードセット #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000
class CADODataAccess { public: CADODataAccess(); virtual ~CADODataAccess();
BOOL SelectListADO(HWND hList); private: _ConnectionPtr m_pConnect; // Connectionオブジェクト _CommandPtr m_pCommand; // Commandオブジェクト _RecordsetPtr m_pRecordset; // Recordsetオブジェクト
CRecordSet m_rsRecSet; // FDS RecSetオブジェクト
void SetSelect(); // Select文生成 void DisplayList(HWND hList); // 検索結果リスト表示 };
これで準備完了。次に使用しているところ。
BOOL CADODataAccess::SelectListADO(HWND hList) { HRESULT hr; IADORecordBinding *picRs = NULL;
// COMの初期化処理 ::CoInitialize(NULL);
// ADOオブジェクトの生成 m_pConnect.CreateInstance(__uuidof(Connection)); m_pCommand.CreateInstance(__uuidof(Command)); m_pRecordset.CreateInstance(__uuidof(Recordset));
// データベースへの接続 hr = m_pConnect->Open( _bstr_t(DB2_NAME), _bstr_t(DB2_USERID), _bstr_t(DB2_PASSWD), adConnectUnspecified);
if(SUCCEEDED(hr)){ // SQLの設定 m_pCommand->ActiveConnection = m_pConnect; SetSelect(); m_pRecordset->PutRefSource(m_pCommand);
// レコードセットの取得 _variant_t vNull; // VARIANT型のNULLとして使う vNull.vt = VT_ERROR; vNull.scode = DISP_E_PARAMNOTFOUND; m_pRecordset->Open(vNull, vNull, adOpenStatic, adLockReadOnly, adCmdText);
// レコードのバインドを行うインターフェイスポインタ取得 if(FAILED(m_pRecordset->QueryInterface(__uuidof(IADORecordBinding), (LPVOID*)&picRs))){ _com_issue_error(E_NOINTERFACE); } picRs->BindToRecordset(&m_rsRecSet);
// 検索結果件数 if(m_pRecordset->GetRecordCount() <= 0){ return FALSE; }
// 先頭レコードへ移動し、フィールドの値を取得 m_pRecordset->MoveFirst(); DisplayList(hList);
}else{ return FALSE; } return TRUE; }
void CADODataAccess::DisplayList(HWND hList) { LV_ITEM lvitem; int i = 0; int iSubItemCount = 0; long lRecCount = 0;
lRecCount = m_pRecordset->GetRecordCount();
// リストビュー画面のクリア ListView_DeleteAllItems(hList);
// List Data lvitem.mask = LVIF_TEXT | LVIF_IMAGE;
for(i = 0; i < lRecCount; i++){
// CardNo lvitem.pszText = m_rsRecSet.stData.cpCardNo; lvitem.iItem = i; lvitem.iSubItem = iSubItemCount; ListView_InsertItem(hList, &lvitem);
iSubItemCount++;
// 利用日時 lvitem.pszText = m_rsRecSet.stData.cpRiyouYMD; lvitem.iItem = i; lvitem.iSubItem = iSubItemCount; ListView_SetItem(hList, &lvitem);
iSubItemCount++;
// 利用金額 sprintf(lvitem.pszText, "%d", m_rsRecSet.stData.iRiyouAmt); lvitem.iItem = i; lvitem.iSubItem = iSubItemCount; ListView_SetItem(hList, &lvitem);
iSubItemCount = 0; m_pRecordset->MoveNext(); }
}
以上
これでもまだ、文字化けしているんだよなぁ。 ただ、int型はバッチリできれてるので、もしやテーブルの方の問題か?
ちなみに、connectなんかをする場合は、きちんとするならtryを使用しましょう。 これはプロトタイプです。
|
|