VBA DoEvent

Written by

Editorial Team

Reviewed by

Steve Rynearson

Translated by

masahiro yoshida

Last updated on 4月 19, 2022

このチュートリアルでは、VBAでDoEventsコマンドを使用する方法について説明します。 VBAのDoEvent関数は、実行中のマクロを一時的に停止し、Excelにキー操作やマウスクリックなどのオペレーティングシステムのメッセージを処理する機会を提供します。

長時間実行するマクロでは、Excelがハングアップして反応しなくなったように見えることがあり、マクロを中断できなくなることがあります。DoEventsがコードに含まれていれば、ユーザーはマクロがまだ実行されていることを確認でき、必要であれば実行を中断することができます。

VBA DoEventsの例

次のようなコードを考えてみましょう。

Public Sub Test()
    Dim i As Long

    For i = 1 To 20000
        Range("A1").Value = i
    Next i

End Sub

このコードを試すと、Excelウィンドウを操作できないことに気がつくと思います。しかし、このマクロはプロセッサへの負荷が低いので、ESCキーやCTRL+BREAKキーで中断することができます。 このループの中で複雑で負荷の高い関数がたくさん実行されている場合、Excelはキーを押したイベントを登録するのに数分かかるか、まったく登録されない可能性があります。 ここで、Rangeの代入の下にDoEventsを1行追加します。

       Range("A1").Value=i
       DoEvents

このコードをもう一度実行すると、Excelがレスポンシブになっているのがわかると思います。つまり、フォーカスして前面に出すことができるのです。 DoEventsはループの中で毎回呼び出され、マクロが常に実行されるようにし、Excelが送られたメッセージを処理できるようにしています。 このマクロは高速に動作するため、バックグラウンドで動作しているように見えますが(実際はそうではありません)、ループ内でさらに処理を行えば、すぐにその錯覚が露呈します。

DoEventsの危険性

しかし、もう一度見てください。単にExcelにフォーカスを当てるだけでなく、マクロの実行中にセル内をクリックしたり、タブを切り替えたりすることもできます(試してみると、おかしな動作が見られるでしょう)。 これはDoEventの危険性を示しています。マクロが注意深くコーディングされていない場合、意図しない結果を引き起こす可能性があるのです。

もう一つの危険は、DoEventが他のマクロのウィンドウとして機能し、その中で実行される可能性があることです。 ワークシート上にActiveX CommandButtonを置き、それをダブルクリックして、CommandButton1_Click()イベント内に次のコードを追加してください。

    Dim c As Range

    For Each c In Range("B3:E8")

        c.Value = c.Value + 1

    Next c

Excelのデザインモードをオフにし、先ほど追加したTest()マクロを実行します。 Testマクロの実行中に、ワークシート上のCommandButtonをクリックすると、DoEventsがTest()マクロをブレークさせると同時に、その関連マクロが実行されます。

ここで危険なのは、CommandButton マクロが Test() マクロが作業していたデータを変更したり、Test() マクロを再度トリガーしたりした場合です。 注意しないと、非常に面倒な結果になる可能性があります。 最後に、DoEventが呼び出されると、マクロのパフォーマンスに影響を与えることに注意する必要があります。 ループ内では、DoEventsが呼ばれる頻度を制限しない限り、この影響はすぐに大きくなります。 Test()の例を参照して、次のようにしてください。

       If i Mod 1000 = 0 Then DoEvents

これにより、Excelの応答性は目に見えて低下しますが、パフォーマンスへの影響は軽減されます。

DoEventを使用する場合

このような危険性はありますが、DoEventsはテストやデバッグにも役立つ便利な機能です。 長く続くループにDoEventsを追加することを検討してみてください。

DoEventを含めるもう一つの理由は、ユーザーからのフィードバックを可能にすることです。例えば、マクロでUserFormのラベルを更新し、進捗状況を表示させることがあります。DoEventがないと、ExcelはUserFormを再描画するためのメッセージを受け取らず、マクロの動作が停止したかのような印象をユーザーに与えてしまいます。しかし、DoEventsを使えば、UserFormは再描画され続け、マクロの進行状況の更新が表示され続けます。

ほとんどの場合において、DoEventsをコードに含める必要はなく、省略することができます。 しかし、もしあなたのマクロが応答性を必要としているなら、DoEventを無視するべきではないのです。

vba-free-addin

VBA Code Examples Add-in

Easily access all of the code examples found on our site.

Simply navigate to the menu, click, and the code will be inserted directly into your module. .xlam add-in.

(No installation required!)

Free Download

Return to VBA Code Examples