次の方法で共有


Visual C++ ADO プログラミング

適用先: Access 2013、Office 2013

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

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

ADO は COM (コンポーネント オブジェクト モデル) インターフェイスで実装されています。 プログラマにとって、COM の操作は言語によって簡単である場合とそうでない場合があります。 たとえば、Visual Basic のプログラマの場合は COM のほとんどの処理が暗黙的に実行されますが、Visual C++ プログラマの場合はそれらの処理を自分で行う必要があります。

ここでは、C のプログラマと C++ のプログラマが ADO と #import ディレクティブを使用する際の概要を示します。 COM 固有のデータ型 (バリアント型 (Variant)、BSTR 型、および SafeArray 型) とエラー処理 (_com_error) に重点を置いて説明します。

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

#import Visual C++ コンパイラ ディレクティブを使用すると、ADO のメソッドとプロパティを簡単に操作できます。 このディレクティブは、タイプ ライブラリを含んでいる ADO .dll (Msado15.dll) などのファイルの名前を取得し、typedef 宣言、インターフェイスのスマート ポインター、および列挙定数を含むヘッダー ファイルを生成します。 各インターフェイスはクラス内にカプセル化またはラップされます。

クラス内の操作 (メソッドまたはプロパティの呼び出し) ごとに、操作を直接呼び出す宣言 ("raw" 形式の操作) と、raw 操作を呼び出して、操作の実行が失敗したときに 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...) コンパイラ ディレクティブは、マイクロソフト固有の 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 プロパティは、GetActiveConnection および PutRefActiveConnection の代替構文で宣言されます。 一般に、このプロパティには開いている Connection オブジェクト (つまり Connection オブジェクトのポインター) を設定することが多いため、PutRef- 構文を選択するのが適切です。 一方、Recordset オブジェクトには Get-、Put-、および PutRefActiveConnection の各操作がありますが、代替構文はありません。

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

ADO では、 FieldsParametersPropertiesErrors など、いくつかのコレクションが定義されています。 Visual C++ では、 GetItem(index) メソッドはコレクションのメンバーを返します。 Index はバリアント型 (Variant) で、値はコレクションのメンバーの数値インデックスか、またはメンバーの名前を含む文字列です。

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

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

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

これを Visual Basic で記述するには、次の 4 つの方法があります (最後の 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(long(2))->PutValue("value"); 
rs->Fields->GetItem("au_fname")->PutValue("value"); 

または、次の形式もあります ( Value プロパティの代替構文を示します)。

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

COM 固有のデータ型

一般に、「ADO API リファレンス」で使われている Visual Basic のデータ型に対しては、同等のデータ型が Visual C++ にあります。 たとえば、Visual Basic のバイト型 ( Byte ) に対する unsigned char 、整数型 ( Integer ) に対する short 、長整数型 ( Long ) に対する long などの標準データ型があります。 各メソッドまたはプロパティのオペランドに必要な要素の詳細については、各「構文インデックス」を参照してください。

この規則が当てはまらないのは、COM 固有のデータ型であるバリアント型 (Variant)、BSTR 型、および SafeArray 型です。

バリアント型

バリアント型 ( 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" などの文字列を渡すと、正しい _variant_t が暗黙的に構築されます。uid=sa;pwd=;"、または "(IDispatch *) pConn" などのポインター。

または、" _variant_t (IDispatch *) pConn, true)" などのポインターを含む_variant_tを明示的にコーディングすることもできます。 キャスト (IDispatch *) を実行することにより、IUnknown インターフェイスへのポインターを取得する別のコンストラクターにも対応するという不明確さを解決できます。

ほとんど言及されませんが、ADO が IDispatch インターフェイスであるということは非常に重要です。 ADO オブジェクトへのポインターをバリアント型 ( Variant ) として渡す場合は、そのポインターを IDispatch インターフェイスへのポインターとしてキャストする必要があります。

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

Safearray

A SafeArray is a structured data type that contains an array of other data types. SafeArray は、各配列次元の境界に関する情報を含み、それらの境界内の配列要素へのアクセスを制限するため、セーフと呼ばれます。

「ADO API リファレンス」で、メソッドまたはプロパティが配列を取得する、または配列を返すと記載されている場合は、メソッドまたはプロパティが、C/C++ のネイティブ配列ではなく SafeArray 型を取得するまたは返すことを意味します。

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

さらに別の例として、 Find メソッドの最初の引数がバリアント型 ( Variant ) で、その値が 1 次元の SafeArray 型である場合、 AddNew の最初と 2 番目のオプションの引数はそれぞれ 1 次元の SafeArray 型で、 GetRows メソッドの戻り値は、値が 2 次元の 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 Invalid DDUE based on source, error:link not allowed in code, link filename:mdmthcnnexecute_HV10294345.xml( _bstr_t CommandText, VARIANT * RecordsAffected, 
 long Options ); // Connection 
_RecordsetPtr Invalid DDUE based on source, error:link not allowed in code, link filename:mdmthcmdexecute_HV10294344.xml( VARIANT * RecordsAffected, VARIANT * Parameters, 
 long Options ); // Command 
_RecordsetPtr Invalid DDUE based on source, error:link not allowed in code, link filename:mdmthnextrec_HV10294541.xml( VARIANT * RecordsAffected ); // Recordset 

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

Command オブジェクト Execute メソッドで、パラメーターを 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 で宣言されたメソッドとプロパティに対してのみエラー処理ルーチンを生成します。 ただし、自分でエラー確認マクロやインライン関数を記述すると、同じエラー処理機構を利用できます。 例については、「 ADO 用の Visual C++ Extensions」または、以下に説明するコードを参照してください。

Visual C++ と同等の Visual Basic 規則

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(...); 

1 つのケースでは、変数がクラス (rs) のインスタンスであるかのように "." 演算子が使用されていることに注意してください。CreateInstance) と別のケースでは、変数がインターフェイス (rs-Open) へのポインターであるかのように "->>" 演算子が使用されます。

"->" 演算子がオーバーロードされ、クラスのインスタンスがインターフェイスへのポインターのように動作できるようにするため、1 つの変数を 2 つの方法で使用できます。 インスタンス変数のプライベート クラス メンバーには、 _Recordset インターフェイスへのポインターが含まれています。"->" 演算子はそのポインターを返し、返されたポインターは _Recordset オブジェクトのメンバーにアクセスします。

欠落しているパラメーターのコーディング

String

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

 
_bstr_t strMissing(L""); 

バリアント型

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

 
_variant_t vtMissingYours(DISP_E_PARAMNOTFOUND, VT_ERROR); 

または、次のように記述することもできます。

 
...vtMissing...; 

バリアントの宣言

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); 

バリアントの配列の使用

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++ の例では、 SafeArray 型を _variant_t と共に使用する方法を示します。

注:

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

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

  2. 必要なのは 1 次元配列のみであるため、汎用の SAFEARRAYBOUND 宣言と SafeArrayCreate 関数の代わりに SafeArrayCreateVector 関数を使用できます。 次に、 SafeArrayCreate を使用した場合のコードを示します。

    
      SAFEARRAYBOUND sabound[1]; 
      sabound[0].lLbound = 0; 
      sabound[0].cElements = 4; 
      pSa = SafeArrayCreate(VT_VARIANT, 1, sabound); 
    
  3. 列挙定数 adSchemaColumns で識別されたスキーマは、TABLE_CATALOG、TABLE_SCHEMA、TABLE_NAME、および COLUMN_NAME という 4 つの制約列に関連付けられています。 したがって、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=MyUserId;pwd=MyPassword;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 の使用

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;Integrated Security=SSPI;" 
    rs.PageSize = 10 
    sz = rs.PageSize 
    rs.ActiveConnection = cn 
    rs.Open "authors",,adOpenStatic 
    ' ... 
    rs.Close 
    cn.Close 
    End Sub

この Visual C++ の例では、PutRef/プロパティ取得/を示します。

注:

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

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

  2. オペランドの型は既に (IDispatch *) であるため、rs-PutRefActiveConnection>(cn) のオペランドを (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=MyServer;" 
      "Initial Catalog=pubs;Integrated Security=SSPI;", 
      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;", adOpenDynamic, _ 
 adLockBatchOptimistic, adTable 
name = rs(0) 
' -or- 
name = rs.Fields.Item(0) 
rs(0) = "Test" 
rs.UpdateBatch 
' Restore name 
rs(0) = name 
rs.UpdateBatch 
rs.Close 
End Sub 

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

注:

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

  1. コレクションに Item を使用してアクセスした場合、適切なコンストラクターが呼び出されるように、インデックス 2long にキャストされる必要があります。

    
     #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=MyServer;" 
      "Initial Catalog=pubs;Integrated Security=SSPI;", 
      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:: の操作の終了時にオブジェクト参照カウントが正しくなるように、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=MyServer;" 
      "Initial Catalog=pubs;Integrated Security=SSPI;", 
      "", "", 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(); 
     }