In einigen Excel-Prozeduren verwende ich Folgendes, um eine Verbindung zu unserer Datenbank herzustellen.
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
Im nachfolgenden Code öffne ich die Verbindung mit verschiedenen SQL-Strings.
Ich möchte testen, ob rs
geöffnet ist. Ich weiß, dass es geschlossen werden muss, aber Folgendes funktioniert nicht Wie kann ich die Bedingung im Folgenden ändern, um zu funktionieren?
If (rs.Open = True) Then
rs.Close
End If
Folgendes funktioniert, aber ich möchte die Fehlerbehebung auf diese Weise nicht verwenden:
On Error Resume Next
rs.Close
ADO-Recordset verfügt über die .State
-Eigenschaft. Sie können überprüfen, ob der Wert adStateClosed
oder adStateOpen
lautet.
If Not (rs Is Nothing) Then
If (rs.State And adStateOpen) = adStateOpen Then rs.Close
Set rs = Nothing
End If
Bearbeiten; Der Grund, .State
nicht gegen 1 oder 0 zu prüfen, ist, da es auch bei 99,99% der Zeit möglich ist, andere Flags gesetzt zu haben , was dazu führt, dass die If-Anweisung die adStateOpen
-Prüfung nicht besteht .
Edit2:
Für die späte Bindung ohne die referenzierten ActiveX-Datenobjekte haben Sie einige Optionen. Verwenden Sie den Wert der Konstante adStateOpen aus ObjectStateEnum
If Not (rs Is Nothing) Then
If (rs.State And 1) = 1 Then rs.Close
Set rs = Nothing
End If
Oder Sie können die Konstante selbst definieren, um Ihren Code lesbarer zu machen (indem Sie alle für ein gutes Beispiel definieren.)
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
Dieses Thema ist alt, aber wenn andere Leute wie ich eine Lösung suchen, ist dies eine Lösung, die ich gefunden habe:
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" ist also ein Datenbankobjekt. Ich habe eine Klasse für den Zugriff auf die Datenbank erstellt (Klasse mit Einfügen, Update usw.). Auf dem Modul wird die Klasse use deklariert (offensichtlich) und ich kann die Verbindung testen mit "[das Objekt] .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: In DBOpen verwende ich "OpenDatabase" und in DBClose verwende ich ".Close" und "set myBase = nothing" Edit 2: Wenn Sie keine Verbindung herstellen, gibt .version einen Fehler an Verbinden Sie sich nicht, der errorHandler gibt Ihnen false