Страницы: 1
RSS
Обработка ошибок с двумя разными метками (VBA), Не срабатывает обработка
 
Добрый день!

Необходимо построить обработку ошибок с двумя разными метками выхода (всё в цикле):
1. Если возникает ошибка до условия If, то просто переходим на End Sub.
2. Если возникает ошибка в условии If, то переходим на Netx.

Прошу помочь разобраться почему на срабатывает макрос :). Спасибо.

Грузить файлы запрещено в организации, поэтому опишу пример.
Есть книга со значениями на Листе1 [A1:A5]={1;2;3;4;5} и макрос:
Код
Sub test()
Dim i%, x#

[B:B].ClearContents

For i = 1 To 10

    On Error GoTo errH1
        If Cells(i, 1).Value > 3 Then
            On Error GoTo errH2
            x = 1 / 0
        End If
    
'Если ошибка в условии цикла, значит Netx
errH2:
If Err.Number > 0 Then
    Cells(i, 2).Value = "Ошибка 2"
    Err.Clear
End If

Next

'Если ошибка перед условием цикла, значит End
errH1:
If Err.Number > 0 Then
    Cells(i, 2).Value = "Ошибка 1"
End If


End Sub
 
Так не проще?:
Код
Sub test()
    Dim i%, x#
    [B:B].ClearContents
    On Error Resume Next
    For i = 1 To 10
        If Cells(i, 1).Value > 3 Then
            If Err Then Cells(i, 2).Value = "Ошибка 1": Err.Clear: Exit Sub
            x = 1 / 0
            If Err Then Cells(i, 2).Value = "Ошибка 2": Err.Clear:
        End If
    Next
End Sub
Я сам - дурнее всякого примера! ...
 
Т.е. выполняется условие, а только потом проверяется наличие ошибок, а не в момент её возникновения?
Так работает, спасибо! Только что делать, если будет так:
Код
Sub test()
    Dim i%, x#, j%
    [B:B].ClearContents
    On Error Resume Next
    For i = 1 To 10
        If Cells(i, 1).Value > 3 Then
            If Err Then Cells(i, 2).Value = Err.Description: Err.Clear: Exit Sub
            x = 1 / 0
            j = "test"
            If Err Then Cells(i, 2).Value = Err.Description: Err.Clear:
        End If
    Next
End Sub
Err.Description будет выдавать последнюю ошибку, а не первую.

А почему в моём варианте возникает ошибка? :(
Вроде всё верно написано, но обработка не срабатывает...
 
Цитата
Евгений написал: Вроде всё верно написано
1. Нет выхода из обработчика ошибки - оператор Resume
2. Нет обхода обработчиков ошибок при нормальном выполнении программы.
 
1. Может я неправильно представлял работу обработчика, но зачем делать Resume, если есть GoTo?
2. Я для этого вставил условие If Err.Number > 0 Then ... End If
 
Задам немного другой вопрос: как сделать так, что в момент возникновения ошибки в цикле For у меня останавливалось выполнение кода и переходило на Next?
 
Цитата
Евгений написал:
Может я неправильно представлял работу обработчика, но зачем делать Resume, если есть GoTo?
Да уж наверно, раз не работает :)
Resume нужен для того, чтобы выйти из состояния обработки ошибки и перейти в состояние нормальной работы.
Если при работе обработчика ошибок происходит ошибка, происходит останов (есть правда возможность обойти его: On Error Goto -1 , но это крайний случай), а если ошибка происходит после Resume, то вызывается обработчик ошибок, который назначен в данный момент.
Ваш код может выглядеть так:
Код
Sub test()
Dim i%, x#
 
[B:B].ClearContents
 
For i = 1 To 10
    On Error GoTo errH1
    x = 1 / Int(Rnd * 5) 'ошибка с вероятностью 1/5
    If Cells(i, 1).Value > 3 Then
        On Error GoTo errH2
        x = 1 / 0
    End If
nxt:
Next
Exit Sub

'Если ошибка в условии цикла, значит Netx
errH2:
'If Err.Number > 0 Then  'проверка не нужна, т.к. без ошибки мы бы сюда не попали
    Cells(i, 2).Value = "Ошибка 2"
'    Err.Clear
'End If
Resume nxt
 
'Если ошибка перед условием цикла, значит End
errH1:
'If Err.Number > 0 Then 'проверка не нужна, т.к. без ошибки мы бы сюда не попали
    Cells(i, 2).Value = "Ошибка 1"
'End If
 
 
End Sub
Изменено: Казанский - 02.03.2016 16:51:57
 
Спасибо за подробное объяснение, всё работает :)
А то у Уокенбаха такого не написано :)
Страницы: 1
Наверх