2009-09-13 3 views
3

Я не много читал об этом, но автор по приведенной ниже ссылке рекомендует, чтобы я не использовал «пузырь» для централизации обработки ошибок в VBA.Ошибка VBA «Bubble Up»

Excel Programming Weekend Crash Course via Google Books

Но я не знаю, почему он рекомендует, и он не объясняет.

Может кто-нибудь сказать мне, почему я должен помещать обработку ошибок в КАЖДУЮ процедуру вместо того, чтобы использовать «bubble up»? Или, по крайней мере, знаете ли вы, почему автор не говорит?

Спасибо.

+2

-1 Пожалуйста, не используйте сокращенные URL-адреса. Никто не любит следить за слепыми ссылками на работе. (+1 доступно по прямой ссылке.) – Oorang

ответ

0

Я не уверен, что обработка ошибок по умолчанию VBA есть, но так как его Visual Basic для приложений, и эти приложения включают в себя такие вещи, как Excel и слова, я предполагаю, что только появится диалоговое окно, которое не будет быть полезным для пользователя.

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

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

+0

VBA _does_ разрешает ошибки пузыриться. Существуют исключения, но в целом вам не нужно иметь обработку ошибок в каждом отдельном методе, чтобы предотвратить появление всплывающего окна из приложения. –

0

Я вижу по крайней мере одну причину в его объяснении: потому что это лишает вас возможности возобновить (далее).
Плюс вы не узнаете, в каком модуле произошла ошибка.

0

лучше не использовать «пузырь вверх» часть обработки ошибок, потому что ошибки должны быть обработаны &, если известно, как что делать, если возникает такая ошибка - более известна процедура, как к тому, что , а не вызывающая процедура.

Sub test() 
    On Error GoTo e 
    Dim c As Integer 
    Dim d As Integer 
    c = add(5, 0) 
    d = divideWhichManagedItsOwnErrorHandling(5, 0) 
    d = divide(5, 0) 

    Exit Sub 

e: 
    MsgBox "error occurred somewhere for which I don't know what to do: " + Err.Description 
End Sub 

Function add(a As Integer, b As Integer) As Integer 
    add = a + b 
End Function 

Function divide(a As Integer, b As Integer) As Integer 
    divide = a/b 'if error occurs, it will "bubble-up" to the caller. 
End Function 

Function divideWhichManagedItsOwnErrorHandling(a As Integer, b As Integer) As Integer 
    On Error Resume Next 
    Dim result As Integer 
    result = a/b 
    If Err.Number = 11 Then 'if divide by zero occurred, user must have passed 0 for b 
    result = 0 ' return 0 if the divide by zero occurs. 
    End If 
    divideWhichManagedItsOwnErrorHandling = result 
End Function 
+0

a/0 не 0! Вы просто проглотили реальную ошибку и вернули неправильный результат. – jtolle

+1

@jtolle: Я не обсуждаю результат разделения здесь. Это просто привести пример обработки ошибок и, в частности, обработку ошибки там, где она встречается. – shahkalpesh

+0

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

11

Короткий ответ на ваш первый вопрос: «вы не должны помещать обработчик ошибок в каждую процедуру».

Сказать, что «каждая процедура должна иметь обработчик ошибок», в общем, является ужасным советом. Недостатки при обработке ошибок VBA обсуждались в других местах. Концептуально, однако, это не все, что отличается от более стандартной формы обработки исключений, найденной на других языках. Большинство из лучших практик этих языков применяются. Вы должны обрабатывать ошибки на самом низком уровне, где их обработка имеет смысл. Иногда это происходит в процедуре, где произошла ошибка, во много раз нет.

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

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

+0

Для примера, отличного от VBA, см .: http://stackoverflow.com/questions/2737328/why-should-i-not-wrap-every-block-in-try-catch/2737337#2737337 – jtolle

1

Мои 2 цента: Вы должны поместить обработчики ошибок во все публичные процедуры и события. Это означает, что процедура в нижней части стека вызовов всегда будет иметь обработчик ошибок. Затем добавьте обработчики ошибок в свои другие процедуры, поскольку это имеет смысл. Если в процедуре, которая не имеет обработчика ошибок, возникает ошибка, она «пузырится» с обработчиком ошибок верхнего уровня, где она будет регистрироваться/отображаться профессионально. Сценарий, в котором вы можете добавить обработчик ошибок к частной процедуре (нижний уровень), таков: Код должен быть быстрым. У вас есть редкое условие, которого можно избежать, но заставит вас выполнить дорогостоящий логический тест внутри цикла (или, что еще хуже, вложенный цикл). Вы можете выполнить логический тест в обработчике ошибок, и если это говорит о «редком явлении», выполните коррекцию и возобновите. Поскольку это условие редко, вы увидите прирост производительности для большинства условий. Если обработчик ошибок не может определить и исправить проблему, повторите попытку, чтобы выровнять его по стеке.

Очевидно, что это всего лишь один сценарий.