【Excel VBA】究極奥義!VBA実行中に応答せずフリーズしたときの対処法

ExcelなどのVBAで繰り返し処理など長時間実行をする処理を実行したときに、応答がなくホワイトアウトした状態になってしまって、Escキーを押しても反応せず困った経験はないでしょうか。
こんな状態です。

今回はそんなときに対処する方法をご紹介したいと思います。

「ESC」を連打してみる

はい、とりあえず「ESC」を連打してみましょう。
1秒間隔でタン、タンと「ESC」を押すとよいとの情報もあります。

さっそく、サンプルのマクロで試したいと思います。

Sub 長時間ループ()
    Dim i As Long
    
    Do While i < 1000000 ' i が 1000000より小さい間ループする
        i = i + 1
        Cells(i, 1) = i
    Loop
    
End Sub

画面がホワイトアウトする前にやれば結構な確率で中断されますね。

下手に足掻いてウインドウ操作をしてしまうとホワイトアウトされてしまうので、早めの対処が肝心かと思います。

なおホワイトアウト後でもマクロのブレイクポイントにうまく入れば中断できるかもしれません。

しかし、これは運でしょうか。必ずしもうまくいくとは限りません。

DoEvents()をマクロへ追加する

DoEvents関数はExcelからOSのWindows本体に制御を渡す処理で、安定化を行うことが可能となります。

これを実装して試してみたいと思います。

Sub 長時間ループ()
    Dim i As Long
    
    Do While i < 1000000 ' i が 1000000より小さい間ループする
        i = i + 1
        Cells(i, 1) = i
    Loop
    DoEvents
End Sub

うーん、ホワイトアウトされますね。。

心なしかウインドウの切り替えは少しスムーズになったような気がします。

繰り返し処理の場合は制御をOSへ渡しても結局処理は続くので根本解決にはならないみたいですね。

DoEvents訂正版

読者様よりご指摘ありました。
DoEvents()の設定位置はループの中である必要がありますので以下の通り訂正をいたします。

Sub 長時間ループ()
    Dim i As Long
    
    Do While i < 1000000 ' i が 1000000より小さい間ループする
        i = i + 1
        Cells(i, 1) = i
        DoEvents
    Loop
    
End Sub

こちらですと、ホワイトアウトされませんね。

タカヒロ
タカヒロ
大変失礼しました…

「Esc」を押しながら他のウインドウをいろいろ開いてみる

Twitterで見かけた裏技のようなものです。
「Esc」を押しながらExcel以外の他のウインドウをいろいろ開いてみましょう。
私の場合はChromeのウインドウに切り替えたときに中断できました。

マクロの処理内容やPCのスペックによって結果が異なるのかもしれませんが、おまじない程度に思っておいたほうがよいかもしれません。

究極奥義:タスクマネージャから強制終了する

はい、タスクマネージャから対象のアプリケーションを指定して強制的にブッチします。
ほぼ確実に終了できますが、その分リスクがありますので最終奥義としました。

タスクマネージャの起動方法は2種類あります。
1.タスクバー上でクリックしメニューから「タスクマネージャーの起動」を選択します。

2.「Ctrl」 +「Alt」 + 「Delete」を同時に押し「Windows のセキュリティ」ダイアログが表示されますので画面の一番下の「タスク マネージャ」をクリックします。

タスクマネージャが起動したら、「プロセス」タブをクリックし、「アプリ」を展開し、VBEを探したら、右クリックし、「タスクの終了」をクリックします。

これでほぼ確実に処理が中断というか、サンプルではExcelとVBEが強制終了させられます。

ということは更新分の内容も吹っ飛びますので、処理実行前には必ずセーブすることを心がけましょう。

さいごに

いかがでしょうか。
マクロ処理中に応答がないときに知っておくと無駄な時間を使わずに対処ができるのでぜひ覚えてもらえばと思います。



この記事の関連キーワード

こちらの記事の関連キーワード一覧です。クリックするとキーワードに関連する記事一覧が閲覧できます。








2 件のコメント

    • ご指摘ありがとうございます。

      DoEventsはループ内に設置する必要がありますね。
      記事中のコードを訂正させて頂きました。

      大変失礼いたしました。

  • コメントを残す

    メールアドレスが公開されることはありません。 * が付いている欄は必須項目です