今回の記事では、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/レコードセット” プロパティの設定に、そのオブジェクトは使えません。
次項ではエラーの原因を解説します。
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.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」の関係性について言及している記事が見つからずに、すぐに原因がわからず困りました。
今回の記事がどなたかの助けになれば幸いです。
それでは皆さまごきげんよう!