Как перехватить Escape-клавишу во время ADODB SELECT (Excel VBA) - PullRequest
0 голосов
/ 29 октября 2018

У меня есть некоторый код 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.

1 Ответ

0 голосов
/ 29 октября 2018

MSDN:

Свойство EnableCancelKey всегда сбрасывается в xlInterrupt всякий раз, когда Microsoft Excel возвращается в состояние ожидания, и код не выполняется. Чтобы перехватить или отключить отмену в вашей процедуре, вы должны явно меняйте свойство EnableCancelKey каждый раз, когда процедура называется.

...