Как заполнить ListBox с ADODB.Recordset (Ошибка 91), чтобы сделать автозаполнение в Access
Я работаю с БД Access, и мне нужно использовать соединение источника данных с SQL Server.
Для этого я использую объект ADODB с:
-ADODB.Connection
-ADODB.Recordset
Код Обновлен после наблюдения Яна Кенни
Dim cnn As ADODB.Connection
Set cnn = New ADODB.Connection
Dim rs As ADODB.Recordset
cnn.ConnectionString = "driver={SQL Server};provider=SQLOLEDB;server=10.****;uid=****readonly;pwd=****readonly;database=****"
cnn.Open
Set rs = cnn.Execute("SELECT [MATRI], [NOMPRE] FROM SCHEME_DB.TABLE WHERE NOMPRE LIKE '*" & Me.Textbox_recherche.Text & "*'")
Me.Liste_choix.RowSourceType = "Table/List"
Me.Liste_choix.Recordset = rs
rs.Close
cnn.Close
(Этот код (часть кода) является способом сделать автозаполнение в Access с помощью TextBox и ListBox)
И у меня появляется ошибка 91, когда я запускаю этот код: "Ошибка 91: переменная объекта или переменная блока не установлена" .
Я не понимаю, как решить эту проблему.
Заранее спасибо.
3 ответа
Вы сказали нам, что код выдает ошибку 91 "Переменная объекта или переменная блока не установлена". К сожалению, вы не указали, какая строка вызывает ошибку. Это заставляет нас догадываться, в чем проблема.
Одна проблема здесь:
Me.Liste_choix.Recordset = rs
Это пытается присвоить один объект другому. =
знак достаточно для назначений с простыми типами данных... т.е. MyVariable = 2
, Однако вы должны включить Set
Ключевое слово с объектами.
Set Me.Liste_choix.Recordset = rs
Хотя вы должны внести это изменение, я не уверен, что это было причиной ошибки 91; Я бы предположил, что Access вместо этого будет жаловаться на "недопустимое использование собственности".
SELECT
Это еще одна проблема, но опять же я не уверен, способствует ли она сообщенной вами ошибке. WHERE
пункт использует Like
сравнение с шаблоном, который имеет *
в качестве символа подстановки. Этот запрос может вернуть то, что вы ожидаете при запуске из DAO. Но вы используете ADO, который лечит *
как просто символ звездочки без какого-либо особого значения. Так что этот запрос, вероятно, не возвращает строк, когда вы запускаете его из ADO. замещать *
с %
,
Как общий совет, если ваш кодовый модуль еще не включает Option Explicit
в разделе объявлений, добавьте его. Затем запустите Debug->Compile из главного меню VB Editor. Исправьте все, на что жалуется компилятор. Убедитесь, что вы сделали эти вещи перед дальнейшим устранением неполадок.
Я решил свою проблему (Ошибка 91). Было три проблемы: создание ADODB.Connection, * в Select (благодаря HansUp) и Set для listbox.recordset (еще раз благодаря HansUp)
Я решил ошибку:
Private Sub Textbox_recherche_Change()
Dim cnn As ADODB.Connection
Set cnn = New ADODB.Connection
Dim rs As ADODB.Recordset
'A important point to solve the Error 91 is to declare your ADODB.Connection with .Properties like that : (I don't use Windows NT authentification but the SQL Server authentification)
With cnn
.Provider = "Microsoft.Access.OLEDB.10.0"
.Properties("Data Provider").Value = "SQLOLEDB"
.Properties("Data Source").Value = "10.******"
.Properties("User ID").Value = "*****readonly"
.Properties("Password").Value = "*****readonly"
.Open
End With
'The second point is to replace the * in the search for the autocompletion by the %
Set rs = cnn.Execute("SELECT [NOMPRE] FROM ****.***** WHERE NOMPRE LIKE '%" & Me.Textbox_recherche.Text & "%'")
'You have to declare the RowSourceType of your listbox to "Table/Query"
Me.Liste_choix.RowSourceType = "Table/Query"
'And Finally to SET your recordset like that:
Set Me.Liste_choix.Recordset = rs
rs.Close
cnn.Close
Set cnn = Nothing
Set rs = Nothing
End Sub
Вы закрыли набор записей и подключение, прежде чем использовать его
rs закрыто здесь
rs.Close
и здесь связь закрыта
cnn.Close
Me.Liste_choix.RowSourceType = "Table/List"
rs используется здесь
Me.Liste_choix.Recordset = rs
Обновление из документов:
Использование метода Close для закрытия объекта Connection также закрывает все активные объекты Recordset, связанные с соединением. Объект Command, связанный с объектом Connection, который вы закрываете, сохранится, но он больше не будет связан с объектом Connection; то есть его свойство ActiveConnection будет иметь значение Nothing. Кроме того, коллекция параметров объекта Command будет очищена от любых определенных провайдером параметров.
Использование метода Close для закрытия объекта Recordset, Record или Stream освобождает связанные данные и любой монопольный доступ к данным через этот конкретный объект. Позже вы можете вызвать метод Open, чтобы заново открыть объект с такими же или измененными атрибутами. Когда объект Recordset закрыт, вызов любых методов, для которых требуется динамический курсор, приводит к ошибке.
SQL- инъекция Существует также риск внедрения SQL-кода при создании SQL-файла непосредственно из пользовательского ввода.
Этот вопрос ( подготовленные операторы MS Access) показывает, как использовать параметризованный запрос - может быть, стоит посмотреть.