web-dev-qa-db-fra.com

VBA: Comment afficher un message d'erreur exactement comme le message d'erreur standard comportant un bouton "Debug"?

Comme d'habitude, je crée un gestionnaire d'erreurs à l'aide de l'instruction On Error Goto. Là, je mets quelques lignes de codes de nettoyage et affiche le message d'erreur, mais maintenant, je ne veux pas perdre le confort du gestionnaire par défaut, qui m'indique également l'exact ligne où l'erreur s'est produite. Comment puis je faire ça?

Merci d'avance.

21
Vantomex

D'abord la bonne nouvelle. Ce code fait ce que vous voulez (veuillez noter les "numéros de ligne")

Sub a()
 10:    On Error GoTo ErrorHandler
 20:    DivisionByZero = 1 / 0
 30:    Exit Sub
 ErrorHandler:
 41: If Err.Number <> 0 Then
 42:    Msg = "Error # " & Str(Err.Number) & " was generated by " _
         & Err.Source & Chr(13) & "Error Line: " & Erl & Chr(13) & Err.Description
 43:    MsgBox Msg, , "Error", Err.HelpFile, Err.HelpContext
 44:    End If
 50:    Resume Next
 60: End Sub

Lorsqu’il est exécuté, le MsgBox attendu est affiché:

alt text

Et maintenant la mauvaise nouvelle: 
Les numéros de ligne sont des résidus d'anciennes versions de Basic. L'environnement de programmation se chargeait généralement de les insérer et de les mettre à jour. Dans VBA et les autres versions "modernes", cette fonctionnalité est perdue. 

Cependant, Ici il existe plusieurs alternatives pour ajouter "automatiquement" des numéros de ligne, ce qui vous évite la tâche fastidieuse de les taper ... mais tous semblent plus ou moins encombrants ... ou commerciaux. 

HTH!

41
Dr. belisarius

Il existe un moyen plus simple de simplement désactiver le gestionnaire d'erreurs dans votre gestionnaire d'erreurs s'il ne correspond pas aux types d'erreur que vous faites et de le reprendre.

Le gestionnaire ci-dessous vérifie chaque type d'erreur et si aucun ne correspond, il renvoie l'erreur à VBA normal, c.-à-d. GoTo 0 et reprend le code qui tente ensuite de le réexécuter et le bloc d'erreur normal s'affiche.

On Error GoTo ErrorHandler

x = 1/0

ErrorHandler:
if Err.Number = 13 then ' 13 is Type mismatch (only used as an example)

'error handling code for this

end if

If err.Number = 1004 then ' 1004 is Too Large (only used as an example)

'error handling code for this

end if

On Error GoTo 0
Resume
1
Paul Haines

Этот ответ не касается кнопки "Отладка" (вам нужно создать форму и использовать кнопки для этого, чтобы сделать что-то похожее на метод в вашем следующий вопрос ) Но это относится к этой части.:

который рестратоватоватоватование католь католь ералана сельная.

Во-первых, я предполагаю, что вы не хотите этого в производственном коде - вы хотите это либо для отладки, либо для кода, который вы лично будете использовать. Использую флаг компилятора, чтобы указать отладку; À la une.

# Const IsDebug = True

Sub ProcA()
On Error Goto ErrorHandler
' Main code of proc

ExitHere:
    On Error Resume Next
    ' Close objects and stuff here
    Exit Sub

ErrorHandler:
    MsgBox Err.Number & ": " & Err.Description, , ThisWorkbook.Name & ": ProcA"
    #If IsDebug Then
        Stop            ' Used for troubleshooting - Then press F8 to step thru code 
        Resume          ' Resume will take you to the line that errored out
    #Else
        Resume ExitHere ' Exit procedure during normal running
    #End If
End Sub

Примечание. Исключением из Resume является то, что если ошибка возникает в подпроцедуре без подпрограммы обработки ошибок, то Resume перенесет вас в строку этого процесса, которая вызвала подпроцедуру с ошибкой. Tous les prixF8пока он снова не выдаст ошибку. Если подпроцедура слишком длинная, чтобы сделать ее даже такой утомительной, то ваша подпроцедура, вероятно, должна иметь свою собственную процедуру обработки ошибок.

Сть несколько способов сделать то. Иногда для небольших программ, где я знаю, что я все равно буду проходить через них при поиске и устранении неисправностей, я просто помещаю эти строки сразу после оператора MsgBox:

    Resume ExitHere         ' Normally exits during production
    Resume                  ' Never will get here
Exit Sub

Он никогда не попадет в оператор CV, если вы не пройдете и не установите его в качестве следующей строки для выполнения, либо перетаскивая указатель следующего оператора на эту строку, либо нажавCtrlF9с курсором на этой строке.

Вот статья, которая расширяет эти понятия: Пять советов по обработке ошибок в VBA Наконец, если вы используете VBA и еще не обнаружили удивительный сайт Чипа Пирсона, у него есть страница, объясняющая Обработка ошибок в VBA ..

0
GlennFromIowa

Pour moi, je voulais juste voir l'erreur dans mon application VBA, donc dans la fonction j'ai créé le code ci-dessous.

Function Database_FileRpt
'-------------------------
On Error GoTo CleanFail
'-------------------------
'
' Create_DailyReport_Action and code


CleanFail:

'*************************************

MsgBox "********************" _

& vbCrLf & "Err.Number: " & Err.Number _

& vbCrLf & "Err.Description: " & Err.Description _

& vbCrLf & "Err.Source: " & Err.Source _

& vbCrLf & "********************" _

& vbCrLf & "...Exiting VBA Function: Database_FileRpt" _

& vbCrLf & "...Excel VBA Program Reset." _

, , "VBA Error Exception Raised!"

*************************************

 ' Note that the next line will reset the error object to 0, the variables 
above are used to remember the values
' so that the same error can be re-raised

Err.Clear

' *************************************

Resume CleanExit

CleanExit:

'cleanup code , if any, goes here. runs regardless of error state.

Exit Function  ' SUB  or Function    

End Function  ' end of Database_FileRpt

' ------------------
0
Hank Freeman