2009-06-08 38 views
7

expert's exchangeおよびteck republicには、combobox.recordsetプロパティを使用してAccessフォームにコンボボックスを設定する方法についての資料があります。ComboBoxにVBAを使用してレコードセットを設定する方法

これらのコントロールには、通常、コントロールの '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 

  • connexionActive:私のデータベースサーバへの私の永久的なADO接続です
  • FC() :現在の/アクティブなフォームです
  • コントロール( "id_Personne"): コンボボックスコントロールには、 会社スタッフリスト
  • Accessバージョン2003

では残念ながら、それは動作しません!

デバッグモードでは、レコードセットが正しく作成され、要求された列とデータで、コンボボックスコントロールに適切に関連付けられていることを確認できます。残念ながら、私がフォームを表示すると、空のコンボボックスが残っていて、そこにレコードはありません!どんな助けも高く評価されます。

EDIT:

このレコードセットプロパティが実際に特定のコンボボックスオブジェクトのではなく、標準のコントロールオブジェクトのために利用可能である、と私は数日前にそれを発見することは非常に驚きました。 私はすでにコンボボックスのコールバック関数を使用しようとしましたが、コンボボックスの "addItem"メソッドでリストを設定しようとしました。これらはすべて時間がかかります。

答えて

3

私はトリックを見つけました...コンボボックスコントロールの "rowSourceType"プロパティは "Table/List"に設定する必要があります。表示は今は大丈夫ですが、私は今メモリと別の問題があります。フォーム上でこれらのADOレコードセットを使用するため、フォームを参照するたびにAccessのメモリ使用量が増加しています。ブラウジングを停止するか、フォームを閉じてMS Accessを不安定にし、定期的にフリーズすることによって、メモリが解放されません。この問題を解決できない場合は質問を開きます

+0

私にはうまくいかない:/エラー91:ブロックが存在しない –

+0

アドバイスが必要な場合は、エラーのあるコードを与え、エラーを投げるラインを特定する必要があります。 –

+0

ここでのエラーの説明:http://stackoverflow.com/questions/16231456/how-to-populate-a-listbox-with-a-adodb-recordset-error-91 –

0

コンボボックスコントロールには、レコードセットプロパティはありません。それはRowSourceプロパティを持っていますが、そこにはSQL文字列が必要です。

RowSourceTypeをユーザー定義のコールバック関数の名前に変更できます。 Access Helpを使用すると、RowSourceTypeに自分自身を置き、F1キーを押して、サンプルコードを含むより多くの情報を得ることができます。利用可能なレポート、ドライブレター、またはSQLクエリでは利用できないその他のデータのリストをユーザに提供したい場合、このタイプの関数を使用します。

サーバー側から直接データを使用することに関して、3番目の段落の意味を理解していません。または、むしろ、標準クエリを使用して問題が何かを理解できません。

+0

ありがとうTony。このレコードセットプロパティは、特定のコンボボックスオブジェクトに対して実際に使用可能であり、標準コントロールオブジェクトに対しては使用できません。私はあなたのような状況にもこのコールバック関数を使用しています。私の問題は、クライアント側のコンボボックスにサーバー側からのデータを入力する方法を見つけることです。これまではローカルの一時テーブルを作成していましたが、実際には時間がかかります。私は、レコードセットの使用がより効率的になることを望んでいました。 –

+0

コンボボックスにレコードセットを割り当てると、Access/JetでSQL文字列のデータ取得を管理できるため、効率が向上するのはなぜですか?切断されたレコードセットを使用しているということですか?なぜあなたは何を求めているのだろうと誰も想像することができません - それは私には何の意味もありません。 –

+0

はい、ADOレコードセットが切断されています –

5

このように、クエリ結果を表示するには、RowSourceTypeを "Table/List"(またはフランス語の場合は "Table /Requête")に設定する必要があります。コンボボックス。

メモリの問題は、レコードセット(rsPersonne)を閉じずに開くことによって発生します。フォームを閉じる/アンロードするときに閉じなければなりません(ただし、レコードセットは関数内で宣言され、フォームでは宣言されていないため、スコープに問題があります)。

また、Accessの組み込みクエリ作成者でクエリを作成して保存し、同じクエリをコンボボックスのRowSourceにプラグインすることもできます。こうすることで、クエリはAccess内で検証され、コンパイルされます。

+0

私はメモリの問題についてあなたの提案をチェックし、できるだけ早くあなたに戻ってきます。 –

2

このヒントのおかげで、Recordsetプロパティを使用すると良い方法です!

あなたのページに表示されている方法には大きな欠点があります(私自身もそれを試しました)。値のリストは32 KBに過ぎません。この制限を超えるとエラーが発生します。 コールバックメソッドは非常に遅いという大きな欠点があります。また、コールバックメソッドはすべてのエントリに対して1回呼び出されるため、長いリストでは使用できなくなります。 レコードセットメソッドを使用すると非常にうまく動作します。これは、SQLの文字列が32 KB(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はエラーとメッセージボックスを表示します、もしあれば)。

この関数は開いているレコードセットを閉じてしまうので、メモリに問題はないはずです。私はそれをテストし、コンボボックスでフォームを閉じた後に解放されなかったメモリの増加を見なかった。

フォームのアンロードイベントでは、さらに "Set rs = Me.Comboboxname.Recordset"を使用して閉じます。これはメモリに関しては必要ではありませんが、オープン接続(バックエンドデータベースサーバと一緒に使用されている場合)を解放するほうが良いかもしれません。

乾杯、MS Accessで

クリスチャン

+0

確かに私の方法は限られています。 (herited)非常に遅いクエリ(1分程度)からリストを作成しなければならなかったので、私はそれを構築しました。文字列trickを使用すると、長い問合せを再実行せずに非常に迅速に任意の列のリストを再ソートできました。 –

0

は、それは大丈夫だが、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 
3

を次のようにレコードセットにrowsourceを受け入れます。

Set recordset = currentDb.OpenRecordset("SELECT * FROM TABLE", dbOpenSnapshot) 
Set control.recordset = recordset 

DAO Recordse私がADOレコードセットを試したことはありません。私はADOレコードセットを使用する本当の理由がないからです。

このようにすると、簡単なクエリーがデータを更新するためには機能しません。set文を繰り返し実行する必要があります。

+0

個人的には、コントロールにレコードセットを割り当てるためにSet単語を使用するのを忘れていました。ありがとう! –

関連する問題