VBA: как отобразить сообщение об ошибке, как стандартное сообщение об ошибке с кнопкой "Отладка"?
Как обычно, я создаю обработчик ошибок с помощью инструкции On Error Goto
, там я помещаю несколько строк очищающих кодов и выводим сообщение об ошибке, но теперь я не хочу потерять удобство обработчика по умолчанию, который также укажите мне точную строку, где произошла ошибка. Как я могу это сделать?
Спасибо заранее.
Ответы
Ответ 1
Сначала хорошие новости. Этот код делает то, что вы хотите (обратите внимание на "номера строк" )
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 и других "современных" версиях эта функция теряется.
Однако Здесь существует несколько альтернатив для "автоматического" добавления номеров строк, что избавляет вас от утомительной задачи ввода их... но все из них кажутся более или менее громоздкими... или коммерческими.
НТН!
Ответ 2
Существует более простой способ просто отключить обработчик ошибок в обработчике ошибок, если он не соответствует типам ошибок, которые вы делаете и возобновляете.
Затем обработчик проверяет снова каждый тип ошибки, и если ни один из них не является совпадением, он возвращает сообщение об ошибке в обычный 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
Ответ 3
Этот ответ не относится к кнопке отладки (вам нужно будет создать форму и использовать кнопки для этого, чтобы сделать что-то вроде метода в следующем вопросе). Но это касается этой части:
теперь я не хочу потерять удобство обработчика по умолчанию, который также указывает мне на точную строку, где произошла ошибка.
Во-первых, я предполагаю, что вы не хотите этого в производственном коде - вы хотите его либо для отладки, либо для кода, который вы лично будете использовать. Я использую флаг компилятора для указания отладки; то, если я искажаю программу, я могу легко найти строку, которая вызывает проблему.
# 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
приведет вас к строке в этом proc, которая вызвала подпроцедуру с ошибкой. Но вы можете по-прежнему входить в подпроцедуру и через нее, используя F8, пока он снова не выйдет из строя. Если подпроцедура слишком длинная, чтобы сделать ее утомительной, то ваша подпроцедура должна, вероятно, иметь свою собственную процедуру обработки ошибок.
Существует несколько способов сделать это. Иногда для небольших программ, где я знаю, что я буду проходить через него в любом случае при устранении неполадок, я просто помещаю эти строки сразу после утверждения MsgBox:
Resume ExitHere ' Normally exits during production
Resume ' Never will get here
Exit Sub
Он никогда не попадет в оператор Resume, если вы не перейдете к нему и не установите его в качестве следующей строки, которую нужно выполнить, перетащив следующий указатель оператора на эту строку или нажав Ctrl F9 с помощью курсор на эту строку.
Здесь статья, расширяющая эти понятия: Пять советов по обработке ошибок в VBA. Наконец, если вы используете VBA и еще не обнаружили удивительный сайт Chip Pearson, у него есть страница, объясняющая Обработка ошибок в VBA.
Ответ 4
Для меня я просто хотел увидеть ошибку в моем приложении VBA, поэтому в функции я создал код ниже.
Функция Database_FileRpt
"-------------------------
Ошибка при ошибке GoTo CleanFail
"-------------------------
'
'Create_DailyReport_Action и код
CleanFail:
'*************************************
MsgBox "********************" _
& vbCrLf и "Err.Number:" и Err.Number _
& vbCrLf и "Err.Description:" и Err.Description _
& vbCrLf и "Err.Source:" и Err.Source _
& vbCrLf и "********************" _
& vbCrLf и "... Выход из функции VBA: Database_FileRpt" _
& vbCrLf и "... Программа Excel VBA Reset". _
"Ошибка исключения VBA!"
'Обратите внимание, что в следующей строке reset объект ошибки будет равен 0, переменные
выше, используются для запоминания значений
', так что одна и та же ошибка может быть повторно поднята
Err.Clear
'*************************************
Resume CleanExit
CleanExit:
'код очистки, если таковой имеется, идет здесь. выполняется независимо от состояния ошибки.
Выход из функции SUB или функция
Конечная функция 'end of Database_FileRpt
'------------------