処理実行中の表現

時間が掛かる処理を行なう場合は処理中であることを画面で表現しておく必要があります。



■処理状況はステータスバーを利用する。
場合によっては、マクロの動作に時間がかかる場合があります。
このような場合、何らかの方法で処理が実行中であることを操作者に通知する必要があります。通知してあげないと操作者にはExcelがハングした」ような印象を与えてしまいます。

ステータスバーに処理中の表示を出す。
一番簡単なのは、このようにステータスバーを利用することです。ステータスバーに現在の進行状態や「件数」などを表示していけば「進んでいる」ことを認知してもらうことができます。全体の件数が判定できている処理では、「何件中、何件処理」というような感じで表示させると、「どの位で終わるか」も認知できます。

cntRec = cntRec + 1
Application.StatusBar = "処理実行中....(現在 " & cntRec & "件)"
マクロ上の記述も簡単で、処理件数をカウントしているならば、その下に1行加えるだけで済みます。
但し「Application.ScreenUpdating = False」を動作させた後でこの件数表示を頻繁に繰り返すと、 途中で画面が更新されなくなり、実際には止まっていなくてもハングしたように見える場合があります。
この対応のためにはループ処理中にあるサイクル(毎回でなくても)で「DoEvents」を記述することをお勧めします。

※このままマクロが終了してしまうと、ステータスバーの表示はそのまま残ってしまうので、最終的な処理件数はメッセージで通知することにして、ステータスバーの方は元に戻して下さい。
処理終了時の状態
これもコードとしてはこの2行だけです。

Application.StatusBar = False
MsgBox "処理終了しました。(処理件数=" & cntRec & "件)"

■フォームのコントロールにはプログレスバーがない。
ユーザーフォームを表示させた状態で時間がかかる処理を行なう場合は、VisualBasicなどでは「プログレスバー」を利用します。しかし、Excelのユーザーフォームにはこの「プログレスバー」がありません。

しかし、ないから不可能ではなく、似たようなものを作ることは可能です。
プログレスバーを模したフォームのサンプル
詳しくは「ダウンロード」の方の説明に任せますが、元々、コントロールが存在しない場合でも既存のコントロールを組み合わせて使うことで「それらしい動作」は得られます。
このプログレスバーでは、フォームの上に2つの「フレーム(グループボックスに使うもの)」を利用しています。1つはこの画面に見える「青いバー」自体で、もう一つはそれを収容しているテキストボックス状のボックスです。どちらもCaptionをなくし境界の囲いもなくします。外側の方はSpecialEfectで凹んだ形にして、「青いバー」の方はフラットにしてBackColorを青くするわけです。
後は、「青いバー」のWidthを処理状況によって変化させていけば「帯表示がだんだん伸びていく」動作が実現されます。
「ダウンロード」のページのサンプルはクラス化させてあり、モジュール単位にインポートさせてそのまま利用できるようにしてあります。利用方法はサンプルを元に理解していただく必要がありますが、Escキーによる中断機能も盛り込んであるので、総件数が予め取得できる処理であれば試してみて下さい。

■処理中は画面描画や自動計算を停止する。
マクロの動作中の画面描画停止やイベント輻輳などのコントロール配慮して下さい。
長い時間が掛かるような処理では、この点に配慮するだけで極端に時間短縮できる場合があります。
以下のプロパティで制御します。
  • マクロ動作でシートやウィンドウが切り替わるのを見せないようにします。
    Application.ScreenUpdating = False
    を記述すると、画面描画が停止します。これ以降セルにデータを貼ったり、シートを切り替えたり、他のブックを開いたりしても画面には表示されません。
    処理の終了段階でTrueに戻して下さい。
  • マクロ動作自体で別のイベントが生成されるのを抑制する。
    Application.EnableEvents = False
    を記述すると、以降マクロの動作が起因するイベント発生を抑制できます。
    処理の終了段階でTrueに戻して下さい。
  • マクロ動作でセル値などが変わる時自動計算が処理を遅くするのを避ける。
    Application.Calculation = xlCalculationManual
    を記述すると、計算方法が「手動」に切り替わります。計算式が貼られたシートに順次データを置いていくような処理では、「自動」のままで処理すると非常に時間がかかってしまいます。「手動」で動作させると十数倍速くなる例もあるので試して下さい。
    処理の終了段階でxlCalculationAutomaticに戻して下さい。
  • マクロ動作中にEscキーで止められるのを抑制する。
    これは次項で説明します。
  • マクロ動作中に一切のキーやマウス操作を制限する。
    Application.Interactive = False
    を記述すると、処理中はキーボードやマウス等の介入が一切排除されます。当然Escキーでマクロ動作を停止させることもできなくなります。
    処理の終了段階でTrueに戻して下さい。
    但し、この状態で何らかの理由でマクロが停止してしまうと、Excel自体は何も操作できない状態になってしまい、タスクマネージャで強制終了させなければならなくなります。この記述だけは確実に動作検証が終わってから設定して下さい。
  • マクロ動作中はマウスカーソルを「砂時計」にする。
    Application.Cursor = xlWait
    を記述すると、Excelのウィンドウ内はカーソルが「砂時計」になります。
    処理の終了段階でxlDefaultに戻して下さい。
    これはカーソル形状だけの操作なので、もし実行時エラーなどが発生して元に戻せなくても「砂時計」にままでマウスは問題なく操作できます。