У меня есть некоторый код VBA в Excel, который устанавливает соединение ADODB и запускает запрос SELECT к базе данных Access, используя rst.Open
(где rst
- ADODB.RecordSet
). Все работает хорошо. У меня есть некоторая стандартная обработка ошибок почти в каждой подпрограмме в коде, и все это тоже хорошо работает, изящная обработка ошибок с помощью вызова MsgBox
и т. Д.
Моя проблема в том, что если пользователь нажимает ESCAPE во время SELECT (то есть во время выполнения rst.Open
), то Excel / VBA, кажется, полностью игнорирует обработку ошибок и отображает стандартный Code execution has been interrupted
с кнопками Continue/End/Debug/Help
, как будто не было никакой обработки ошибок вообще. Как будто для подтверждения этого, если я нажимаю «Отладка» в этом диалоговом окне с ошибкой, он отправляет меня на строку непосредственно после строки rst.Open
(как обычно, выделено желтым цветом) ; если я затем иду в окно VBE Immediate и набираю print Err.number
, он возвращает ноль - т.е. без ошибки - вместо стандартной ошибки 18, которую я ожидал.
Обратите внимание, что одна из первых вещей, которые программа выполняет при запуске, - Application.EnableCancelKey = xlErrorHandler
, но это, плюс On Error Goto ErrHandler
в этой подпрограмме, кажется, полностью игнорируется.
Другие вещи, которые я пробовал:
- Отключите клавишу ESC с помощью
Application.OnKey "{ESC}",""
и восстановите его с помощью Application.OnKey "{ESC}"
сразу после rst.Open
- когда пользователь нажимает ESCAPE, затем отладка, это вторая строка, которая выделяется!
- Использование
Application.Interactive = False
непосредственно перед rst.Open
и восстановление сразу после.
- Код вызывается из пользовательской формы, и я попытался вставить
Userform_KeyDown
и искать vbKeyEscape
.
Ничего из этого не сработало. Похоже, что rst.Open
работает «вне» среды Excel VBA, а ESCAPE нажимается в среде «ADODB», и ADODB сообщает в Excel, что произошло прерывание.
Может кто-нибудь помочь, пожалуйста? Я не обязательно хочу, чтобы пользователи не прерывали SELECT (поскольку это, вероятно, было бы опрометчиво!), Но я хочу быть в состоянии изящно обработать прерывание без стандартного уродливого сообщения, которое дает им возможность попасть в VBA.
Не думаю, что это помогло бы показать вам код, но в любом случае вот оно:
Private Sub RunSelectQuery(ByRef rst As ADODB.Recordset, _
ByVal strSql As String, ByRef cnn As ADODB.Connection)
Dim booEof As Boolean
On Error GoTo ErrHandler
rst.Open strSql, cnn, adOpenForwardOnly, adLockReadOnly
booEof = rst.EOF
ErrHandler: ' -- Error handling and Routine termination.
If Err.Number <> 0 Then If DspErr() Then Stop: Resume Else End
End Sub
Как я уже сказал, это прекрасно работает при условии, что пользователь не нажимает ESCAPE во время оператора rst.Open; если они нажимают ESCAPE, появляется ужасное сообщение об ошибке, а когда вы нажимаете «Отладка», оно выделяет строку booEof =
. Эта строка, кстати, может быть любой - я вставил туда другие строки, и кнопка «Отладка» всегда выводит меня на следующую исполняемую строку ниже строки rst.Open
.
Работа с Office профессиональный плюс 2016, Windows 10.