VBA を使用してコンボボックスにレコードセットを設定する方法
質問
いくつかの文献が次の場所で入手できます。 専門家の意見交換 そしてで テック共和国 combobox.recordset プロパティを使用して Access フォームのコンボボックスに値を設定する方法について説明します。
これらのコントロールには通常、コントロールの「rowsource」プロパティに「SELECT *」文字列が設定され、アプリのクライアント側で使用可能なテーブルまたはクエリを参照します。サーバー側のデータをコンボボックスに表示する必要がある場合は、一時的なローカル テーブルを作成し、要求されたレコードをインポートします。これは、特に大きなテーブルの場合には時間がかかります。
レコードセットを使用してコンボボックス コントロールにデータを設定できると、ユーザーはサーバー側からデータを直接表示できるようになります。
前の 2 つの例に触発されて、次のようなコードを作成しました。
Dim rsPersonne as ADODB.recordset
Set rsPersonne = New ADODB.Recordset
Set rsPersonne.ActiveConnection = connexionActive
rsPersonne.CursorType = adOpenDynamic
rsPersonne.LockType = adLockPessimistic
rsPersonne.CursorLocation = adUseClient
rsPersonne.Open "SELECT id_Personne, nomPersonne FROM Tbl_Personne"
fc().Controls("id_Personne").Recordset = rsPersonne
どこ:
- 接続アクティブ:データベース サーバーへの永続的な ADO 接続です
- fc():私の現在の/アクティブなフォームです
- コントロール("id_personne"):会社のスタッフリストを入力するコンボボックスコントロールですか
- 2003 年の Access バージョン
残念ながら、それは機能しません!
デバッグ モードでは、要求された列とデータを備えたレコードセットが適切に作成され、コンボボックス コントロールに適切に関連付けられていることを確認できます。残念ながら、フォームを表示すると、レコードが入っていない空のコンボボックスが表示され続けます。ご協力をよろしくお願いいたします。
編集:
確かに、このレコードセット プロパティは、標準のコントロール オブジェクトではなく、特定のコンボボックス オブジェクトで使用できます。私は数日前にそれを発見して非常に驚きました。すでにコンボボックスのコールバック関数を使用するか、コンボボックスの「addItem」メソッドを使用してリストを作成しようとしました。これらはすべて時間がかかります。
解決 3
私はトリックを発見した...コンボボックスコントロールの「値集合タイプ」プロパティが「表/リスト」に設定する必要があります。ディスプレイは今OKですが、私は今、メモリと別の問題があります。私は自分のフォーム上でこれらのADOレコードセットを使用しているので、アクセスのメモリ使用量は、私は、フォームを閲覧するたびに増加しています。メモリは、閲覧を停止したり、フォームを閉じる、MSアクセスが不安定になって、定期的に凍結することによりいずれかを解放されません。私はこの問題を解決できない場合、私は疑問を開きます。
他のヒント
、あなたはコンボボックスにクエリ結果を表示するために、値集合タイプに「テーブル/リスト」(または「表/Requête」、フランス語であれば)取得する必要があります。
あなたのメモリの問題は、それを閉じずにレコードセット(rsPersonne)を開くから生じます。クローズ/フォームをアンロードするときに、それらを閉じる必要があります(ただし、レコードセットは関数内ではなく、フォーム内で宣言されているので、もう一度、あなたはスコープの問題を持っているでしょう)。
また、作成およびアクセスのビルトインクエリの作成者でクエリを保存し、コンボボックスの値集合ソースに、同じクエリをプラグインしようとすることができます。その方法は、クエリが検証され、アクセス中にコンパイルされます。
あなたは次の操作を行うレコードセットに値集合ソースを受け入れるコントロールを設定するには:
Set recordset = currentDb.OpenRecordset("SELECT * FROM TABLE", dbOpenSnapshot)
Set control.recordset = recordset
は確かにDAOレコードセットで動作します、私はそれらを使用する任意の本当の理由を持っていないので、私は、ADOのレコードセットを試していません。
この方法を完了したら、簡単な再クエリがデータをリフレッシュするために動作しません。は、set文の繰り返しを行う必要があります。
そのヒントのために、感謝をRecordsetプロパティを使用して良い方法!
値リストが唯一あなたがこの制限を超える場合、関数がエラーをスローします、32キロバイトことができます:パトリック、あなたは大きな欠点を持っているあなたのページに示されている方法は(私も自分のことを試してみました)。 コールバックメソッドは、それが非常に遅い大きな欠点を持っており、それが長いリストについては、それが使用不能になり、すべてのエントリに1回呼び出されます。 レコードセットメソッドを使用すると、非常によく動作します。私のSQL文字列は、32キロバイトよりも長かったので、私はこれを必要に応じて(ためのインデックス値の多くはWHERE ID IN(X、X、X、X、X ...))。
ここでコンボボックスにレコードを設定するには、このアイデアを使用して簡単な関数です
' Fills a combobox with the result of a recordset.
'
' Works with any length of recordset results (up to 10000 in ADP)
' Useful if strSQL is longer than 32767 characters
'
' Author: Christian Coppes
' Date: 16.09.2009
'
Public Sub fnADOComboboxSetRS(cmb As ComboBox, strSQL As String)
Dim rs As ADODB.Recordset
Dim lngCount As Long
On Error GoTo fnADOComboboxSetRS_Error
Set rs = fnADOSelectCommon(strSQL, adLockReadOnly, adOpenForwardOnly)
If Not rs Is Nothing Then
If Not (rs.EOF And rs.BOF) Then
Set cmb.Recordset = rs
' enforces the combobox to load completely
lngCount = cmb.ListCount
End If
End If
fnADOComboboxSetRS_Exit:
If Not rs Is Nothing Then
If rs.State = adStateOpen Then rs.Close
Set rs = Nothing
End If
Exit Sub
fnADOComboboxSetRS_Error:
Select Case Err
Case Else
fnErr "modODBC->fnADOComboboxSetRS", True
Resume fnADOComboboxSetRS_Exit
End Select
End Sub
(機能fnADOSelectCommonは、ADOレコードセットを開き、戻ってそれを与える。一つがあった場合、関数fnErrは、エラーのメッセージボックスを示す。)
この関数は、開かれたレコードセットを閉じると、は、メモリに問題があってはなりません。私はそれをテストし、任意のコンボボックスでフォームを閉じた後にリリースされなかったメモリの増加を見ませんでした。
あなたはadditionaly「セットrs = Me.Comboboxname.Recordset」を使用し、それを閉じることができ、フォームのアンロードイベントで。これは、メモリに関して必要はありませんが、(バックエンドデータベースサーバーで使用する場合)、オープン接続を解放するために、より良いかもしれません。
乾杯、
クリスチャン
コンボボックスコントロールには、レコードセットのプロパティを持っていません。これは、値集合ソースプロパティを持っていますが、アクセスがそこにSQL文字列を期待してます。
あなたは、「コールバック」ユーザー定義関数の名前に値集合タイプを変更することができます。アクセスヘルプは、[値集合タイプに自分自身を配置し、F1キーを押すことで、あなたにサンプルコードを含むより多くの情報を提供します。私は、ユーザーが使用可能なレポート、ドライブ文字、またはSQLクエリを経由して利用可能でない他のデータのリストを与えたいとき、私は、関数のこのタイプを使用します。
私は、サーバー側から直接データを使用してについてのあなたの第三段落で何を意味するのか理解していません。か私はこの問題は、標準的なクエリを使用しているかを理解していない。
MS Accessで、それは大丈夫だが、VBで、あなたはADODC(ジェット4.0)を使用して、このようなものを使用することがあります:
Private sub Form1_Load()
with Adodc1
.commandtype = adcmdtext
.recordsource = "Select * from courses"
.refresh
while not .recordset.eof
combo1.additem = .recordset.coursecode
.recordset.movenext
wend
end with
End Sub