2010-10-12 1 views
16

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

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

+0

Просто держать правильные ссылки ... этот вопрос продолжается здесь: http://stackoverflow.com/questions/3929997/vba-how-to-make-the-current-cursor-in-vbe-jump-to-the-line-where- the-last-error/3930626 # 3930626 –

ответ

37

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

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 и других «современных» версиях эта функция теряется.

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

HTH!

+0

MZTools могут добавлять/удалять номера строк и бесплатно –

+0

@Charles yep. Это одна из ссылок на странице, которую я привел. Tnx! –

+0

@belisarius, большое спасибо за код, ценную информацию и полезные внешние ссылки. Любопытно, есть ли способ привлечь внимание читателя, даже выделить их и войти в режим отладки? Это действительно внутренняя функциональность? – Vantomex

1

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

Обработчик ниже проверяет каждый тип ошибки, и если ни один из них не соответствует, он возвращает сообщение об ошибке в нормальный 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

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

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

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

# 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 

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

Вот статья, которая расширяется по следующим понятиям: Five tips for handling errors in VBA. Наконец, если вы используете VBA и еще не обнаружили удивительного сайта Chip Pearson, у него есть страница, объясняющая Error Handling In VBA.

0

For Me Я просто хотел, чтобы увидеть ошибку в моем приложении 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». _

,, "Ошибка исключения VBA!"


«Обратите внимание, что следующая строка будет сброшен объект ошибки 0, переменные выше, используется для запоминания значения » так, что та же ошибка может быть повторно поднят

Err.Clear

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

резюме CleanExit

CleanExit:

'код очистки, если есть, идет здесь. выполняется независимо от состояния ошибки.

Выход Функция 'SUB или функция

End Function' конец Database_FileRpt

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