VBA: Как отобразить сообщение об ошибке, как стандартное сообщение об ошибке с кнопкой «Отладка» - PullRequest
22 голосов
/ 12 октября 2010

Как обычно, я создаю обработчик ошибок с помощью оператора On Error Goto, там я помещаю несколько строк кодов очистки и отображаю сообщение об ошибке, но теперь я не хочу терять удобство обработчика по умолчанию, который также укажите мне точную линию, где произошла ошибка. Как я могу это сделать?

Заранее спасибо.

Ответы [ 4 ]

44 голосов
/ 12 октября 2010

Сначала хорошие новости. Этот код делает то, что вы хотите (обратите внимание на «номера строк»)

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

При запуске отображается ожидаемый MsgBox:

alt text

А теперь плохие новости:
Номера строк являются остатком старых версий Basic.Среда программирования обычно отвечала за их вставку и обновление.В VBA и других «современных» версиях эта функциональность потеряна.

Однако, Здесь есть несколько альтернатив для «автоматического» добавления номеров строк, избавляя вас от утомительной задачи их набирать ... но все они кажутся более или менее громоздкими ...или коммерческий.

HTH!

1 голос
/ 14 мая 2014

Существует более простой способ просто отключить обработчик ошибок в вашем обработчике ошибок, если он не соответствует типам ошибок, которые вы делаете, и возобновить работу.

Обработчик, приведенный ниже, проверяет снова каждый тип ошибки и, если нет совпадений, возвращает возобновление ошибки к нормальному VBA, то есть GoTo 0, и возобновляет код, который затем пытается повторно выполнить код, и появляется обычный блок ошибок.

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
0 голосов
/ 22 сентября 2017

Для меня я просто хотел увидеть ошибку в своем приложении VBA, поэтому в функции я создал следующий код ..

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 голосов
/ 29 апреля 2016

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

теперь я не хочу терять удобство обработчика по умолчанию, который также указывает на точную строку, где произошла ошибка.

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

# 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 перенесет вас в строку этого процесса, которая вызвала подпроцедуру с ошибкой. Но вы все равно можете перейти к этой подпроцедуре и выполнить ее, используя F8 , пока она снова не выдаст ошибку. Если подпроцедура слишком длинная, чтобы сделать ее даже такой утомительной, то ваша подпрограмма, вероятно, должна иметь свою собственную процедуру обработки ошибок.

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...