Как заполнить ComboBox набором записей с помощью VBA
есть некоторая литература, доступная в обмен экспертов и теке республики об использовании combobox.recordset свойство для заполнения combobox в форме доступа.
эти элементы управления обычно заполняются строкой "SELECT *" в свойствах элемента управления "rowsource", ссылающейся на таблицу или запрос, доступные на стороне клиента приложения. Когда мне нужно отобразить данные на стороне сервера в combobox, я создаю временную локальную таблицу и импортировать запрошенные записи. Это отнимает много времени, особенно с большими таблицами.
возможность использовать набор записей для заполнения элемента управления combobox позволит пользователю напрямую отображать данные со стороны сервера.
вдохновленный 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"): управление combobox для заполнения штатное расписание компании
- версия доступа в 2003
к сожалению, это не работает!
в режиме отладки я могу проверить, что набор записей правильно создан, с запрошенными столбцами и данными и правильно связан с элементом управления combobox. К сожалению, когда я показываю форму, я продолжаю получать пустой combobox, без записей в нем! Любая помощь очень оцененный.
изменить:
это свойство набора записей действительно доступно для конкретного объекта combobox, а не для стандартного объекта управления, и я был очень удивлен, обнаружив его несколько дней назад. Я уже пытался использовать функцию обратного вызова combobox или заполнить список методом "addItem" combobox. Все это отнимает много времени.
6 ответов
Как было сказано, Вы должны получить RowSourceType в "Table/List" (или "Table / Requête", если на французском языке), чтобы показать результаты запроса в combobox.
проблемы с памятью возникают при открытии набора записей (rsPersonne) без его закрытия. Вы должны закрыть их при закрытии / выгрузке формы (но опять же у вас будут проблемы с областью, так как набор записей объявлен в функции, а не в форме).
вы также можете попытаться создать и сохранить запрос с помощью Встроенный создатель запросов Access и подключите тот же запрос к источнику строк вашего combobox. Таким образом, запрос проверяется и компилируется в Access.
чтобы задать элемент управления, который принимает rowsource в набор записей, выполните следующие действия:
Set recordset = currentDb.OpenRecordset("SELECT * FROM TABLE", dbOpenSnapshot)
Set control.recordset = recordset
работает с наборами записей DAO наверняка, я не пробовал наборы записей ADO, потому что у меня нет реальной причины их использовать.
когда это сделано таким образом, простой запрос не будет работать для обновления данных, вы должны повторить инструкцию set.
Я нашел трюк ... свойство " rowSourceType "элемента управления combobox должно быть установлено в"Таблица/список". Дисплей теперь в порядке, но теперь у меня есть еще одна проблема с памятью. Поскольку я использую эти наборы записей ADO в своих формах, использование памяти Access увеличивается каждый раз, когда я просматриваю форму. Память не освобождается ни при остановке просмотра, ни при закрытии формы, что делает MS Access нестабильным и регулярно замораживается. Я открою вопрос, если я не могу решить эту проблему
хороший метод с использованием свойства Recordset, спасибо за этот намек!
Патрик, метод, который вы показали на своей странице, имеет большой недостаток (я тоже пробовал это самостоятельно): список значений может быть только 32 КБ, если вы превысите этот предел, функция выдаст ошибку. Метод обратного вызова имеет большой недостаток, что он очень медленный и вызывается один раз для каждой записи, что делает его непригодным для более длинного списка. Использование метода recordset работает очень хорошо. Мне это было нужно, потому что моя строка SQL была длиннее 32 КБ (много значений индекса для 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 показывает окно сообщения с ошибкой, если она была.)
поскольку эта функция закрывает открытый набор записей, проблем с памятью быть не должно. Я проверил и не увидел. любое увеличение памяти, которое не было выпущено после закрытия формы с помощью comboboxes.
в случае выгрузки формы вы можете дополнительно использовать " Set rs=Me.Comboboxname.Записей", а затем закройте его. Это не должно быть необходимо в отношении памяти, но может быть лучше освободить открытые соединения (если используется с серверным сервером базы данных).
спасибо,
христианин
элемент управления со списком не имеет свойства набора записей. У него есть свойство RowSource, но Access ожидает там строку SQL.
вы можете изменить тип RowSourceType на имя определяемой пользователем функции "обратного вызова". Доступ к справке даст вам больше информации, включая пример кода, расположив себя на RowSourceType и нажав F1. Я использую этот тип функции, когда хочу предоставить пользователям список доступных отчетов, букв дисков или других данных это недоступно через SQL-запрос.
Я не понимаю, что вы подразумеваете под третьим абзацем в отношении использования данных непосредственно со стороны сервера. Или, скорее, я не понимаю, в чем проблема с использованием стандартных запросов.
в 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