VBA DoEvents 関数:応答なしを回避する

はじめに

Excel VBA マクロの DoEvents 関数から応答なしを回避する方法を紹介します。

DoEvents 関数は、制御をオペレーティングシステムに返します。

処理中に Excel の画面をクリックしたりキー入力すると、処理が終わるまで保留されます。応答なしになる原因です。

DoEvents 関数を呼び出して、保留されている入力や描画を即座に実行して、応答なしになるのを回避できます。

  • 目次
    • DoEvents 関数
    • 解説
    • 使用例

DoEvents 関数

DoEvents()
クリックやキー入力や描画の処理を直ちに実行します。

戻り値の型使用しません。

解説

応答なし

時間のかかる処理中に Excel の画面をクリックしたりキーを入力すると、処理が終わるまでその入力が「保留」されます。その結果、応答なしになりフリーズしているように見えます。

DoEvents 関数とは

DoEvents 関数を呼び出すと、保留されている入力 (クリックやキー入力、描画など) をそれが発生した順番にすべて実行します。これで応答なしを回避できます。

使い方

処理中にキャンセルしようとボタンをクリックしても、そのクリックイベントは処理が終わってから発生するのでキャンセルできません。

DoEvents 関数を呼び出すと、処理中にクリックされたボタンのクリックイベントが発生します。そこでキャンセルできます。

ただし、通常は処理が終わってから行われるクリックやキー入力が処理中に行われるため、結果が不正になることがあります。例えば、セルの値を編集中に別の値を入力されると整合性がとれなくなります。エラーが発生することもあります。

このため、DoEvents 関数を使用してもしなくても、処理中に Excel の画面を操作してはいけません。画面の移動くらいなら問題ありません。

DoEvents を使用しないのが一番いいですが、長時間の処理をキャンセルしたり、フリーズしないようにするためには必要になります。

高速化

DoEvents 関数は遅いです。処理中に何度も呼び出すと、その分処理が終わるまで時間がかかります。

詳しくは「高速化」をご覧ください。

使用例

時間のかかる処理中は Excel を操作できません。

' 時間のかかる処理
Dim i As Long
For i = 1 To 10000
    Range("A1").Value = i
Next

DoEvents 関数を実行して、処理中でも Excel を操作できます。

' 時間のかかる処理
Dim i As Long
For i = 1 To 10000
    Range("A1").Value = i
    
    ' 100 回毎に DoEvents を実行
    If i Mod 100 = 0 Then
        DoEvents ' この時点で入力されている処理を実行
    End If
Next

処理をキャンセル

キャンセルボタンがクリックされたか判定して、処理をキャンセルできます。

Private cancelled As Boolean

Sub 実行()

    cancelled = False

    ' 時間のかかる処理
    Dim i As Long
    For i = 1 To 10000
        Range("A1").Value = i
    
        ' 100 回毎に DoEvents を実行
        If i Mod 100 = 0 Then
            DoEvents ' クリックイベントが発生

            ' 処理をキャンセル
            If cancelled = True Then
                Exit Sub
            End If
        End If
    Next

End Sub

' キャンセルボタン
Private Sub CommandButton1_Click()
    cancelled = True
End Sub