Escキーで処理が止まるのをコントロールする。

普通に記述しているマクロは、動作途中でEscキーが押されると、その瞬間で停止してしまいます。処理の場合によっては不都合な所で停止してしまい、再度処理し直すことができなくなる可能性があります。これを制御するのが「EnableCancelKey」プロパティです。

デフォルトは、Application.EnableCancelKey = xlInterruptです。
無限ループをわざと作成して見ます。


'***************************************************************************************************
'   Escキー動作テスト                                               Module1(Module)
'
'   作成者:井上治  URL:http://www.ne.jp/asahi/excel/inoue/ [Excelでお仕事!]
'***************************************************************************************************
'変更日付 Rev  変更履歴内容------------------------------------------------------------------------>
'03/07/30(1.00)新規作成
'12/01/22(1.01)初回修正
'20/02/23(1.10)*.xlsm化、他
'***************************************************************************************************
Option Explicit

'***************************************************************************************************
'   ■■■ ワークシート側からの呼び出し処理 ■■■
'***************************************************************************************************
'* 処理名 :EscKeyTEST1
'* 機能  :Escキー動作テスト@
'---------------------------------------------------------------------------------------------------
'* 返り値 :(なし)
'* 引数  :(なし)
'---------------------------------------------------------------------------------------------------
'* 作成日 :2003年07月30日
'* 作成者 :井上 治
'* 更新日 :2020年02月23日
'* 更新者 :井上 治
'* 機能説明:何もエラー制御を行なわない場合
'* 注意事項:
'***************************************************************************************************
Sub EscKeyTEST1()
    '-----------------------------------------------------------------------------------------------
    ' 無限ループを生成する
    Do
        ' ループ中では何もしない
    Loop
End Sub
While」や「Until」条件がないので終了しないマクロです。
このマクロを実行し、Escキーを押すとマクロは停止してしまいます。
Escキーでの中断(終了)
(この画像をクリックすると、このページのサンプルがダウンロードができます。)
「継続」はできますが、「終了」すると止まる所は、Escキーを押した瞬間であり、都合が良い所とは限りません。通常と違うシートが開いていたり、何かのファイルがOPENされたままかも知れません。
(プロジェクトがロックされている場合は「デバッグ」はクリックできません)

これを、Application.EnableCancelKey = xlDisabledにすると、Escキーを押しても停止しなくなります。

'***************************************************************************************************
'* 処理名 :EscKeyTEST2
'* 機能  :Escキー動作テストA
'---------------------------------------------------------------------------------------------------
'* 返り値 :(なし)
'* 引数  :(なし)
'---------------------------------------------------------------------------------------------------
'* 作成日 :2003年07月30日
'* 作成者 :井上 治
'* 更新日 :2020年02月23日
'* 更新者 :井上 治
'* 機能説明:Escキーを無効にする("100-10-100"まで止まらない)
'* 注意事項:
'***************************************************************************************************
Sub EscKeyTEST2()
    '-----------------------------------------------------------------------------------------------
    Dim lngIx1 As Long                                              ' テーブルINDEX@
    Dim lngIx2 As Long                                              ' テーブルINDEXA
    Dim lngIx3 As Long                                              ' テーブルINDEXB
    ' ESCキーを無効にする
    Application.EnableCancelKey = xlDisabled
    ' 外ループ処理
    For lngIx1 = 1 To 100
        ' 中ループ処理
        For lngIx2 = 1 To 10
            ' 内ループ処理
            For lngIx3 = 1 To 100
                ' カウントを表示
                Application.StatusBar = _
                    lngIx1 & "-" & lngIx2 & "-" & lngIx3
            Next lngIx3
        Next lngIx2
    Next lngIx1
    ' セットしたプロパティを初期値に戻す
    Application.EnableCancelKey = xlInterrupt
    Application.StatusBar = False
End Sub
Escキーを途中で押しても、ステータスバーの表示が「100-10-100」になるまで終了しません。一見都合が良いようですが、何かの問題で「無限ループ」の状態になっても停止できなくなります。この場合は、タスクマネージャで強制終了させなければなりません。

もう一つ、Application.EnableCancelKey = xlErrorHandlerがあります。
これをうまく利用すると、区切りの良い所で停止、又は停止確認を入れることができます。
任意位置で停止確認を表示
これには、次のようなマクロの書き方を行ないます。

'***************************************************************************************************
'* 処理名 :EscKeyTEST3
'* 機能  :Escキー動作テストB
'---------------------------------------------------------------------------------------------------
'* 返り値 :(なし)
'* 引数  :(なし)
'---------------------------------------------------------------------------------------------------
'* 作成日 :2003年07月30日
'* 作成者 :井上 治
'* 更新日 :2020年02月23日
'* 更新者 :井上 治
'* 機能説明:都合が良い所で中断処理を行なう
'* 注意事項:
'***************************************************************************************************
Sub EscKeyTEST3()
    '-----------------------------------------------------------------------------------------------
    Dim lngIx1 As Long                                              ' テーブルINDEX@
    Dim lngIx2 As Long                                              ' テーブルINDEXA
    Dim lngIx3 As Long                                              ' テーブルINDEXB
    Dim swEND As Boolean                                            ' 終了判定スイッチ
    ' エラー処理を登録
    On Error GoTo ERR1
    ' ESCキーでエラー処理に進む
    Application.EnableCancelKey = xlErrorHandler
    ' 外ループ処理
    For lngIx1 = 1 To 100
        ' 中ループ処理
        For lngIx2 = 1 To 10
            swEND = False
            ' 内ループ処理
            For lngIx3 = 1 To 1000
                ' カウントを表示
                Application.StatusBar = _
                    lngIx1 & "-" & lngIx2 & "-" & lngIx3
            Next lngIx3
            ' 中断の判断(カウントは内ループ終了のタイミング゙)
            If swEND Then
                ' 終了確認
                If MsgBox("中断キーが押されました。" & vbCr & _
                    "終了しますか?", vbYesNo) = vbYes Then GoTo EXIT1
            End If
        Next lngIx2
    Next lngIx1
    ' 終了処理に進む
    GoTo EXIT1

'===================================================================================================
' エラー処理
ERR1:
    ' Escキー打鍵か
    If ERR.Number = 18 Then
        ' Escキーでのエラートラップなのでスイッチをセットして戻る
        swEND = True
        Resume
    Else
        ' 他の実行時エラーはメッセージを表示して終了
        MsgBox ERR.Number & " " & ERR.Description, vbCritical
    End If

'===================================================================================================
' 終了処理
EXIT1:
    ' セットしたプロパティを初期値に戻す
    Application.EnableCancelKey = xlInterrupt
    Application.StatusBar = False
End Sub
Application.EnableCancelKey = xlErrorHandler」は、Escキー打鍵で実行時エラーを起こさせる指定です。この時のエラーコード(ERR.Number)は「18」が通知されてきます。



@
Escキーが押されたかの判定スイッチを用意し、判断のループ単位の先頭で初期化しておきます。
A
このサンプルは10回×1000回のループを1単位としており、さらにこれを100回行なうと終了します。この「100回×10回×1000回」の中の状態がステータスバーに表示されます。
B
判断のループ単位の終了で判定スイッチでEscキーが押されたことになっていた場合は、「終了するか」の確認メッセージを表示させ、「はい」だったら終了します。タイミングはステータスバー右端の数値が「1000」になるタイミングです。
C
Escキーが押された瞬間、このエラートラップに進みます。その他の実行時エラーと区別するため、ERR.Number=18の時だけ判断分岐します。
D
この段階では終了できる単位位置ではないので判定スイッチをセットし、「Resume」でそのまま元に戻ります。これで次にBの位置で終了確認されるのです。
ユーザーフォームが表示されている場合は、上記の機能より先にユーザーフォーム側でトラップされるようです。フォーム上にCancelプロパティをTrueにしたボタンを配置しておくと、Escキーが押された場合にこのボタンのクリックイベントが発生します。
この場合、 「Application.EnableCancelKey = xlDisabled」が記述されていてもEscキーでボタンのクリックイベントは発生します。しかし、CtrlBreakでの停止はできないので、この機能が無効なわけではありません。

■ユーザーフォームでのEscキー制御のサンプル
「ユーザーフォームでの閉じるボタン処理」
「プログレスバーのクラス」