2009-06-08 252 views
7

expert's exchangeteck republic有一些關於使用combobox.recordset屬性在Access窗體中填充組合框的文獻。如何使用VBA填充具有Recordset的組合框

這些控件通常在控件的「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年

不幸的是,這是行不通的!

在調試模式下,我能夠檢查記錄集是否已正確創建,具有所需的列和數據,並與組合框控件正確關聯。不幸的是,當我顯示錶單時,我總是收到一個空的組合框,沒有記錄!任何幫助,高度讚賞。

編輯:

此記錄財產的確是可用於特定的組合框對象,而不是標準的控制對象,我很驚訝地發現它在幾天前。 我已經嘗試過使用組合框的回調函數,或者用組合框的「addItem」方法填充列表。所有這些都很耗時。

回答

3

我發現了這個技巧......組合框控件的「rowSourceType」屬性必須設置爲「Table/List」。顯示現在好了,但我現在有另一個內存問題。由於我在表單上使用這些ADO記錄集,因此每次瀏覽表單時Access的內存使用量都在增加。內存不是通過停止瀏覽或關閉表單來釋放,使MS Access不穩定並定期凍結。如果我不能解決這個問題,我會打開一個問題

+0

不爲我工作:/有一個錯誤91:集團不存在 – 2013-04-25 13:51:19

+0

如果你想建議你應該給出錯誤的代碼,並確定引發錯誤的行。 – 2013-04-26 08:40:15

+0

錯誤的描述在這裏:http://stackoverflow.com/questions/16231456/how-to-populate-a-listbox-with-a-adodb-recordset-error-91 – 2013-04-26 11:23:05

0

組合框控件沒有記錄集屬性。它確實有一個RowSource屬性,但Access期望在那裏有一個SQL字符串。

您可以將RowSourceType更改爲用戶定義的「回調」函數的名稱。訪問幫助將通過將您自己定位在RowSourceType上並按F1來爲您提供更多信息,其中包括示例代碼。當我想向用戶提供可用報告,驅動器號或其他無法通過SQL查詢獲得的數據時,我使用這種類型的功能。

我不明白你的意思是你的第三段就直接從服務器端使用數據。或者說,我不明白使用標準查詢會出現什麼問題。

+0

謝謝託尼。此記錄集屬性確實可用於特定組合框對象,而不是標準控制對象。我也使用這個回調函數來處理類似於你的情況。我的問題是找到一種方法來在客戶端使用來自服務器端的數據填充組合框。到目前爲止,我正在創建本地臨時表來執行此操作,但這非常耗時。我希望使用記錄集會更有效率。 – 2009-06-09 04:18:01

+0

爲什麼您認爲將記錄集分配到組合框會更有效率,讓Access/Jet管理SQL字符串的數據檢索?你的意思是你正在使用一個斷開的記錄集?我無法想象爲什麼有人會需要你所要求的 - 這對我來說毫無意義。 – 2009-06-10 04:03:10

+0

是的,ADO記錄集被斷開 – 2009-07-15 15:36:54

5

如前所述,您必須將RowSourceType設置爲「Table/List」(如果使用法語,則爲「Table /Requête」)以顯示查詢結果組合框。

您的內存問題是由於打開記錄集(rsPersonne)而未關閉它而引起的。關閉/卸載表單時應關閉它們(但是,由於記錄集是在函數中聲明的,而不是在表單中),因此您將再次遇到範圍問題。

您也可以嘗試使用Access的內置查詢創建器創建並保存查詢,並在組合框的RowSource中插入相同的查詢。這樣查詢在Access中被驗證和編譯。

+0

我會檢查您關於內存問題的建議並儘快回覆您。 – 2009-07-15 15:34:42

2

使用Recordset屬性的好方法,謝謝你的提示!

帕特里克,您的網頁上顯示的方法有一個很大的缺點(我試過,也對我自己):值列表只能是32 KB,如果超過此限制的功能將拋出一個錯誤。 回調方法有一個很大的缺點,它非常緩慢,每調用一次就會被調用一次,從而導致長列表不可用。 使用記錄集方法工作得很好。我需要這個,因爲我的SQL字符串長於32 KB(很多索引值爲WHERE ID IN(x,x,x,x,x ...))。

這裏有一個簡單的功能,使用這個想法來設置一個記錄到ComboBox:

' 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顯示了錯誤的消息框,如果有的話)。

由於這個函數關閉了打開的記錄集,所以內存應該沒有問題。我測試了它,並沒有看到任何增加的內存,這是在用組合框關閉窗體後才釋放的。

在窗體的Unload事件中,您可以添加使用「Set rs = Me.Comboboxname.Recordset」,然後關閉它。這對於內存來說不是必須的,但是釋放打開的連接(如果與後端數據庫服務器一起使用)可能會更好。

乾杯,

基督教

+0

當然,我的方法是有限的。我構建它是因爲我必須從一個(herited)非常慢的查詢(1分鐘左右)填充列表。使用字符串技巧可以非常快速地重新排列列上的列表,而無需重新運行長查詢。 – 2009-09-17 10:44:37

0

在MS Access,這是確定的,但在VB中,你可以使用像這樣使用ADODC(Jet 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

要設置一個控制它接受一個記錄集的行源,你需要做以下操作:

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

與DAO Recordse當然,我還沒有嘗試ADO記錄集,因爲我沒有任何真正的理由來使用它們。

完成後這樣,一個簡單的重新查詢將行不通刷新數據,你必須做的一組語句重複。

+0

就我個人而言,我忘了使用Set字將一個記錄集分配給我的控件。謝謝! – 2015-10-27 17:11:49