【Access VBA】コンボボックスにレコードセットを代入する方法とエラーの原因

MS Access
スポンサーリンク

今回の記事では、Access VBAでADOを使用して取得したRecordsetオブジェクトをコンボボックスに代入する方法と、代入の際に実行時エラーが出る場合の原因を解説します。

尚、エラーについては私自身なぜエラーになるのかわからず、原因を特定するのに時間が掛かったため、備忘録として残しておこうと思います。
 
 

コンボボックスにレコードセットを代入してエラーになるサンプルコード

当項では、AccessのコンボボックスにADODB.Recordsetオブジェクトを代入する場合にエラーになるサンプルコードを紹介しておきます。

サンプルコードの前提条件

  • コンボボックスの名前は「cmb_test」。
  • コンボボックスのプロパティはVBAで指定。
  • コンボボックスにはRecordsetオブジェクトを変換せずそのまま代入する。
  Dim objCon As ADODB.Connection
  Dim objRs As ADODB.Recordset
  Dim ConString As String
  Dim strSQL As String

    'コンボボックスのプロパティを設定
    Me.cmb_test.ColumnCount = 2
    Me.cmb_test.BoundColumn = 1
    Me.cmb_test.ColumnWidths = "2cm;4cm"
    Me.cmb_test.RowSourceType = "Table/Query"

    'データベースと接続します。
    Set objCon = New ADODB.Connection
    ConString = "Driver={SQL Server};Server=DBホスト名;Uid=ユーザーID;Pwd=パスワード;Database=接続先DB名"
    objCon.Open ConString

    'SQLを生成して実行します。
    strSQL = "SELECT 列1,列2 FROM テストテーブル WHERE 列1 = 条件"
    Set objRs = objCon.Execute(strSQL)

    '取得したレコードセットをコンボボックスに代入します。
    'ここでエラー
    Set Me.cmb_test.Recordset = objRs
    
    objRs.Close
    objCon.Close
    
    Set objRs = Nothing
    Set objCon = Nothing

上記のコードを一部補足します。

コンボボックスにレコードセットを代入する場合、10行目のように、「RowSourceType」プロパティに”Table/Query“を指定します。
19行目でデータベースからレコードを取得して、レコードセットに格納しています。

本来は、このRecordsetオブジェクトを23行目のように、コンボボックスの「Recordset」プロパティに直接代入できます。

ただ、上記のコードでは以下のエラーが発生します。

実行時エラー ‘7965’
“Recordset/レコードセット” プロパティの設定に、そのオブジェクトは使えません。

実行時エラー '7965'

次項ではエラーの原因を解説します。
 
 

Recordsetのカーソルタイプ「adOpenForwardOnly」はコンボボックスに代入できない

コンボボックスのRecordsetプロパティにRecordsetオブジェクトを代入する場合は、そのRecordsetオブジェクトの「CursorType」プロパティの設定によって、代入の可否が変わります。

RecordsetオブジェクトのCursorTypeプロパティについては以下のMicrosoftのリファレンスをご確認ください。

各CursorTypeごとのコンボボックス代入可否の一覧は以下です。

CursorType 代入可否
adOpenForwardOnly(既定) ×
adOpenKeyset
adOpenDynamic ×
adOpenStatic
adOpenUnspecified ×

コンボボックスに対して、Recordsetオブジェクトのまま代入する場合、CursorTypeは「adOpenKeyset」又は「adOpenStatic」が指定されている必要があります。

前述したコードでエラーになる原因は、「ADODB.Connection」オブジェクトの「Execute」メソッドを使用してレコードセットを取得した場合、「Execute」メソッドの戻り値のRecordsetオブジェクトのCursorTypeは、既定値である「adOpenForwardOnly」がセットされます。
そのため、コンボボックスのRecordsetプロパティに対応しておらずエラーになります。

尚、「ADODB.Connection」オブジェクトの「Execute」メソッドの戻り値であるRecordsetオブジェクトのCursorTypeは「adOpenForwardOnly」しか使用できません。

「ADODB.Connection」オブジェクトの「Execute」メソッドではCursorTypeを明示的に指定できないため、コンボボックスのレコードセットを代入する場合は、「ADODB.Recordset」オブジェクトの「Open」メソッドを使用してレコードセットを取得する必要があります。

尚、「ADODB.Recordset」オブジェクトの「Open」メソッドを使用してレコードセットを取得する方法については、当ブログで以前に書いた以下の記事で詳しく解説しております。
良ければご一読ください。

 
 

コンボボックスにレコードセットを代入できるように修正したサンプルコード

Accessのコンボボックスにレコードセットを代入する際に、エラーになるサンプルコードの紹介と、その解説内容を踏まえて、当項では、エラーにならずに代入できるように修正したサンプルコードを紹介します。

  Dim objCon As ADODB.Connection
  Dim objRs As ADODB.Recordset
  Dim ConString As String
  Dim strSQL As String

    'コンボボックスのプロパティを設定
    Me.cmb_test.ColumnCount = 2
    Me.cmb_test.BoundColumn = 1
    Me.cmb_test.ColumnWidths = "2cm;4cm"
    Me.cmb_test.RowSourceType = "Table/Query"

    'データベースと接続します。
    Set objCon = New ADODB.Connection
    ConString = "Driver={SQL Server};Server=DBホスト名;Uid=ユーザーID;Pwd=パスワード;Database=接続先DB名"
    objCon.Open ConString

    'SQLを生成して実行します。
    strSQL = "SELECT 列1,列2 FROM テストテーブル WHERE 列1 = 条件"
    Set objRs = New ADODB.Recordset
    'RecordsetオブジェクトのOpenメソッドで、CursorTypeに「adOpenKeyset」を指定します。
    objRs.Open strSQL, objCon, adOpenKeyset
    
    '取得したレコードセットをコンボボックスに代入します。
    Set Me.cmb_test.Recordset = objRs
    
    objRs.Close
    objCon.Close
    
    Set objRs = Nothing
    Set objCon = Nothing

上記コードの21行目のように、RecordsetオブジェクトのOpenメソッドの引数として適切なCursorTypeを指定することで、無事にコンボボックスのRecordsetプロパティにRecordsetオブジェクトを丸っと渡すことができるようになります。
 
 

最後に

今回の記事では、AccessのコンボボックスにRecordsetオブジェクトを代入する場合にエラーになる現象の紹介と、その原因の解説。
また、正常に代入できる実際のサンプルコードを紹介しました。

インターネットで調べていても、コンボボックスの「Recordset」プロパティと「ADODB.Recordset」オブジェクトの「CursorType」の関係性について言及している記事が見つからずに、すぐに原因がわからず困りました。

今回の記事がどなたかの助けになれば幸いです。

それでは皆さまごきげんよう!

タイトルとURLをコピーしました