Как заполнить 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) показывает, как использовать параметризованный запрос - может быть, стоит посмотреть.

Другие вопросы по тегам