Я хочу теперь рассмотреть ситуации, когда при выполнении операции по тем или иным причинам возникают ошибки. Мы рассмотрим, как выглядят обработчики ошибок в таких ситуациях, как можно проанализировать содержимое объектов Error, созданных Провайдером и переданных обработчику ошибок, как можно исправить ситуацию и продолжить выполнение.
Первым делом я смоделировал ситуацию, приводящую к ошибке в момент создания соединения, для чего сменил свойство " Provider ", не позаботившись о корректном задании характеристик этого Провайдера.
Вот как выглядит модернизованная процедура, организующая соединение:
Public Sub ConnectionWithEvents() 'Создание соединения с тестовой базой данных Access 'Объект с событиями Dim imEvCon As New MyEventsADO ' Связывание объекта с событиями Set imEvCon.EvCon = Con1 Dim strConnStr As String If Con1.State = adStateOpen Then Con1.Close 'закрыть соединение 'Вариант 1 'Конфигурирование соединения Con1 'Con1.Provider = "Microsoft.jet.oledb.4.0" Con1.Provider = "MSDASQL" Con1.ConnectionString = "Data Source=c:\!O2000\DsCd\Ch14\dbPP2000.mdb" Con1.CursorLocation = adUseClient 'Открытие соединения On Error GoTo Check Con1.Open Exit Sub Check: 'Повтор операции соединения Resume End Sub
В этой процедуре следует обратить внимание на следующие моменты:
В класс MyEventsADO я добавил следующий обработчик события ConnectComplete:
Private Sub EvCon_ConnectComplete(ByVal pError As ADODB.Error, _ adStatus As ADODB.EventStatusEnum, _ ByVal pConnection As ADODB.Connection) 'Печать параметров обработчика события MsgBox "Обработчик события ConnectComplete! " & vbCrLf & _ "Строка соединения = " & _ pConnection.ConnectionString & vbCrLf & _ "Статус выполняемой операции = " & adStatus 'Печать параметров объекта Error If Not (pError Is Nothing) Then With pError MsgBox "Описание ошибки:" & .Description & vbCrLf & _ "Код Провайдера:" & .NativeError & vbCrLf & _ "Константа, идентифицирующая ошибку:" & .Number & vbCrLf & _ "Имя объекта:" & .Source & vbCrLf & _ "ANSI SQL код:" & .SqlState End With End If If adStatus = adStatusErrorsOccurred Then 'Исправление ошибки pConnection.Provider = "Microsoft.jet.oledb.4.0" End If 'Анализ коллекции Errors Dim myErr As Error Dim MyCon As Connection Set MyCon = pConnection Debug.Print MyCon.Errors.Count For Each myErr In MyCon.Errors Debug.Print myErr.Description Next myErr MyCon.Errors.Clear Debug.Print MyCon.Errors.Count MyCon.Errors.Refresh Debug.Print MyCon.Errors.Count For Each myErr In MyCon.Errors Debug.Print myErr.Description Next myErr End Sub
Прокомментирую работу этой процедуры:
0 0 0 1 [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified 0 0
Еще одна ошибка, которую я решил смоделировать, возникает при работе с объектом Recordset, - некорректно формируется значение поля при изменении записи. К уже имеющемуся обработчику события WillChangeField я добавил обработчик события ChangeFieldComplete. Поскольку общая схема экспериментов остается такой же, как и для объекта Connection, то я приведу тексты процедур без дополнительных комментариев. В уже описанной процедуре CreateEvents я заменил оператор
!Цена = !Цена * 2
на оператор
!Цена = "По Договоренности"
Эта замена приводит к ошибке несоответствия типов. Вот текст обработчика события ChangeFieldComplete:
Private Sub EvRst_FieldChangeComplete(ByVal cFields As Long, _ ByVal Fields As Variant, ByVal pError As ADODB.Error, _ adStatus As ADODB.EventStatusEnum, _ ByVal pRecordset As ADODB.Recordset) 'Печать параметров обработчика события MsgBox "Номер поля = " & cFields & vbCrLf & _ "Значение поля = " & Fields(cField) & vbCrLf & _ "Позиция записи в наборе = " & _ pRecordset.AbsolutePosition & vbCrLf & _ "Статус выполняемой операции = " & adStatus 'Печать параметров объекта Error If Not (pError Is Nothing) Then With pError MsgBox "Описание ошибки:" & .Description & vbCrLf & _ "Код Провайдера:" & .NativeError & vbCrLf & _ "Константа, идентифицирующая ошибку:" & .Number & vbCrLf & _ "Имя объекта:" & .Source & vbCrLf & _ "ANSI SQL код:" & .SqlState End With End If 'Анализ коллекции Errors Dim myErr As Error Dim MyCon As Connection Set MyCon = pRecordset.ActiveConnection Debug.Print MyCon.Errors.Count For Each myErr In MyCon.Errors Debug.Print myErr.Description Next myErr End Sub
Вот как выглядит серия появляющихся окон функции MsgBox, вызываемой в процедурах: CreateEvents, WillChangeField, ChangeFieldComplete, при попытке изменить поле "Цена":
Возможно, полезно взглянуть и на информацию, появляющуюся в окне отладки:
0 1 Operation was canceled. 1 Operation was canceled. 1 Multiple-step operation generated errors. Check each status value.