non voglio alle imbarcazioni gestori di errori speciali per ogni struttura ad anello nel mio codice quindi ho un modo di trovare problema loop usando il mio gestore degli errori standard in modo che posso quindi scrivi un gestore di errori speciale per loro.
Se si verifica un errore in un ciclo, in genere desidero sapere cosa ha causato l'errore anziché saltarlo. Per scoprire questi errori, scrivo i messaggi di errore in un file di registro come fanno molte persone. Tuttavia scrivere in un file di log è pericoloso se si verifica un errore in un loop poiché l'errore può essere attivato per ogni volta che il ciclo itera e nel mio caso 80.000 iterazioni non sono infrequenti.Ho quindi inserito del codice nella mia funzione di registrazione degli errori che rileva errori identici e salta scrivendoli nel log degli errori.
Il mio gestore di errori standard utilizzato in ogni procedura è simile a questo. Registra il tipo di errore, la procedura in cui si è verificato l'errore e tutti i parametri ricevuti dalla procedura (FileType in questo caso).
procerr:
Call NewErrorLog(Err.number, Err.Description, "GetOutputFileType", FileType)
Resume exitproc
mio errore funzione di registrazione, che scrive a un tavolo (io sono in MS-Access) è la seguente. Utilizza le variabili statiche per conservare i valori precedenti dei dati di errore e confrontarli con le versioni correnti. Viene registrato il primo errore, quindi il secondo errore identico spinge l'applicazione in modalità di debug se sono l'utente o se in un'altra modalità utente, esce dall'applicazione.
Public Function NewErrorLog(ErrCode As Variant, ErrDesc As Variant, Optional Source As Variant = "", Optional ErrData As Variant = Null) As Boolean
On Error GoTo errLogError
'Records errors from application code
Dim dbs As Database
Dim rst As Recordset
Dim ErrorLogID As Long
Dim StackInfo As String
Dim MustQuit As Boolean
Dim i As Long
Static ErrCodeOld As Long
Static SourceOld As String
Static ErrDataOld As String
'Detects errors that occur in loops and records only the first two.
If Nz(ErrCode, 0) = ErrCodeOld And Nz(Source, "") = SourceOld And Nz(ErrData, "") = ErrDataOld Then
NewErrorLog = True
MsgBox "Error has occured in a loop: " & Nz(ErrCode, 0) & Space(1) & Nz(ErrDesc, "") & ": " & Nz(Source, "") & "[" & Nz(ErrData, "") & "]", vbExclamation, Appname
If Not gDeveloping Then 'Allow debugging
Stop
Exit Function
Else
ErrDesc = "[loop]" & Nz(ErrDesc, "") 'Flag this error as coming from a loop
MsgBox "Error has been logged, now Quiting", vbInformation, Appname
MustQuit = True 'will Quit after error has been logged
End If
Else
'Save current values to static variables
ErrCodeOld = Nz(ErrCode, 0)
SourceOld = Nz(Source, "")
ErrDataOld = Nz(ErrData, "")
End If
'From FMS tools pushstack/popstack - tells me the names of the calling procedures
For i = 1 To UBound(mCallStack)
If Len(mCallStack(i)) > 0 Then StackInfo = StackInfo & "\" & mCallStack(i)
Next
'Open error table
Set dbs = CurrentDb()
Set rst = dbs.OpenRecordset("tbl_ErrLog", dbOpenTable)
'Write the error to the error table
With rst
.AddNew
!ErrSource = Source
!ErrTime = Now()
!ErrCode = ErrCode
!ErrDesc = ErrDesc
!ErrData = ErrData
!StackTrace = StackInfo
.Update
.BookMark = .LastModified
ErrorLogID = !ErrLogID
End With
rst.Close: Set rst = Nothing
dbs.Close: Set dbs = Nothing
DoCmd.Hourglass False
DoCmd.Echo True
DoEvents
If MustQuit = True Then DoCmd.Quit
exitLogError:
Exit Function
errLogError:
MsgBox "An error occured whilst logging the details of another error " & vbNewLine & _
"Send details to Developer: " & Err.number & ", " & Err.Description, vbCritical, "Please e-mail this message to developer"
Resume exitLogError
End Function
Nota che un logger di errore deve essere il più funzione di prova di proiettile nella vostra applicazione, come l'applicazione non in grado di gestire con garbo errori nel logger errore. Per questo motivo, io uso NZ() per assicurarmi che i nulli non possano entrare di nascosto. Nota che aggiungo anche [loop] al secondo errore identico in modo che sappia prima cercare i loop nella procedura di errore.
non ci sono 'oggetti elenco' che non sono tabelle di query? Ho bisogno che il foglio abbia una tabella di query. –
@Justin, in tal caso, aggiungere un test per 'ListObjects (1) .QueryTable Is Nothing' - il codice non ha avuto questo test. Il punto principale del mio esempio è verificare se la raccolta ListObjects ha elementi prima di dereferenziare il primo elemento. – Joe