7

我在 Access DB 上工作,我必须使用数据源连接到 SQL Server。

为此,我使用 ADODB 对象:

-ADODB.连接

-ADODB.Recordset

代码更新,遵循 Ian Kenney 的观察

   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:对象变量或未设置块变量”。

我不明白如何解决这个问题。

提前致谢。

4

3 回答 3

8

我解决了我的问题(错误 91),存在三个问题:ADODB.Connection 的创建、Select 中的 *(感谢 HansUp)和 listbox.recordset 的 Set(再次感谢 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
于 2013-04-30T11:51:04.770 回答
7

您告诉我们代码抛出错误 91, "Object variable or With block variable not set"。不幸的是,您没有指出哪一行触发了错误。这迫使我们猜测问题出在哪里。

这里有一个问题:

Me.Liste_choix.Recordset = rs

这会尝试将一个对象分配给另一个对象。符号对于简单数据类型的=赋值就足够了......即MyVariable = 2。但是,您必须在Set对象分配中包含关键字。

Set Me.Liste_choix.Recordset = rs

尽管您应该进行更改,但我不确定这是错误 91 的原因;我会猜到 Access 会抱怨“无效使用财产”

SELECT声明是另一个问题,但我再次不确定它是否会导致您报告的错误。该WHERE子句使用与作为通配符Like的模式进行比较。*当您从 DAO 运行它时,该查询可能会返回您期望的结果。但是您使用的 ADO*仅将星号视为没有任何特殊含义的字符。因此,当您从 ADO 运行该查询时,它可能不会返回任何行。替换*%

作为一般建议,如果您的代码模块尚未包含Option Explicit在其声明部分中,请添加它。然后从 VB 编辑器的主菜单运行 Debug->Compile。修复编译器抱怨的任何问题。在进一步排除故障之前,请确保您已完成这些操作。

于 2013-04-26T13:46:37.923 回答
4

您在使用之前关闭了记录集和连接

rs在这里关闭

   rs.Close  

并且连接在这里关闭

   cnn.Close

Me.Liste_choix.RowSourceType = "Table/List"

这里使用的 rs

Me.Liste_choix.Recordset = rs

文档更新

使用 Close 方法关闭 Connection 对象也会关闭与该连接关联的所有活动 Recordset 对象。与您正在关闭的 Connection 对象关联的 Command 对象将持续存在,但将不再与 Connection 对象关联;也就是说,它的 ActiveConnection 属性将设置为 Nothing。此外,Command 对象的参数集合将清除任何提供者定义的参数。

使用 Close 方法关闭 Recordset、Record 或 Stream 对象会释放关联的数据以及您可能通过此特定对象对数据拥有的任何独占访问权。您可以稍后调用 Open 方法以重新打开具有相同或已修改属性的对象。关闭 Recordset 对象时,调用任何需要实时游标的方法都会产生错误。

SQL注入 直接从用户输入构建 sql 也存在sql 注入风险。
这个问题(MS Accessprepared statements)显示了如何使用参数化查询 - 可能值得一看。

于 2013-04-26T08:09:27.997 回答