2013-04-26 78 views
7

我使用Access数据库,并且必须使用到SQL Server的数据源连接。如何使用ADODB.Recordset填充ListBox(错误91)在Access中执行自动填充

要做到这一点我使用ADODB对象有:

-ADODB.Connection

-ADODB.Recordset

代码跟上时代的,下面伊恩的观察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中使用文本框和列表框执行自动完成的方法)

而且我运行此代码时出现错误91:“错误91:对象变量或块变量未设置“。

我不明白如何解决此问题。

在此先感谢。

回答

5

您告诉我们,代码会抛出错误91,“对象变量或块变量未设置”。不幸的是,你没有指出哪一行会触发错误。这迫使我们猜测问题出在哪里。

的一个问题是在这里:

Me.Liste_choix.Recordset = rs 

试图到另一个对象的分配。 =符号足以用于简单数据类型的分配...即MyVariable = 2。但是,您必须在对象分配中包含Set关键字。

Set Me.Liste_choix.Recordset = rs 

虽然你应该做出这样的改变,但我并不确定这是导致错误91的原因;我会猜测访问会抱怨“无效的财产使用”而不是。

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

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

+0

谢谢,我给你的赏金,但我认为一个重要的问题是如何声明ADODB.Connection对象的方式。我们必须声明这个对象.Properties(不知道具体为什么......)就像我的回答中一样...... – 2013-04-30 12:14:03

4

使用前

RS这里关闭

rs.Close 

您已经关闭了记录和连接,并连接在这里关闭这里使用

cnn.Close 

Me.Liste_choix.RowSourceType = "Table/List" 

RS

Me.Liste_choix.Recordset = rs 

更新docs

使用Close方法关闭连接对象还关闭与该连接相关联的任何 活性记录的对象。与正在关闭的Connection对象关联的对象 将保留 ,但它不再与Connection对象关联; 也就是说,它的ActiveConnection属性将被设置为Nothing。同样, Command对象的Parameters集合将被清除任何 提供程序定义的参数。

使用Close方法关闭记录集,记录或流对象 将释放相关数据以及您可能通过此特定对象获得的对数据的任何专有访问权限 。您稍后可以调用 打开方法重新打开具有相同或修改的属性的对象。当Recordset对象关闭时,调用任何需要实时游标的方法 都会产生错误。

SQL INJECTION 也有直接从用户输入构建SQL的sql injection风险。
此问题(MS Access prepared statements)显示了如何使用参数化查询 - 值得一看。

+0

这不是错误的原因,当我移动rs.Close和cnn.Close下Me.Liste_choix.Recordset = RS,我已经得到了错误。 – 2013-04-26 08:19:30

+0

您是否尝试将rs.close/cnn.close移到使用记录集后? – 2013-04-26 08:30:02

+0

是... Me.Liste_choix.RowSourceType = “表/列表” Me.Liste_choix.Recordset = RS rs.Close cnn.Close – 2013-04-26 08:34:41

7

我解决我的问题(错误91),有三个问题:在ADODB.Connection,在选择*(感谢HansUp),并设置为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