Элементы обработки ошибок во время выполнения

Ошибки и обработка ошибок

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

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

При добавлении обработки ошибок в процедуру следует учитывать, как процедура направляет выполнение при возникновении ошибки. Первый этап направления в обработчик ошибок состоит во включении обработчика ошибок путем добавления одной из форм оператора On Error в процедуру. Оператор On Error направляет выполнение в событие ошибки. Если оператор On Error отсутствует, при возникновении ошибки Visual Basic просто приостанавливает выполнение и отображает сообщение об ошибке.

Если ошибка возникает в процедуре с включенным обработчиком ошибок, Visual Basic не отображает обычное сообщение об ошибке. Вместо этого он направляет выполнение в обработчик ошибок, при его наличии. Когда выполнение передается включенному обработчику ошибок, он становится активным. В активном обработчике ошибок можно определить тип возникшей ошибки и устранить ее выбранным способом. Приложение Access представляет три объекта, содержащих сведения о возникших ошибках: объект Error ADO, объект Err Visual Basic и объект Error DAO.

Направление выполнения при возникновении ошибки

Обработчик ошибок указывает, что происходит в процедуре при возникновении ошибки. Например, может потребоваться завершение процедуры, если возникает определенное событие, или может потребоваться исправление условия, вызвавшего ошибку, и возобновление выполнения. Операторы On Error и Resume определяют, как продолжается выполнение в случае ошибки.

Оператор On Error

Оператор On Error включает или отключает процесс обработки ошибки. Если процесс обработки ошибки включен, при возникновении ошибки выполнение передается в него.

Существует три формы инструкции On Error : On Error GoTolabel, On Error GoTo 0 и On Error Resume Next. Инструкция On Error GoTolabel включает подпрограмму обработки ошибок, начиная со строки, в которой найден оператор. Нужно включить процесс обработки ошибок перед первой строкой, в которой произошла ошибка. Если обработчик ошибок активен и происходит ошибка, выполнение передается в строку, указанную аргументом label.

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

Function MayCauseAnError() 
    ' Enable error handler. 
    On Error GoTo Error_MayCauseAnError 
    .            ' Include code here that may generate error. 
    . 
    . 
 
Error_MayCauseAnError: 
    .            ' Include code here to handle error. 
    . 
    . 
End Function

Оператор On Error GoTo 0 отключает обработку ошибки в процедуре. Он не должен указывать строку 0 в качестве начала для кода обработки ошибок, даже если в процедуре есть строка с номером 0. Если оператор On Error GoTo 0 отсутствует в коде, обработчик ошибок автоматически отключается, когда процедура полностью завершена. Оператор On Error GoTo 0 сбрасывает свойства объекта Err, оказывая такое же действие, как метод Clear объекта Err.

Оператор On Error Resume Next игнорирует строку, которая вызывает ошибку, и направляет выполнение к следующей за ней строке. Выполнение не прерывается. Используйте инструкцию On Error Resume Next , чтобы проверить свойства объекта Err сразу после строки, в которой ожидается ошибка, и обработать ошибку в процедуре, а не в обработчике ошибок.

Оператор Resume

Оператор Resume направляет выполнение обратно к телу процедуры из процесса обработки ошибок. Оператор Resume можно добавить в процесс обработки ошибок, если нужно продолжить выполнение в определенной точке процедуры. Однако оператор Resume не является обязательным; процедуру также можно завершить после процесса обработки ошибок.

Существует три формы оператора Resume. Оператор Resume или Resume 0 возвращает выполнение в строку, в которой произошла ошибка. Оператор Resume Next возвращает выполнение в строку, расположенную непосредственно после строки, в которой произошла ошибка. Инструкция Resumelabel возвращает выполнение в строку, указанную аргументом label . Аргумент label должен указывать на метку строки или на номер строки.

Если пользователю нужно внести исправление, обычно используется оператор Resume или Resume 0. Например, если у пользователя запрашивается имя таблицы для открытия, и пользователь вводит несуществующее имя таблицы, можно отправить пользователю повторный запрос и продолжить выполнение с оператором, вызвавшим ошибку.

Используйте оператор Resume Next, если код исправляет ошибку в обработчике ошибок и вы хотите продолжить выполнение без повторного запуска строки, вызвавшей ошибку. Оператор Resumelabel используется, если требуется продолжить выполнение в другой точке процедуры, заданной аргументом label . Например, можно продолжить выполнение с процесса выхода, как описано в разделе ниже.

Выход из процедуры

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

Например, можно добавить процесс выхода к примеру в предыдущем разделе. Если ошибка не возникает, процесс выхода запускается после тела процедуры. Если ошибка возникает, выполнение передается процессу выхода после завершения процесса обработки ошибок. Процесс выхода содержит оператор Exit.

Function MayCauseAnError() 
    ' Enable error handler. 
    On Error GoTo Error_MayCauseAnError 
    .            ' Include code here that may generate error. 
    . 
    . 
 
Exit_MayCauseAnError: 
    Exit Function 
 
Error_MayCauseAnError: 
    .            ' Include code to handle error. 
    . 
    . 
    ' Resume execution with exit routine to exit function. 
    Resume Exit_MayCauseAnError 
End Function

Обработка ошибок во вложенных процедурах

Если ошибка возникает во вложенной процедуре без включенного обработчика ошибок, Visual Basic выполняет поиск по списку вызовов в обратном направлении, чтобы найти включенный обработчик ошибок в другой процедуре, а не просто приостанавливает выполнение. Благодаря этому у кода есть возможность исправить ошибку в другой процедуре. Для примера предположим, что Процедура A вызывает Процедуру B, а Процедура B вызывает Процедуру C. Если ошибка возникает в Процедуре C, в которой нет включенного обработчика ошибок, Visual Basic проверяет наличие включенного обработчика ошибок в Процедуре B, а затем в Процедуре A. Если он существует, выполнение передается этому обработчику ошибок. Если его нет, выполнение приостанавливается и отображается сообщение об ошибке.

Visual Basic также выполняет поиск включенного обработчика ошибок по списку вызовов в обратном направлении, если ошибка возникает в активном обработчике ошибок. Можно принудительно заставить Visual Basic выполнять поиск по списку вызовов в обратном направлении, запустив ошибку в активном обработчике ошибок с помощью метода Raise объекта Err. Это удобно для обработки ошибок, которые не ожидаются в обработчике ошибок. Если возникает неожиданная ошибка и она воспроизводится в обработчике ошибок, выполнение передается назад по списку вызовов для поиска другого обработчика, который может быть настроен для обработки такой ошибки.

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

Чтобы проиллюстрировать этот принцип, предположим, что у вас есть вложенная процедура, содержащая средство обработки ошибок несоответствия типов (ожидаемой ошибки). В какой-то момент в процедуре С возникает неожиданная ошибка деления на ноль. Если вы добавили оператор для воспроизведения исходной ошибки, выполнение передается назад по списку вызовов другому включенному обработчику ошибок, если он существует. Если вы исправляли ошибку деления на ноль в другой процедуре в списке вызовов, ошибка будет исправлена. Если код не воспроизводит ошибку, процедура продолжает выполнение без исправления ошибки деления на ноль. Это, в свою очередь, может вызывать другие ошибки в наборе вложенных процедур.

Таким образом, Visual Basic выполняет поиск включенного обработчика ошибок по списку вызовов в обратном направлении, если:

  • Ошибка возникает в процедуре, не содержащей включенного обработчика ошибок.

  • Ошибка возникает в активном обработчике ошибок. Если для запуска ошибки используется метод Raise объекта Err, можно принудительно заставить Visual Basic выполнять поиск включенного обработчика ошибок по списку вызовов в обратном направлении.

Получение сведений об ошибке

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

Элементы языка, доступные для обработки ошибок, включают:

  • Объект Err

  • Объект Error и коллекция Errors ADO

  • Объект Error и коллекция Errors DAO

  • Метод AccessError

  • Событие Error

Объект Err

Объект Err представлен в Visual Basic. При возникновении ошибки Visual Basic сведения об этой ошибке сохраняются в объекте Err. Объект Err хранит сведения только об одной ошибке одновременно. При возникновении новой ошибки объект Err изменяется для включения сведений об этой ошибке вместо старой.

Чтобы получить сведения об определенной ошибке, можно использовать свойства и методы объекта Err:

  • Свойство Number — это свойство по умолчанию объекта Err. Оно возвращает идентификационный номер возникшей ошибки.
  • Свойство Description объекта Err возвращает описательную строку, связанную с ошибкой Visual Basic.
  • Метод Clear очищает текущие сведения об ошибке из объекта Err.
  • Метод Raise создает определенную ошибку и заполняет свойства объекта Err сведениями об этой ошибке.

В приведенном ниже примере показано, как использовать объект Err в процедуре, которая может вызывать ошибку несоответствия типов:

Function MayCauseAnError() 
    ' Declare constant to represent likely error. 
    Const conTypeMismatch As Integer = 13 
 
    On Error GoTo Error_MayCauseAnError 
        .            ' Include code here that may generate error. 
        . 
        . 
 
Exit_MayCauseAnError: 
    Exit Function 
 
Error_MayCauseAnError: 
    ' Check Err object properties. 
    If Err = conTypeMismatch Then 
        .            ' Include code to handle error. 
        . 
        . 
    Else 
        ' Regenerate original error. 
        Dim intErrNum As Integer 
        intErrNum = Err 
        Err.Clear 
        Err.Raise intErrNum 
    End If 
    ' Resume execution with exit routine to exit function. 
    Resume Exit_MayCauseAnError 
End Function

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

Объект Err предоставляет все необходимые сведения об ошибках Visual Basic. Однако он не предоставляет полные сведения об ошибках Access или ошибках ядра СУБД Access. Access и объекты доступа к данным (DAO) предоставляют дополнительные элементы языка, помогающие устранять ошибки.

Объект Error и коллекция Errors

Объект Error и коллекция Errors предоставляются интерфейсами ADO и DAO. Объект Error представляет ошибку ADO или DAO. Отдельная операция ADO или DAO может вызвать несколько ошибок, особенно при выполнении операций ODBC DAO. У каждой ошибки, возникающей во время определенной операции доступа к данным, есть соответствующий объект Error. Все объекты Error, связанные с определенной операцией ADO или DAO, хранятся в коллекции Errors. Ошибки нижнего уровня являются первыми объектами в коллекции, а ошибки верхнего уровня являются последними объектами в коллекции.

При возникновении ошибки ADO или DAO объект Err Visual Basic сохраняет номер ошибки для первого объекта в коллекции Errors. Чтобы определить, происходили ли дополнительные ошибки ADO или DAO, проверьте коллекцию Errors. Значения свойств Number ADO или Number DAO и свойств Description ADO или Description DAO первого объекта Error в коллекции Errors должны совпадать со значениями свойств Number и Description объекта Err Visual Basic.

Метод AccessError

Используйте метод Raise объекта Err , чтобы создать ошибку Visual Basic, которая фактически не произошла, и определить описательную строку, связанную с этой ошибкой. Однако нельзя использовать метод Raise, чтобы создать ошибку Access, ошибку ADO или ошибку DAO. Чтобы определить строку описания, связанную с ошибкой Access, ошибкой ADO или ошибкой DAO, не происходившей на самом деле, используйте метод AccessError.

Событие Error

Используйте событие Error для ловли ошибок, возникающих в форме или отчете Access. Например, если пользователь пытается ввести текст в поле с типом данных "Дата и время", возникает событие Error. Если добавить процедуру обработки события Error в форму Employees, а затем попытаться ввести текстовое значение в поле HireDate, запустится процедура обработки события Error.

Процедура обработки события Error использует целочисленный аргумент DataErr. Когда запускается процедура обработки события Error, аргумент DataErr сохраняет номер возникшей ошибки Access. Проверка значения аргумента DataErr в процедуре обработки событий — это единственный способ определить номер возникшей ошибки. Объект Err не заполняется сведениями об ошибке после возникновения события Error. Используйте значение аргумента DataErr вместе с методом AccessError , чтобы определить номер ошибки и ее описательную строку.

Примечание.

Оператор Error и функция Error предоставляются только для обеспечения обратной совместимости. При создании нового кода используйте объекты Err и Error, функцию AccessError и событие Error для получения сведений об ошибке.

Об участниках

Ссылка, предоставляемая участникомсообщества Значок сообщества UtterAccess .

UtterAccess — это премиальный вики-портал и форум, посвященный Microsoft Access.

См. также

Поддержка и обратная связь

Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.