数万件のレコードを読み込んで、かつ1件ごとにさまざまな処理を施すような場合、相当時間がかかることもあるでしょう。そんなときに、"処理中"のメッセージを表示するダイアログを開き、かつその中の[中止]ボタンをクリックすることによって、時間のかかる処理を途中で中止させる方法をご紹介します。
ここでは、1件ごとの処理を実行するとともに処理中メッセージフォームを開くモジュールと、処理中メッセージフォームのモジュールの2つを作ります。
まず、1件ごとの処理を実行するとともに処理中メッセージフォームを開くモジュールでは、次のようなコードを記述します。
Sub StopTest()
Dim iintLoop As Integer
Dim intWrk As Integer
DoCmd.OpenForm "frm処理中メッセージ"
For iintLoop = 1 To 10000
For intWrk = 1 To 10000: Next intWrk
'実際にはここでさまざまな処理をします
DoEvents
If Forms!frm処理中メッセージ.pblnStopFlg Then Exit For
Next iintLoop
DoCmd.Close acForm, "frm処理中メッセージ"
End Sub
ここで、For intWrk.....Next の部分はサンプル用に処理時間を増やすためのダミーループです。実際にはこの部分で1件ごとの処理を実行します。そしてポイントとなるのが、ループ内で実行される DoEvents と、フォーム"frm処理中メッセージ"で宣言されている変数"pblnStopFlg"を参照する部分です。この変数には"frm処理中メッセージ"で停止ボタンがクリックされたかどうかが設定されています。もし、この変数がTrue、つまり停止ボタンがクリックされていればループを抜ける、つまり処理を停止するようにします。しかしこれだけでは動作しません。肝心の「停止」ボタンをクリックすることができないのです。ループ内の処理中は完全にこの処理だけにWindowsが占有されてしまうためです。これを回避するために DoEvents を記述して、一時的にWindowsに制御を渡してやります。
一方、処理中メッセージフォームのクラスモジュールにも次のようなコードを記述します。
Public pblnStopFlg As Boolean
Private Sub cmdStop_Click()
'中止ボタンがクリックされたら中止フラグをONする
pblnStopFlg = True
End Sub
変数 pblnStopFlgは、メインの処理を行うプロシージャからも参照される変数です。必ず"Declarations"セクションに"Public"を付けて宣言します。そして、"cmdStop"という名前の中止ボタンがクリックされたら、この変数をTrueにすることによって、メインの処理を行うプロシージャに中止ボタンがクリックされたことを知らせます。 |