ADO Recordset Not Staying Open in VBA - “Operation is not allowed when the object is closed”

六月ゝ 毕业季﹏ 提交于 2019-12-01 22:11:06

Please try the following code:

Public Sub AdoTestConnection()
Dim conServer As ADODB.Connection
Dim rstResult As ADODB.Recordset
Dim strDatabase As String
Dim strServer As String
Dim strSQL As String

strServer = "YourServerName"
strDatabase = "YourDatabaseName"

Set conServer = New ADODB.Connection
conServer.ConnectionString = "PROVIDER=SQLOLEDB; " _
    & "DATA SOURCE=" & strServer & "; " _
    & "INITIAL CATALOG=" & strDatabase & "; " _
    & "User ID=" & strLogin & ";" _
    & "Password=" & strPassword
On Error GoTo SQL_ConnectionError
conServer.Open
On Error GoTo 0

Set rstResult = New ADODB.Recordset
strSQL = "set nocount on; "
strSQL = strSQL & "select  1 "
rstResult.ActiveConnection = conServer
On Error GoTo SQL_StatementError
rstResult.Open strSQL
On Error GoTo 0

If Not rstResult.EOF And Not rstResult.BOF Then
    MsgBox "Connection worked. Server returned " & rstResult.Fields(0).Value
Else
    MsgBox "Connection worked. The server did not return any value."
End If

Exit Sub

SQL_ConnectionError:
MsgBox "Problems connecting to the server." & Chr(10) & "Aborting..."
Exit Sub

SQL_StatementError:
MsgBox "Connection established. Yet, there is a problem with the SQL syntax." & Chr(10) & "Aborting..."
Exit Sub

End Sub

If the above code works then you can change the SQL command with your procedure like so:

strSQL = "set nocount on; "
strSQL = strSQL & "exec StoredProcedureName @Parm1 = " & intValue1 & ", "
strSQL = strSQL & "                         @Parm2 = " & intValue2 & ", "
strSQL = strSQL & "                         @Parm3 = " & intValue3 & ", "
strSQL = strSQL & "                         @Parm4 = N'" & strValue1 & "', "
strSQL = strSQL & "                         @Parm5 = N'" & strValue2 & "', "
strSQL = strSQL & "                         @Parm6 = N'" & strValue3 & "', "
strSQL = strSQL & "                         @Parm7 = N'" & strValue4 & "' "

I strongly favor this approach over your current because it is much easier to debug. If you ever run into a problem with your SQL syntax you can simply request the content of strSQL like so:

Debug.Print strSQL

Then you can copy the result of that into SQL Server Management Studio (SSMS) and verify the result there. You may even come to the conclusion that you do not want to use a stored procedure and copy the entire content of the SP into your VBA code.

This is a bit long for a comment so I'll put it here as a possible answer. Please try:

Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
With rs
    Set .ActiveConnection = conn
    .LockType = adLockOptimistic
    .CursorLocation = adUseServer
    .CursorType = adOpenForwardOnly
    .Open "SET NOCOUNT ON"
End With
rs.Open Cmd, , , , adCmdStoredProc

MsgBox ("Success! " & rs.RecordCount & " Records Returned!")

I had a similar issue and found two things that killed the query results over ODBC

  • Count of intermediate values for processing before the final output. Fixed with "set nocount on" at the start of the query

  • null values being aggregated away - running the query directly on SQL Server showed the message "Warning: Null value is eliminated by an aggregate or other SET operation." Fixed by chasing down each of them and either replacing with empty strings, zeros or whatever low value makes sense and doesn't impact the query results.

I think in both cases the warning message was output before the records, so the storage recordset was 'filled' with that warning, but no data. On SQL Server, these warnings silently sit in the message log but don't impact the query results, so the temptation is to let them be and move on to higher priority work.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!