2013-07-12 18 views
14

Uso le seguenti procedure all'interno di alcune procedure excel per stabilire una connessione al nostro database.Verificare se la connessione ADODB è aperta

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 

Nel codice successivo apro la connessione utilizzando varie stringhe SQL.
Mi piacerebbe testare se rs è aperto, quindi so che deve essere chiuso, ma quanto segue non funziona. Come posso cambiare la condizione di seguito per lavorare?

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

le seguenti opere, ma io non preferisco usare l'intercettazione degli errori in questo modo:

On Error Resume Next 
    rs.Close 

risposta

25

ADO Recordset ha .State proprietà, è possibile verificare se il suo valore è adStateClosed o adStateOpen

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

MSDN about State property

Modifica; La ragione per non controllare .State contro 1 o 0 è perché anche se funziona il 99,99% delle volte, è ancora possibile avere other flags set che farà sì che l'istruzione If fallisca il controllo adStateOpen.

Edit2:

per la fine del legame senza ActiveX Data Objects di riferimento, avete alcune opzioni. Utilizzare il valore di adStateOpen costante da ObjectStateEnum

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

Oppure si può definire la costante se stessi per rendere il codice più leggibile (li definisce per un buon esempio.)

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 
+0

ok - solo indovinando ma c'è un errore di battitura nella risposta? ... fammi provare a modificare ... dovrebbe leggere 'If (rs.State And rs.adStateOpen) = rs.adStateOpen Then': anche se continuo a non capire questa affermazione condizionale. A cosa valuterà se rs è aperto? 'Se (1 E?) =? Quindi ' – whytheq

+0

E 'operativo bit per' '. Il bit che è 'adStateOpen' rimarrà impostato solo se quel bit in' .State' è impostato e tutti gli altri bit sono azzerati. Il risultato del confronto del valore dell'operazione 'And' in' adStateOpen' darà come risultato 'True' solo se il bit-bit è stato impostato in' .State'. – Raybarg

+0

Heh, probabilmente la tua confusione era a posto. Non volevo usare 'rs.adStateOpen' ma' adStateOpen'. – Raybarg

0

Questo argomento è vecchio ma se altre persone come me cercano una soluzione, questa è una soluzione che ho trovato:

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 

Così "myBase" è un oggetto di database, I h ho fatto una classe per accedere al database (classe con insert, update etc ...) e sul modulo la classe è use dichiarare in un oggetto (ovviamente) e posso testare la connessione con "[the Object] .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 io uso "OpenDatabase" e in dbclose io uso ".Close" e "set myBase = niente" Edit 2: nella funzione, se non si connette, .version darvi un errore quindi se non sei connesso, errorHandler ti dà il falso

+0

cos'è: '.Version'? .... potresti aggiungere il codice all'interno di 'myClass' .... L'ho postato recentemente, solo l'altra settimana, quindi sarei MOLTO interessato a vedere come hai scritto' myClass': http: // codereview. stackexchange.com/questions/116253/class-module-to-wrap-up-classic-ado-call-to-sql-server – whytheq

+0

".Version" fornisce la versione del Database, quindi se non si connette a un database (Uso Access) non puoi conoscere la versione in modo da poter sapere se sei connesso al database – JustGuest

Problemi correlati