Подтвердить что ты не робот

VBA: как отобразить сообщение об ошибке, как стандартное сообщение об ошибке с кнопкой "Отладка"?

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

Спасибо заранее.

4b9b3361

Ответ 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

'------------------