はじめてのExcelVBA~イベントプロシージャ~

ちょっとご無沙汰してました。クニ吉です。

クリスマスが近いですね。
アイキャッチをクリスマスバージョンにしてみましたw
もちろんパワポ作です(^^)

さて、今回は前回の「はじめてのExcelVBA~基本~」で出た「イベントプロシージャ」についてです。

イベントプロシージャとは

イベントプロシージャとは、特定の動作によって処理を実行するためのプロシージャのことです。 
例えば「ワークシートがアクティブになった時」、「値が変更された時」等があげられます。
この「○○した時」の設定(イベント)によって構文が変化します。

イベントプロシージャの種類

イベントプロシージャは、大きくワークブックのイベントとワークシートのイベントの2つに分類することができます。
ワークブックイベントは、ワークブック(Excelファイル)が開いた時に実行するなどワークブックを操作した際に発生するイベントプロシージャです。
ワークシートイベントは、ワークシートがアクティブになった時に実行するなどワークシートを操作した際に発生するイベントプロシージャになります。

ワークブックのイベントプロシージャ

ワークブックのイベントの中でもワークブック自体の操作に関わるイベントと、「ブック内のシートが選択された時」といったブック内にあるシートの操作に関わるイベントとがあります。
シートの操作に関わるなら「ワークシートのイベントプロシージャ」では?と思いますが、指定したワークシートが適用範囲となるワークシートのイベントプロシージャと異なり、ブック内の全てのシートに対するイベントになります。
つまり、ブック内のシートやセルオブジェクトを評価して処理を実行することが出来ます。
例えば、シートオブジェクトを格納するイベントプロシージャの引数「Sh」を利用して、アクティブになったシート名が「Sheet1」か「Sheet3」の場合は「このシートは参照用です」というメッセージを表示するといった処理ができるため、各シートに同じコードを記述することなく実行することが可能です。

(1)ブックの操作に関するイベント

ワークブックのイベントプロシージャ1-1

(2)ブック内シートの操作に関するイベント

ワークブックのイベントプロシージャ2

ワークシートのイベントプロシージャ

ワークシートのイベントプロシージャは前述の通り指定したワークシートが適用範囲となり、Sheet1に記述したイベントはSheet1のみで発生します。
ブックのイベントのように共通化されたものではなく、シートそれぞれの細かな処理を記述する際に利用します。

ワークシートのイベントプロシージャ

ChangeイベントとCalculateイベントについて

ちょっとわかりづらいのが「Changeイベント」と「Calculateイベント」です。
Changeイベントは一般的に「値が変更された時に発生する」とありますので、セルの値が「1」→「2」に変更された時に発生ものと思っていました。
しかし数式で計算されて値が変更した場合、Calculateイベントのみ発生し、Changeイベントは発生しません。
考えてみればそれも当然で、見ための値は変更しててもセルの中に入っている数式(仮に=SUM(A1:A5))は変更されてないからなんですね。
だけど値を変更してなくてもセルを編集モードにするとChangeイベントが発生するんですけど・・・

【補記】
後からChangeイベントについて社内のエンジニアに相談して試したところ、見ための値は変わらなくても「新しい値でデータを上書き」と認識されてるからイベントが発生するという結論に至りました。
「change」というより「write」の意味合いが近いとのこと。
私が最初に試した時の厳密な発生順序は「編集モード(F2)」→「(値を変更せずに)Enter」→「Changeイベント発生」ですが、途中の「Enter」を「Esc」にして編集モードを抜けるとChangeイベントは発生しませんでした。

 イベントプロシージャの引数

イベントプロシージャの中には引数を持つものがあります。
イベント一覧の(ほにゃらら)となっているものがそうです。
詳細についてはそれぞれの内容をご確認いただきたいのですが、まとめるとこんな感じです。参考までに。

  • Wb    対象となるブックオブジェクトが格納されます。
  • Wn    対象となるウィンドウオブジェクトが格納されます。
  • Sh     対象となるシートオブジェクトが格納されます。
  • Target   対象となるセル範囲が格納されます。
  • Cancel   操作中止の指定。操作を中止する場合は「Cancel=True」を指定します。
           既定値はFalseのため、何も指定しなければそのまま操作が実行されます。

最後にちょっと注意したいこと

イベントプロシージャを使って処理を実行する際に気をつけたいことがあります。
それは処理の無限ループや処理が重すぎて固まってしまうことです。
これはイベントプロシージャに関わらず気をつけるべきことですが、イベントプロシージャの良さ(セルやシートを変更した場合に自動で処理してくれる)は、反対に意図しないちょっとした操作で処理が実行されてしまうということです。
シートをちょっと開いただけでActivateイベントが実行され、固まっちゃったりしたら困りますよね。
このようなことが起こらないようにするには必要のないところもいちいち処理対象にしないことです。
要は「処理速度が落ちるようなコードを書かないこと」ですかね。
例えばChangeイベントを利用する場合、全部のセルに対して実行される必要はないので、処理を実行したいセル範囲以外はExitSubを使って終了させるとか。
特に気をつけたいのはFor~Next、Do~Loopなどの繰り返し処理系。きちんと必要なところだけ見るようにして、ずっとクルクル回らないように逃げ道を作るようにしましょう。

と、今回はこの辺で。またーノシ