Проверьте, открыто ли соединение ADODB

Я использую следующие из некоторых процедур excel для установления соединения с нашей базой данных.

Private Const strConn As String = _
    "PROVIDER=SQLOLEDB.1 ..."     

Sub OpenConnection()

Set cn = CreateObject("ADODB.Connection")
cn.Open strConn
cn.CommandTimeout = 0
Set rs = CreateObject("ADODB.Recordset")
Set rs.ActiveConnection = cn

End Sub 

в последующем коде я открываю соединение, используя различные строки SQL.
Я хотел бы проверить, если rs открыт, поэтому я знаю, что он должен быть закрыт, но следующее не работает. Как я могу изменить условие в следующей работе?

If (rs.Open = True) Then
    rs.Close
End If

следующие работы, но я бы предпочел не использовать перехват ошибок таким образом:

On Error Resume Next
    rs.Close

2 ответов


ADO Recordset имеет .State собственность, вы можете проверить, если его значение adStateClosed или adStateOpen

If Not (rs Is Nothing) Then
  If (rs.State And adStateOpen) = adStateOpen Then rs.Close
  Set rs = Nothing
End If

MSDN о государственной собственности

изменить; Причина не проверять .State против 1 или 0, потому что даже если он работает 99,99% времени, это еще можно есть!--15-->другие флаги набор что приведет к сбою оператора If adStateOpen проверка.

Edit2:

для поздней привязки Без данных ActiveX Объекты, на которые ссылаются, у вас есть несколько вариантов. Используйте значение константы adStateOpen из ObjectStateEnum

If Not (rs Is Nothing) Then
  If (rs.State And 1) = 1 Then rs.Close
  Set rs = Nothing
End If

или вы можете сами определить константу, чтобы сделать ваш код более читаемым (определяя их все для хорошего примера.)

Const adStateClosed As Long = 0 'Indicates that the object is closed.
Const adStateOpen As Long = 1 'Indicates that the object is open.
Const adStateConnecting As Long = 2 'Indicates that the object is connecting.
Const adStateExecuting As Long = 4 'Indicates that the object is executing a command.
Const adStateFetching As Long = 8 'Indicates that the rows of the object are being retrieved.    

[...]

If Not (rs Is Nothing) Then

    ' ex. If (0001 And 0001) = 0001 (only open flag) -> true
    ' ex. If (1001 And 0001) = 0001 (open and retrieve) -> true
    '    This second example means it is open, but its value is not 1
    '    and If rs.State = 1 -> false, even though it is open
    If (rs.State And adStateOpen) = adStateOpen Then 
        rs.Close
    End If

    Set rs = Nothing
End If

эта тема старая, но если другие люди, такие как я, ищут решение, это решение, которое я нашел:

Public Function DBStats() As Boolean
    On Error GoTo errorHandler
        If Not IsNull(myBase.Version) Then 
            DBStats = True
        End If
        Exit Function
    errorHandler:
        DBStats = False  
End Function

Итак, "myBase" - это объект базы данных, я сделал класс для доступа к базе данных (класс с insert, update и т. д...) и на модуле класс использует объявление в объекте (очевидно), и я могу проверить соединение с "[объектом].DBStats":

Dim BaseAccess As New myClass
BaseAccess.DBOpen 'I open connection
Debug.Print BaseAccess.DBStats ' I test and that tell me true
BaseAccess.DBClose ' I close the connection
Debug.Print BaseAccess.DBStats ' I test and tell me false

Edit: в DBOpen я использую "OpenDatabase" и в DBClose я использую ".Закрыть " и " установить myBase = ничего" Edit 2: в функции, если вы не подключаетесь, .версия дает вам ошибку, поэтому, если вы не подключаетесь, errorHandler дает вам false