MyTetra Share
Делитесь знаниями!
Обработка ошибок в VBA
Время создания: 16.03.2019 23:23
Раздел: Разные закладки - MSO - Access
Запись: xintrea/mytetra_db_adgaver_new/master/base/153470762324xsn5sx6l/text.html на raw.githubusercontent.com

Автор Allen Browne, июнь 1997 г. Обновлено в сентябре 2009 г..

Оригинал http://allenbrowne.com/ser-23a.html

Перевел с английского Александр Артамонов, ноябрь 2011 г.


В каждую функция или процедуру следует включать обработку ошибок. Без нее пользователь может оказаться глядящим на дефектный код в открытом редактороме VBA в полной версии Аксесс, а в рантайм версии приложение просто падает.. Более подробно обработка ошибок изложена в статье FMS  Error Handling and Debugging.

Простейший подход состоит в том, чтобы показать сообщение об ошибке и выйти из процедуры. Каждая процедура, таким образом, будет иметь такой формат (без номеров строк):

1 Sub|Function SomeName()

2 On Error GoTo Err_SomeName ' Инициализировать обработку ошибок.

3 'здесь должен быть ваш код.

4 Exit_SomeName: ' Метка для возобновления после ошибки.

5 Exit Sub|Function ' Выход до обработки ошибок.

6 Err_SomeName: ' Метка для перехода при ошибке.

7 MsgBox Err.Number & Err.Description ' Место для обработчика ошибок.

8 Resume Exit_SomeName ' возобновить код и выйти.

9 End Sub|Function

Для задач, где есть возможность нескольких ошибок, строки 7-8 нужно заменить более подробным вариантом:

Select Case Err.Number

Case 9999 ' Номер ожидаемой ошибки.

Resume Next ' Чтобы игнорировать вызвавшую ошибку строку

Case 999

Resume Exit_SomeName ' Это используется для выхода из процедуры.

Case Else ' Любая неожиданная ошибка.

Call LogError(Err.Number, Err.Description, "SomeName()")

Resume Exit_SomeName

End Select

Ветка Case Else в этом примере вызывает пользовательскую функцию записи деталей ошибки в таблицу. Это позволит подробнее разобраться уже после того, как ошибка будет очищена. Таблицу можно назвать "tLogError" и состоять она будет из следующих полей:



Имя поля

Тип данных

Описание

ErrorLogID

Счетчик

Первичный ключ.

ErrNumber

Число

Длинное целое. Номер ошибки, сгенерированный Аксессом.

ErrDescription

Текст

Размер=255. Сообщение об ошибке, сгенерированное Аксессом.

ErrDate

Дата/время

Системная дата и время ошибки. По умолчанию: =Now()

CallingProc

Текст

Имя процедуры, вызвавшей LogError()

UserName

Текст

Имя пользователя.

ShowUser

Логический

Будет или нет показан диалоговое сообщение (MsgBox) c описанием ошибки

Parameters

Текст

255. Опционально. Любые параметры, которые сочтете нужным записать.

 

Below is a procedure for writing to this table. It optionally allows recording the value of any variables/parameters at the time the error occurred. You can also opt to suppress the display of information about the error.

Ниже процедура для записи в эту таблицу. Она опционально позволяет записывать значения переменных/параметров во время возникновения ошибки. Можно также подавить вывод информации об ошибке на экран.


Function LogError(ByVal lngErrNumber As Long, ByVal strErrDescription As String, _

strCallingProc As String, Optional vParameters, Optional bShowUser As Boolean = True) As Boolean

On Error GoTo Err_LogError

' Назначение: Обобщенный обработчик ошибок.

' Записывает ошибки в таблицу "tLogError".

' Аргументы: lngErrNumber - значение Err.Number

' strErrDescription - значение Err.Description

' strCallingProc - имя процедуры/функции, сгенерировавшей ошибку.

' vParameters - необязательный параметр-строка: список параметров для записи в таблицу.

' bShowUser - необязательный параметр boolean: если False, подавляет вывод сообщения на экран.

' Автор: Allen Browne, allen@allenbrowne.com Комментарии перевел Александр Артамонов

Dim strMsg As String ' Строковое значение для отображения в MsgBox

Dim rst As DAO.Recordset ' таблица tLogError

Select Case lngErrNumber

Case 0

Debug.Print strCallingProc & " called error 0."

Case 2501 ' Cancelled

'Do nothing.

Case 3314, 2101, 2115 ' Can't save.

If bShowUser Then

strMsg = "Record cannot be saved at this time." & vbCrLf & _

"Complete the entry, or press <Esc> to undo."

MsgBox strMsg, vbExclamation, strCallingProc

End If

Case Else

If bShowUser Then

strMsg = "Error " & lngErrNumber & ": " & strErrDescription

MsgBox strMsg, vbExclamation, strCallingProc

End If

Set rst = CurrentDb.OpenRecordset("tLogError", , dbAppendOnly)

rst.AddNew

rst![ErrNumber] = lngErrNumber

rst![ErrDescription] = Left$(strErrDescription, 255)

rst![ErrDate] = Now()

rst![CallingProc] = strCallingProc

rst![UserName] = CurrentUser()

rst![ShowUser] = bShowUser

If Not IsMissing(vParameters) Then

rst![Parameters] = Left(vParameters, 255)

End If

rst.Update

rst.Close

LogError = True

End Select

Exit_LogError:

Set rst = Nothing

Exit Function

Err_LogError:

strMsg = "В программе возникла непредвиденная ситуация." & vbCrLf & _

"Пожалуйста запишите следующую информацию:" & vbCrLf & vbCrLf & _

"Вызывающая процедура: " & strCallingProc & vbCrLf & _

"Номер ошибки " & lngErrNumber & vbCrLf & strErrDescription & vbCrLf & vbCrLf & _

"Запись в таблицу невозможна из-за Ошибки " & Err.Number & vbCrLf & Err.Description

MsgBox strMsg, vbCritical, "LogError()"

Resume Exit_LogError

End Function



Замечания по функции:

  1. Для Аксесса 1 или 2, используйте Access Basic error handler.
  2. Возвращаемое значение служит только с целью показать, успешно ли функция записала в лог ошибку.
  3. Возможные расширения: Поскольку таблица tErrorLog у вас уже открыта, вы могли бы посчитать последние ошибки и подавить вывод на экран одного и того же сообщения несколько раз, или отменить повторные ошибки блокировки.
Так же в этом разделе:
 
MyTetra Share v.0.62
Яндекс индекс цитирования