2009-06-08 3 views
7

Существует бесплатная литература по адресу expert's exchange и по адресу teck republic об использовании свойства combobox.recordset для заполнения combobox в форме доступа.Как заполнить ComboBox набором записей с помощью VBA

Эти элементы управления обычно заполняются строкой «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 к серверу базы данных
  • Ь() : моя текущая/активная форма
  • элементы управления («id_Personne»): это элемент управления со списком для заполнения компанией «S список сотрудников
  • версия Access в 2003

К сожалению, это не работает!

В режиме отладки я могу проверить, правильно ли создан набор записей, с запрошенными столбцами и данными и правильно связан с элементом управления combobox. К сожалению, когда я показываю форму, я получаю пустое поле со списком, без записей! Любая помощь высоко ценится.

EDIT:

Это свойство записей действительно доступно для конкретного объекта поля со списком, а не для стандартного объекта управления, и я был очень удивлен, обнаружив его несколько дней назад. Я уже пытался использовать функцию обратного вызова combobox или заполнить список методом «addItem» для combobox. Все это требует много времени.

ответ

3

Я нашел трюк ... свойство «rowSourceType» элемента управления combobox должно быть установлено в «Таблица/Список». Дисплей теперь в порядке, но теперь у меня есть еще одна проблема с памятью. Поскольку я использую эти записи 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, но Access ожидает строку SQL.

Вы можете изменить RowSourceType на имя пользовательской функции «обратного вызова». Access поможет вам получить дополнительную информацию, включая пример кода, позиционируя себя в RowSourceType и нажав F1. Я использую этот тип функции, когда хочу предоставить пользователям список доступных отчетов, букв дисков или других данных, которые недоступны с помощью SQL-запроса.

Я не понимаю, что вы подразумеваете под третьим абзацем относительно использования данных непосредственно со стороны сервера. Вернее, я не понимаю, в чем проблема с использованием стандартных запросов.

+0

Спасибо Тони. Это свойство recordset действительно доступно для конкретного объекта combobox, а не для стандартного объекта управления. Я также использую эту функцию обратного вызова для ситуаций, подобных вашим. Моя проблема заключается в том, чтобы найти способ заполнить поле со списком со стороны клиента с данными со стороны сервера. До сих пор я создавал локальные временные таблицы для этого, но это действительно требует много времени.Я надеялся, что использование набора записей будет более эффективным. –

+0

Почему вы считаете, что назначение набора записей в поле со списком будет более эффективным, позволяя Access/Jet управлять извлечением данных из строки SQL? Вы имеете в виду, что используете отключенный набор записей? Я не могу себе представить, почему кому-то понадобится то, о чем вы просите, - это не имеет для меня никакого смысла. –

+0

Да, набор записей ADO отключен –

5

Как уже было сказано, вы должны получить RowSourceType в «Table/List» (или «Table/Requête», если на французском), чтобы показать результаты запроса в поле со списком.

Проблемы с памятью возникают из-за открытия набора записей (rsPersonne), не закрывая его. Вы должны закрыть их при закрытии/выгрузке формы (но опять же у вас возникнут проблемы с областью, так как набор записей объявлен в функции, а не в форме).

Вы также можете попытаться создать и сохранить запрос с помощью встроенного в запрос создателя запросов и подключить этот же запрос в RowSource вашего combobox. Таким образом, запрос проверяется и компилируется в Access.

+0

Я проверю ваше предложение о проблеме с памятью и вернусь к вам как можно скорее. –

2

хороший способ с использованием свойства Recordset, спасибо за этот намек!

Patrick, метод, который вы показывали на своей странице, имеет большой недостаток (я тоже это пробовал самостоятельно): список значений может быть только 32 КБ, если вы превысите это ограничение, функция вызовет ошибку. Метод обратного вызова имеет большой недостаток в том, что он очень медленный, и он вызывается один раз для каждой записи, что делает ее непригодной для более длинного списка. Использование метода набора записей работает очень хорошо. Мне это нужно, потому что моя строка 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 показывает окно с ошибкой , если таковой был.)

Поскольку эта функция закрывает открытый набор записей, проблем с памятью не должно быть. Я тестировал его и не видел увеличения памяти, которое не было выпущено после закрытия формы с помощью comboboxes.

В случае разгрузки формы формы вы можете дополнительно использовать «Установить rs = Me.Comboboxname.Recordset», а затем закрыть его. Это не должно быть необходимо в отношении памяти, но может быть лучше освободить открытые соединения (если используется с сервером базы данных бэкэнд).

Приветствия,

Christian

+0

Уверен, что мой метод ограничен. Я построил его, потому что мне пришлось заполнить список из (узкого) очень медленного запроса (1 минута или около того). Использование трюка строки позволило быстро отсортировать список в любом столбце, не перезапуская длинный запрос. –

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 ts наверняка, я не пробовал записи ADO, потому что у меня нет реальной причины их использовать.

Когда это делается, простейшая просьба не будет работать для обновления данных, вы должны сделать повторение оператора set.

+0

Лично я забыл использовать слово Set для присвоения набора записей для моего контроля. Благодаря! –

Смежные вопросы