Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 无法多次打开ADO记录集_Vba_Excel - Fatal编程技术网

Vba 无法多次打开ADO记录集

Vba 无法多次打开ADO记录集,vba,excel,Vba,Excel,我有一个传递SQL字符串、查询SQL server并通过数组返回结果的函数。此函数在第一次运行时效果很好,但我尝试再次调用它,结果如下: 关闭对象时不允许执行操作 奇怪的是,这个错误正好发生在Open语句之后。我在谷歌上搜索了我能想到的所有东西,但没有找到好结果 Public Function SQL_Query(SQLCommand As String) As Variant Dim cn As New ADODB.Connection Dim SQLrs As New ADO

我有一个传递SQL字符串、查询SQL server并通过数组返回结果的函数。此函数在第一次运行时效果很好,但我尝试再次调用它,结果如下:

关闭对象时不允许执行操作

奇怪的是,这个错误正好发生在Open语句之后。我在谷歌上搜索了我能想到的所有东西,但没有找到好结果

Public Function SQL_Query(SQLCommand As String) As Variant
    Dim cn As New ADODB.Connection
    Dim SQLrs As New ADODB.Recordset

    cn.ConnectionString = "Provider=SQLNCLI11;Server=10.XXX.XXXX.XXX;DataBase=Database1;Trusted_Connection=yes;"
    cn.Open
    SQLrs.CursorLocation = adUseClient
    Call SQLrs.Open(SQLCommand, cn, adOpenStatic, adLockBatchOptimistic)

    SQLrs.MoveFirst

    SQL_Query = RecordSet2Array(SQLrs.GetRows)

    SQLrs.Close
    Set SQLrs = Nothing
    cn.Close
    Set cn = Nothing

End Function

如果我读对了-您再次打开了SQL连接,但没有打开记录集(SQLrs)。每次打开和关闭时都必须创建一个新实例,否则在重新运行时会出现这些问题。

我个人没有经历过,但有人告诉我,
Dim x as new y
可能会导致问题

尝试此更改以查看是否有帮助:

Public Function SQL_Query(SQLCommand As String) As Variant
    'changes here vvvvvvvv
    Dim cn As ADODB.Connection
    Dim SQLrs As ADODB.Recordset

    Set cn = New ADODB.Connection
    Set SQLrs = New ADODB.Recordset
    'to here ^^^^^^^^^^^^^^

    cn.ConnectionString = "Provider=SQLNCLI11;Server=10.XXX.XXXX.XXX;DataBase=Database1;Trusted_Connection=yes;"
    cn.Open
    SQLrs.CursorLocation = adUseClient
    Call SQLrs.Open(SQLCommand, cn, adOpenStatic, adLockBatchOptimistic)

    SQLrs.MoveFirst

    SQL_Query = RecordSet2Array(SQLrs.GetRows)

    SQLrs.Close
    Set SQLrs = Nothing
    cn.Close
    Set cn = Nothing

End Function

所以,我终于跟踪到了我在第二次调用函数时使用的SQL查询。它创建一个临时表并返回该临时表中的记录。这显然是一个很好的例子。但是,通过
设置NOCOUNT ON
可以很容易地纠正此错误。因此,我已将代码更新为以下内容,现在一切正常

Public Function SQL_Query(SQLCommand As String) As Variant
    Dim cn As New ADODB.Connection
    Dim SQLrs As New ADODB.Recordset

    cn.ConnectionString = "Provider=SQLNCLI11;Server=10.XXX.XXXX.XXX;DataBase=Database1;Trusted_Connection=yes;"
    cn.Open
    cn.Execute "SET NOCOUNT ON"
    SQLrs.CursorLocation = adUseClient
    Call SQLrs.Open(SQLCommand, cn, adOpenStatic, adLockBatchOptimistic)

    SQLrs.MoveFirst

    SQL_Query = RecordSet2Array(SQLrs.GetRows)

    SQLrs.Close
    Set SQLrs = Nothing
    cn.Close
    Set cn = Nothing

End Function

这是一个被多次调用的函数。第一次调用时返回结果。第二次以及每次之后,SQLrs都会给出“对象已关闭错误”。因此,每次调用函数时,我都应该实例化一个新的记录集对象。因此,我认为我每次都在打开一个新的记录集。然而,情况似乎并非如此。我没有以这种方式在函数中使用ADO,因此可能是我错了——但我在调用子例程时也遇到了类似的问题,该子例程通过在两次使用之间关闭和打开记录集来解决。在上面的代码中,我不是在函数末尾关闭记录集吗
SQLrs.Close
然后在下一次调用时再次打开它
call SQLrs.Open(…)
?我认为您遇到的问题是因为您试图在打开连接之前设置游标位置。在打开之前,我倾向于不处理记录集。希望这有帮助