Visual C++ ユーザーのための ADO マニュアルの読み方

「ADO API リファレンス」では、Microsoft Visual Basic に似た構文を使用して ADO アプリケーション プログラミング インターフェイス (API) の機能を説明します。あらゆるユーザーを対象に書かれたマニュアルですが、ADO プログラマが利用する言語は、Visual Basic、Visual C++ (#import ディレクティブ付きとなし)、Visual J++ (ADO/WFC クラス パッケージ付き) などさまざまです。

この多様性に対応するため、「Microsoft Visual C++ での ADO の使用」では、「ADO API リファレンス」での、機能、パラメータ、例外処理などの共通の説明にリンクした Visual C++ 言語固有の構文を用意しました。

ADO は COM (コンポーネント オブジェクト モデル) インターフェイスで実装されています。ただし、プログラマにとって、COM はほかのどの言語よりも使い慣れた言語で処理する方が容易です。たとえば、Visual Basic プログラマの場合、COM のほとんどすべては暗黙的に処理されますが、Visual C++ プログラマの場合は自分で処理しなくてはなりません。

次のトピックでは、ADO と #import ディレクティブを使う C プログラマと C++ プログラマのために使用方法の概要を説明します。COM (VariantBSTRSafeArray) に固有のデータ型とエラー処理 (_com_error) を中心に説明します。

#import コンパイラ ディレクティブの使用

#import Visual C++ コンパイラ ディレクティブを利用すれば、簡単に ADO のメソッドとプロパティを処理できます。このディレクティブは、ADO .dll (Msado15.dll) など、タイプ ライブラリを収めたファイルの名前を受けて、typedef 宣言、インターフェイスのスマート ポインタ、および列挙定数を組み込んだヘッダー ファイルを生成します。各インターフェイスはクラスにカプセル化、またはラップされます。

クラス内の操作 (メソッドやプロパティの呼び出し) ごとに、操作を直接呼び出す ("raw" の形式の操作) ための宣言と、raw operation を呼び出して、操作の実行が失敗したときに COM エラーを生成するための宣言が必要です。操作がプロパティ関連の場合は、Visual Basic に似た構文の操作のために、代替構文を作成するコンパイラ ディレクティブが実行されます。

プロパティの値を取得する操作には、GetProperty という形式の名前が割り当てられます。

プロパティの値を設定する操作には、PutProperty という形式の名前が割り当てられます。

ADO オブジェクトに対するポインタを持つプロパティの値を設定する操作には、PutRefProperty という形式の名前が割り当てられます。

プロパティの取得や設定は、次の形式の呼び出しで行います。

variable = objectPtr->GetProperty(); // get property value 
objectPtr->PutProperty(value);       // set property value
objectPtr->PutRefProperty(&value);   // set property with object pointer

プロパティ ディレクティブの使用

__declspec(property...) コンパイラ ディレクティブは、Microsoft 固有の C 言語拡張機能であり、プロパティとして利用される関数を宣言して代替構文を設定します。そのため、プロパティの値の設定や取得は、Visual Basic に似た方法で行うことができます。たとえば、プロパティの設定や取得は、次のように行います。

objectPtr->property = value;        // set property value
variable = objectPtr->property;     // get property value

ここでは、コーディングが不要な点に注意してください。

objectPtr->PutProperty(value);      // set property value
variable = objectPtr->GetProperty;  // get property value

コンパイラは、宣言された代替構文と、プロパティが読み取り専用か、書き込み専用かに基づいて、対応する Get-Put-、または PutRefProperty 呼び出しを生成します。

__declspec(property...) コンパイラ ディレクティブでは、関数には、getput、または getput の代替構文しか宣言できません。読み取り専用操作では get 宣言だけを、書き込み専用操作では put 宣言だけを、また読み書き両方の操作では get 宣言と put 宣言を組み込みます。

このディレクティブで使える宣言は 2 つだけですが、各プロパティには、GetPropertyPutProperty、および PutRefProperty の 3 つのプロパティ関数を組み込むことができます。その場合、代替構文を使えるのは 2 つのプロパティ形式だけです。

たとえば、Command オブジェクト ActiveConnection プロパティは、GetActiveConnectionPutRefActiveConnection の代替構文で宣言します。適切な選択は PutRef- 構文です。なぜなら、一般には、このプロパティには開かれた Connection オブジェクト (すなわち、Connection オブジェクト ポインタ) を書き込むことが多いためです。一方、Recordset オブジェクトには、Get-、Put-、および PutRefActiveConnection の各操作が対応しますが、代替構文はありません。

コレクション、GetItem メソッド、Item プロパティ

ADO では、FieldsParametersProperties、および Errors などいくつかのコレクションを定義しています。Visual C++ では、GetItem(index) メソッドは、このコレクション メンバを返します。Index はバリアント型 (Variant) であり、この値は、コレクション メンバの数値インデックスか、メンバ名を組み込んだ文字列です。

__declspec(property...) コンパイラ ディレクティブは、各コレクションの基本 GetItem() メソッドに対する代替構文として Item プロパティを宣言します。代替構文は角かっこを使い、配列参照に似ています。一般には、次のような 2 つの形式が使われます。

collectionPtr->GetItem(index);
collectionPtr->Item[index];

たとえば、rs という名前の Recordset オブジェクトのフィールドに、pubs データベースの authors テーブルから取り出した値を代入します。Recordset オブジェクト Fields コレクションの 3 番目の Field をアクセスするには、Item() プロパティを使います (コレクションは 0 からインデックスを設定し、3 番目のフィールド名は au_fname と想定)。Field オブジェクトで Value() メソッドを呼び出して、文字列値を代入します。

これを Visual Basic で記述すると次のようになります。(最後の 2 つの 形式は Visual Basic 固有の形式であり、ほかの言語に等価形式はありません)。

rs.Fields.Item(2).Value = "value"
rs.Fields.Item("au_fname").Value = "value"
rs(2) = "value"
rs!au_fname = "value"

上の最初の 2 形式に対する Visual C++ の等価形式は次のとおりです。

rs->Fields->GetItem(2)->PutValue("value"); 
rs->Fields->GetItem("au_fname")->PutValue("value");

- または - (Value プロパティの代替構文は次のとおり)

rs->Fields->Item[2]->Value = "value";
rs->Fields->Item["au_fname"]->Value = "value";

COM 固有のデータ型

一般に、「ADO API リファレンス」で使われている Visual Basic のデータ型には Visual C++ の等価となるデータ型があります。そのようなデータ型には、Visual Basic の Byte に対応する unsigned charInteger に対応する shortLong に対応する long などがあります。各メソッドやプロパティのオペランドに必要な内容については、「構文インデックス」を参照してください。

このルールを適用できないのは、バリアント型 (Variant)BSTR、および SafeArray の、COM 固有の次のデータ型です。

バリアント型 (Variant)

バリアント型 (Variant) は、値メンバとデータ型メンバを格納する構造化データ型です。バリアント型 (Variant) には、別のバリアント型 (Variant)、BSTR、ブール型 (Boolean)、IDispatch、または IUnknown ポインタ、通貨、日付などさまざまな異なるデータ型を格納できます。COM には、簡単にデータ型間の変換が行えるメソッドが用意されています。

_variant_t クラスは、バリアント型 (Variant) データをカプセル化し、管理します。

「ADO API リファレンス」で、メソッド オペランドやプロパティ オペランドが値をとるというとき、一般には _variant_t で値を渡すことを意味します。

「ADO API リファレンス」のトピックの「パラメータ」でオペランドがバリアント型 (Variant) というとき、無条件にこのルールを適用します。ただし、マニュアルでオペランドが長整数型 (Long)、バイト型 (Byte)、または列挙など標準データ型をとると明示してある場合は除きます。また、オペランドが文字列型 (String) をとる場合も除きます。

BSTR

BSTR (Basic STRing) は、文字列と文字長を格納する構造化データ型です。COM には、BSTR を割り当て、操作、解放するメソッドが用意されています。

_bstr_t クラスは BSTR データ型をカプセル化し、管理します。

「ADO API リファレンス」で、メソッド オペランドやプロパティ オペランドが文字列型 (String) の値をとるというとき、一般には _bstr_t で値を渡すことを意味します。

_variant_t クラスと _bstr_t クラスのキャスティング

演算に対して _variant_t または _bstr_t を引数で明示的にコーディングする必要は通常ありません。引数のデータ型に応じたコンストラクタが _variant_t クラスまたは _bstr_t クラスにある場合、必要な _variant_t または _bstr_t がコンパイラによって生成されます。

ただし、引数のデータ型が複数のコンストラクタに対応するなど引数が不明確な場合、対応したデータ型で引数をキャスティングしないと正しいコンストラクタを呼び出すことはできません。

次に Recordset::Open メソッドの宣言例を示します。

    HRESULT Open (
        const _variant_t & Source,
        const _variant_t & ActiveConnection,
        enum CursorTypeEnum CursorType,
        enum LockTypeEnum LockType,
        long Options );

ActiveConnection 引数は、_variant_t に対する参照をとります。これは、開かれた Connection オブジェクトに対する接続文字列またはポインタとしてコーディングできます。

"DSN=pubs;uid=sa;pwd=;" などの文字列または "(IDispatch *) pConn" などのポインタを渡せば、正しい _variant_t が自動的に生成されます。

あるいは、"_variant_t((IDispatch *) pConn, true)" などのポインタを組み込んだ _variant_t を明示的にコーディングする方法もあります。キャスト (IDispatch *) により、IUnknown インターフェイスに対するポインタをとる別のコンストラクタとのあいまいさが解消されます。

あまり取り上げられることはありませんが、ADO が IDispatch インターフェイスであるということに注意してください。ADO オブジェクトに対するポインタをバリアント型 (Variant) として渡すとき、そのポインタは IDispatch インターフェイスに対するポインタとしてキャスティングする必要があるためです。

最後の例では、コンストラクタの 2 番目のブール型 (Boolean) 引数を、オプションの既定値 True で明示的にコーディングしています。この引数の指定により、バリアント型 (Variant) コンストラクタが AddRef() メソッドを呼び出し、このメソッドは、ADO メソッドまたはプロパティの呼び出しが終了すると、_variant_t::Release() メソッドを自動的に呼び出す ADO を補償します。

SafeArray

SafeArray は、別のデータ型の配列を格納する構造化データ型です。SafeArray が "Safe (安全)" であるとされているのは、各配列の次元の範囲に関する情報を SafeArray が格納し、配列要素に対するアクセスをそれらの範囲内に制限するためです。

「ADO API リファレンス」で、「メソッドやプロパティが配列をとる」、または「返す」というとき、メソッドやプロパティが、ネイティブ C/C++ 配列ではなく SafeArray をとること、または返すことを意味します。

たとえば、Connection オブジェクト OpenSchema メソッドの 2 番目のパラメータには、バリアント型 (Variant) の値の配列が必要です。これらのバリアント型 (Variant) の値は、SafeArray の要素として渡され、その SafeArray は別の Variant の値として設定されます。OpenSchema の 2 番目の引数として渡されるのは、別のバリアント型 (Variant) です。

さらに別の例として、Find メソッドの最初の引数がバリアント型 (Variant) で、その値が一次元の SafeArray の場合、AddNew の最初と 2 番目の任意の引数は、それぞれ一次元 SafeArray であり、GetRows メソッドの戻り値は、値が二次元 SafeArray のバリアント型 (Variant) です。

パラメータの省略と既定パラメータ

Visual Basic では、メソッドのパラメータを省略できます。たとえば、Recordset オブジェクトの Open メソッドには 5 つのパラメータがありますが、中間のパラメータを省略して、後続のパラメータはそのまま使用することができます。省略したオペランドのデータ型に応じて、既定の BSTR やバリアント型 (Variant) が代用されます。

C/C++ では、すべてのオペランドを指定する必要があります。データ型が文字列の省略パラメータを指定するには、Null 値を格納した _bstr_t を指定します。データ型がバリアント型 (Variant) の省略パラメータを指定するには、値を DISP_E_PARAMNOTFOUND、型を VT_ERROR で _variant_t を指定します。または、#import ディレクティブが備える等価の _variant_t 定数である vtMissing を指定します。

vtMissing の一般的な使用方法にあてはまらないメソッドが 3 つあります。それは、Connection オブジェクトと Command オブジェクトの Execute メソッド、Recordset オブジェクトの NextRecordset メソッドです。次に、そのシグネチャを示します。

_RecordsetPtr ExecutemdmthCnnExecute( _bstr_t CommandText, VARIANT * RecordsAffected, 
        long Options );  // Connection
_RecordsetPtr ExecutemdmthCmdExecute( VARIANT * RecordsAffected, VARIANT * Parameters, 
        long Options );  // Command
_RecordsetPtr NextRecordsetmdmthNextRec( VARIANT * RecordsAffected );  // Recordset

パラメータ RecordsAffectedParameters は 1 つのバリアント型 (Variant) に対するポインタです。Parameters は、実行するコマンドを変更する 1 つのパラメータまたはパラメータの配列を格納するバリアント型 (Variant) のアドレスを指定する入力パラメータです。RecordsAffected は、メソッドによって影響を受ける行数を返すバリアント型 (Variant) のアドレスを指定する出力パラメータです。

Command オブジェクトの Execute メソッドで、パラメータの省略を指定するには、Parameters&vtMissing (推奨) か、Null ポインタ (NULL またはゼロ (0)) に設定します。Parameters を Null ポインタに設定すると、メソッドは vtMissing の等価に内部的に置換して操作を実行します。

すべてのメソッドで、RecordsAffected を Null ポインタに設定して、影響を受けるレコードの数を返さないように指定します。この場合の Null ポインタは省略パラメータではなく、影響を受けるレコードの数をメソッドで破棄せよという指示です。

したがって、これら 3 つのメソッドの場合、次のようなコーディングも可能です。

pConnection->Execute("commandText", NULL, adCmdText); 
pCommand->Execute(NULL, NULL, adCmdText);
pRecordset->NextRecordset(NULL);

エラー処理

COM では、ほとんどの操作で HRESULT 戻りコードが返ります。これは関数が成功したかどうかを示すコードです。#import ディレクティブは、raw メソッドやプロパティごとにラッパー コードを生成して、返された HRESULT を調べます。HRESULT がエラーを示すとき、ラッパー コードは、HRESULT 戻りコードを引数として _com_issue_errorex() を呼び出して COM エラーを生成します。COM エラー オブジェクトは、try-catch ブロックで捕捉できます。(効率性を考えて、_com_error オブジェクトに対する参照を使います。)

これらは、ADO 操作の失敗で生成される ADO エラーであることを念頭に置いておきます。基になるプロバイダが返すエラーは、Connection オブジェクト Errors コレクションに Error オブジェクトとして表示されます。

#import ディレクティブでは、ADO .dll で宣言したメソッドとプロパティにだけエラー処理ルーチンを作成します。ただし、自分でエラー確認マクロやインライン関数を記述すれば、同じエラー処理機能を利用できます。例については、「Visual C++ Extensions for ADO」または、後述のコードを参照してください。

Visual Basic 規約と等しい Visual C++ 規約

次に、Visual Basic と等しい Visual C++ でコーディングした ADO マニュアルの規約の概要を示します。

ADO オブジェクトの宣言

Visual Basic では、ADO オブジェクト変数 (この場合は Recordset オブジェクト) は、次のように宣言します。

Dim rst As ADODB.Recordset

句 "ADODB.Recordset" は、レジストリで定義した Recordset オブジェクトの ProgID です。Record オブジェクトの新しいインスタンスは次のように宣言します。

Dim rst As New ADODB.Recordset

- または -

Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset

Visual C++ では、#import ディレクティブによってスマート ポインタ型宣言がすべての ADO オブジェクトに対して生成されます。たとえば、_Recordset オブジェクトを指定する変数は、型が _RecordsetPtr になり、次のように宣言します。

_RecordsetPtr  rs;

_Recordset オブジェクトの新しいインスタンスを指定する変数は、次のように宣言します。

_RecordsetPtr  rs("ADODB.Recordset");

- または -

_RecordsetPtr  rs;
rs.CreateInstance("ADODB.Recordset");

- または -

_RecordsetPtr  rs;
rs.CreateInstance(__uuidof(_Recordset));

CreateInstance メソッドの呼び出し後、変数は次のように使うことができます。

rs->Open(...);

変数がクラスのインスタンスであるものとして "." 演算子が使われ (rs.CreateInstance)、変数がインターフェイスへのポインタであるものとして "->" 演算子が使われる (rs->Open) ことに注意してください。

"->" 演算子がオーバーロードされているために、クラスのインスタンスをインターフェイスへのポインタのように利用できる場合は、1 つの変数を 2 通りに使うことができます。インスタンス変数のプライベート クラス メンバは、_Recordset インターフェイスへのポインタを格納します。"->" 演算子はポインタを返し、返されたポインタは _Recordset オブジェクトのメンバにアクセスします。

省略パラメータのコーディング - 文字列型 (String)

省略文字列型 (String) オペランドを Visual Basic でコーディングするときは、単純にそのオペランドを省略します。Visual C++ ではオペランドを指定する必要があります。空文字列を値として持つ _bstr_t をコーディングします。

_bstr_t strMissing(L"");

省略パラメータのコーディング - バリアント型 (Variant)

省略バリアント型 (Variant) オペランドを Visual Basic でコーディングするときは、単純にそのオペランドを省略します。Visual C++ では、すべてのオペランドを指定する必要があります。省略バリアント型 (Variant) パラメータをコーディングするには、特別な値 DISP_E_PARAMNOTFOUND と型 VT_ERROR で _variant_t を設定します。または、#import ディレクティブが提供する等価の定義済み定数である vtMissing を指定します。

_variant_t  vtMissingYours(DISP_E_PARAMNOTFOUND, VT_ERROR); 

- または -

...vtMissing...;

バリアント型 (Variant) の宣言

Visual Basic では、バリアント型 (Variant) は、次のように Dim ステートメントで宣言します。

Dim VariableName As Variant

Visual C++ では、型 _variant_t として変数を宣言します。スキーマ的 _variant_t 宣言の例を次に示します。

注意   これらの宣言は、プログラムで何をコーディングをするか、その概要を示したものです。詳細については、この後の例や Visual C++ のマニュアルを参照してください。

_variant_t  VariableName(value);
_variant_t  VariableName((data type cast) value);
_variant_t  VariableName(value, VT_DATATYPE);
_variant_t  VariableName(interface * value, bool fAddRef = true);

バリアント型 (Variant) 配列の使用

Visual Basic では、バリアント型 (Variant) 配列は Dim ステートメントを使ってコーディングします。または、次のコード例にもあるように Array 関数を使うこともできます。

Public Sub ArrayOfVariants
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim fld As ADODB.Field

cn.Open "DSN=pubs", "sa", ""
rs = cn.OpenSchema(adSchemaColumns, _
                     Array(Empty, Empty, "authors", Empty))
For Each fld in rs.Fields
   Debug.Print "Name = "; fld.Name
Next fld
rs.Close
cn.Close
End Sub

次の Visual C++ の例では、_variant_t に使う SafeArray の使用方法を示します。

注意   次の注意事項は、コード例のコメント部分に対応しています。

  1. もう一度、TESTHR() インライン関数を定義して、既存のエラー処理機能を利用します。

  2. 必要なのは一次元配列のみであり、汎用の SAFEARRAYBOUND 宣言と SafeArrayCreate 関数の代わりに SafeArrayCreateVector が使えます。次の例は、SafeArrayCreate を使ったときのコードを示しています。
       SAFEARRAYBOUND   sabound[1];
       sabound[0].lLbound = 0;
       sabound[0].cElements = 4;
       pSa = SafeArrayCreate(VT_VARIANT, 1, sabound);
    
  3. 列挙定数 adSchemaColumns で識別したスキーマは、4 つの定数列 (TABLE_CATALOG、TABLE_SCHEMA、TABLE_NAME、およびCOLUMN_NAME) に関連付けられています。したがって、4 つの要素を持つバリアント型 (Variant) の値の配列が作成されます。次に、3 番目の列 TABLE_NAME に対応する制約値を指定します。

    返される Recordset は、さまざまな列で構成されています。このサブセットが制約列です。各戻り行に対する制約列の値は、対応する制約値と同じにします。

  4. SafeArrays に慣れていると、終了前に SafeArrayDestroy() が呼び出されないことに驚かれるかもしれません。実際、このときに SafeArrayDestroy() を呼び出すと実行時例外処理になります。これは、_variant_t が範囲外になると SafeArray が解除されて、vtCriteria のデストラクタが VariantClear() を呼び出すためです。手動で _variant_t を消去せずに SafeArrayDestroy を呼び出すと、デストラクタは無効な SafeArray ポインタを消去しようとします。

    SafeArrayDestroy を呼び出すと、次のようなコードになります。

       TESTHR(SafeArrayDestroy(pSa));
       vtCriteria.vt = VT_EMPTY;
       vtCriteria.parray = NULL;
    

    ただし、_variant_tSafeArray を管理する方がずっと簡単です。

#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
   no_namespace rename("EOF", "EndOfFile")
#include <stdio.h>

// Note 1
inline void TESTHR( HRESULT _hr ) 
   { if FAILED(_hr) _com_issue_error(_hr); }

void main(void)
{
   CoInitialize(NULL);
   try 
   {
   _RecordsetPtr   pRs("ADODB.Recordset");
   _ConnectionPtr  pCn("ADODB.Connection");
   _variant_t      vtTableName("authors"),
                   vtCriteria;
   long            ix[1];
   SAFEARRAY       *pSa = NULL;

   pCn->Open("DSN=pubs;User ID=sa;pwd=;Provider=MSDASQL;", "", "", 
               adConnectUnspecified);
// Note 2, Note 3
   pSa = SafeArrayCreateVector(VT_VARIANT, 1, 4);
   if (!pSa) _com_issue_error(E_OUTOFMEMORY);

// Specify TABLE_NAME in the third array element (index of 2). 

   ix[0] = 2;      
   TESTHR(SafeArrayPutElement(pSa, ix, &vtTableName));

//   There is no Variant constructor for a SafeArray, so manually set the 
//   type (SafeArray of Variant) and value (pointer to a SafeArray).

   vtCriteria.vt = VT_ARRAY | VT_VARIANT;
   vtCriteria.parray = pSa;

   pRs = pCn->OpenSchema(adSchemaColumns, vtCriteria, vtMissing);

   long limit = pRs->GetFields()->Count;
   for (long x = 0; x < limit; x++)
      printf("%d: %s\n", x+1, 
         ((char*) pRs->GetFields()->Item[x]->Name));
// Note 4
   pRs->Close();
   pCn->Close();
   }
   catch (_com_error &e)
   {
   printf("Error:\n");
   printf("Code = %08lx\n", e.Error());
   printf("Code meaning = %s\n", (char*) e.ErrorMessage());
   printf("Source = %s\n", (char*) e.Source());
   printf("Description = %s\n", (char*) e.Description());
   }
   CoUninitialize();
}

Get/Put/PutRef Property の使用

Visual Basic では、取得、割り当て、または参照の割り当てによって、プロパティ名が識別されることはありません。

Public Sub GetPutPutRef
Dim rs As New ADODB.Recordset
Dim cn As New ADODB.Connection
Dim sz as Integer
cn.Open "Provider=sqloledb;Data Source=yourserver;" & _
         "Initial Catalog=pubs;User Id=sa;Password=;"
rs.PageSize = 10
sz = rs.PageSize
rs.ActiveConnection = cn
rs.Open "authors",,adOpenStatic
' ...
rs.Close
cn.Close
End Sub

この Visual C++ の例は、Get/Put/PutRefProperty を示しています。

注意   次の注意事項は、コード例のコメント部分に対応しています。

  1. この例では、2 つの形式の省略文字列引数を使っています。それらは、Open メソッドの範囲内で存在する一時 _bstr_t を作成するためにコンパイラが使う、明示定数 strMissing と文字列です。

  2. rs->PutRefActiveConnection(cn) オペランドの型が既に (IDispatch *) になっているので、このオペランドは (IDispatch *) にキャストする必要はありません。
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
   no_namespace rename("EOF", "EndOfFile")
#include <stdio.h>

void main(void)
{
   CoInitialize(NULL);
   try 
   {
      _ConnectionPtr  cn("ADODB.Connection");
      _RecordsetPtr   rs("ADODB.Recordset");
      _bstr_t         strMissing(L"");
      long            oldPgSz = 0, 
                      newPgSz = 5;

// Note 1
      cn->Open("Provider=sqloledb;Data Source=yourserver;"
         "Initial Catalog=pubs;User Id=sa;Password=;", 
         strMissing, "",
         adConnectUnspecified);
   
      oldPgSz = rs->GetPageSize();
   // -or-
      oldPgSz = rs->PageSize;

      rs->PutPageSize(newPgSz);
   // -or-
      rs->PageSize = newPgSz;

// Note 2
      rs->PutRefActiveConnection( cn );
      rs->Open("authors", vtMissing, adOpenStatic, adLockReadOnly,
               adCmdTable);
      printf("Original pagesize = %d, new pagesize = %d\n", oldPgSz, 
               rs->GetPageSize());
      rs->Close();
      cn->Close();
   }
   catch (_com_error &e)
   {
      printf("Description = %s\n", (char*) e.Description());
   }
   ::CoUninitialize();
}

GetItem(x) と Item[x] の使用

この Visual Basic の例では、Item() の標準構文と代替構文を示します。

Public Sub GetItemItem
Dim rs As New ADODB.Recordset
Dim name as String
rs = rs.Open "authors", "DSN=pubs;UID=SA;PWD=;", adOpenDynamic, _
         adLockBatchOptimistic, adCmdTableDirect
name = rs(2)
' -or-
name = rs.Fields.Item(2)
rs(2) = "Test"
rs.UpdateBatch
' Restore name
rs(2) = name
rs.UpdateBatch
rs.Close
End Sub

この Visual C++ の例は、Item を示しています。

注意   次の注意事項は、コード例のコメント部分に対応しています。

  1. コレクションに Item を使ってアクセスした場合、適切なコンストラクタを呼び出すため、インデックス 2 は長整数型 (long) にキャストされます。
#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
   no_namespace rename("EOF", "EndOfFile")
#include <stdio.h>

void main(void)
{
   CoInitialize(NULL);
   try {
      _RecordsetPtr   rs("ADODB.Recordset");
      _variant_t      vtFirstName;

      rs->Open("authors",
               "Provider=sqloledb;Data Source=yourserver;"
               "Initial Catalog=pubs;User Id=sa;Password=;",
               adOpenStatic, adLockOptimistic, adCmdTable);
      rs->MoveFirst();

// Note 1. Get a field.
      vtFirstName = rs->Fields->GetItem((long)2)->GetValue();
   // -or-
      vtFirstName = rs->Fields->Item[(long)2]->Value;

      printf( "First name = '%s'\n", (char*) ((_bstr_t) vtFirstName));

      rs->Fields->GetItem((long)2)->Value = L"TEST";
      rs->Update(vtMissing, vtMissing);

   // Restore name
      rs->Fields->GetItem((long)2)->PutValue(vtFirstName);
      // -or-
      rs->Fields->GetItem((long)2)->Value = vtFirstName;
      rs->Update(vtMissing, vtMissing);
      rs->Close();
   }
   catch (_com_error &e)
   {
      printf("Description = '%s'\n", (char*) e.Description());
   }
   ::CoUninitialize();
}

(IDispatch *) を使った ADO オブジェクト ポインタのキャスティング

次の Visual C++ の例では、(IDispatch *) を使った ADO オブジェクト ポインタのキャスティングを示します。

注意   次の注意事項は、コード例のコメント部分に対応しています。

  1. 明示的にコーディングされたバリアント型 (Variant) で、開いている Connection を指定します。正しいコンストラクタが呼び出されるように、(IDispatch *) を使ってキャストします。また、Recordset::Open の操作の終了時にオブジェクト参照カウントが正しくなるように、2 番目の _variant_t パラメータを既定値 True に明示的に設定します。

  2. (_bstr_t) はキャストではなく、Value が返すバリアント型 (Variant) から _bstr_t 文字列を取り出す _variant_t 演算子です。

    (char*) はキャストではなく、_bstr_t オブジェク内のカプセル化された文字列へのポインタを取り出す _bstr_t 演算子です。

    このコード セクションでは、_variant_t 演算子と _bstr_t 演算子の便利な機能をいくつか示します。

#import "c:\Program Files\Common Files\System\ADO\msado15.dll" \
no_namespace rename("EOF", "EndOfFile")

#include <stdio.h>

void main(void)
{
   CoInitialize(NULL);
   try 
   {
      _ConnectionPtr pConn("ADODB.Connection");
      _RecordsetPtr  pRst("ADODB.Recordset");

      pConn->Open("Provider=sqloledb;Data Source=yourserver;"
         "Initial Catalog=pubs;User Id=sa;Password=;", 
         "", "", adConnectUnspecified);
// Note 1
      pRst->Open(
         "authors",
         _variant_t((IDispatch *) pConn, true),
         adOpenStatic,
         adLockReadOnly,
         adCmdTable);
      pRst->MoveLast();
// Note 2
      printf("Last name is '%s %s'\n", 
            (char*) ((_bstr_t) pRst->GetFields()->GetItem("au_fname")->GetValue()),
            (char*) ((_bstr_t) pRst->Fields->Item["au_lname"]->Value));

      pRst->Close();
      pConn->Close();
   }
   catch (_com_error &e)
   {
      printf("Description = '%s'\n", (char*) e.Description());
   }   
::CoUninitialize();
}