J'utilise les procédures suivantes dans certaines procédures Excel pour établir une connexion à notre base de données.
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
Dans le code suivant, j'ouvre la connexion à l'aide de différentes chaînes SQL.
Je voudrais tester si rs
est ouvert afin que je sache qu'il doit être fermé, mais ce qui suit ne fonctionne pas. Comment puis-je changer la condition dans ce qui suit pour fonctionner?
If (rs.Open = True) Then
rs.Close
End If
Ce qui suit fonctionne, mais je préférerais ne pas utiliser le recouvrement des erreurs de cette manière:
On Error Resume Next
rs.Close
ADO Recordset a la propriété .State
, vous pouvez vérifier si sa valeur est adStateClosed
ou adStateOpen
If Not (rs Is Nothing) Then
If (rs.State And adStateOpen) = adStateOpen Then rs.Close
Set rs = Nothing
End If
MSDN à propos de la propriété de l'État
Edit; La raison pour ne pas cocher .State
par rapport à 1 ou 0 est que même si cela fonctionne 99,99% du temps, il est toujours possible d’avoir d’autres drapeaux définis ce qui fera que l’instruction If échouera avec la vérification adStateOpen
.
Edit2:
Pour les liaisons tardives sans les objets de données ActiveX référencés, vous avez peu d'options . Utilisez la valeur de la constante adStateOpen de ObjectStateEnum
If Not (rs Is Nothing) Then
If (rs.State And 1) = 1 Then rs.Close
Set rs = Nothing
End If
Ou vous pouvez définir vous-même la constante pour rendre votre code plus lisible (en les définissant tous pour un bon exemple).
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
Ce sujet est ancien, mais si d'autres personnes comme moi recherchent une solution, c'est une solution que j'ai trouvée:
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
Donc "myBase" est un objet de base de données, j'ai créé une classe pour accéder à la base de données (classe avec insert, update etc ...) et sur le module la classe est utilisée, déclarer dans un objet (évidemment) et je peux tester la connexion avec "[l'objet] .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: Dans DBOpen, j'utilise "OpenDatabase" et dans DBC, j'utilise ".Close" et "set myBase = none" Edit 2: Dans la fonction, si vous n'êtes pas connecté, .version vous renvoie une erreur donc si aren ne vous connectez pas, le errorHandler vous donne de faux