マクロで大量のデータを処理するような場面では、「あ、ちょっと間違えたかも…」と途中で処理を止めたくなることがあります。
しかし、標準のVBAマクロでは、一度実行を始めると処理が終わるまで止まりません。
こういった場面で便利なのが、「キャンセル」できる仕組みです。
今回は、マクロの処理中にユーザーが途中で「やめる」判断をできるようにするための、キャンセルボタン的な実装方法をご紹介します。
キャンセル判定用のユーザーフォームを用意する
マクロを実行しながら、ユーザーが「キャンセル」できるようにするには、ユーザーフォームを表示して、そこにキャンセルボタンを配置する方法が定番です。
まずは、ユーザーフォームを次のように作成します。
- VBEで「挿入」→「ユーザーフォーム」
- 名前を「frmCancel」に変更
- ボタン(CommandButton)を1つ配置し、「cmdCancel」という名前に変更
- キャプションに「キャンセル」と表示
このフォームには、キャンセルされたかどうかを示す「フラグ変数」を使います。標準モジュールに次のように変数を定義しておきます。
Public CancelFlg As Boolean
次に、キャンセルボタンのクリックイベントに以下のコードを記述します。
Private Sub cmdCancel_Click()
CancelFlg = True
Unload Me
End Sub
この仕組みによって、「ボタンが押されたら CancelFlg を True にしてフォームを閉じる」という動作が実現できます。
メイン処理側のコードでキャンセルをチェックする
次に、長い処理の中でキャンセルが行われたかどうかを定期的にチェックするようにします。
以下はA列のデータを1万件処理するような例です。
Sub RunWithCancel()
Dim i As Long
CancelFlg = False
frmCancel.Show vbModeless ' フォームを開きながら処理を続けるように表示する
For i = 2 To 10000
' 処理の本体(ここではダミー)
Cells(i, 2).Value = Cells(i, 1).Value * 2
DoEvents ' 他の操作を受け付ける
If CancelFlg = True Then
MsgBox "処理がキャンセルされました。", vbExclamation
Exit For
End If
Next i
Unload frmCancel
End Sub
ここでのポイントは DoEvents を入れていることです。
これにより、ループ中でもユーザーフォームの操作が反映され、ユーザーが「キャンセル」ボタンを押せる状態になります。
コードのポイント
vbModelessでフォームを非モーダル表示(処理と並行で操作できる)DoEventsで処理中でも他のイベント(ボタン押下)を受け付けるCancelFlgを見て処理の中断を判定
実装するメリット
キャンセル機能を実装することで、次のような実用的な効果が得られます。
- 間違って長時間の処理を始めたときでも、ユーザー自身が中断できる
- テスト中に「何かおかしいな」と感じたら、すぐ止められる
- 運用上の「使いづらさ」「不安感」を軽減できる
- 処理を止める判断をユーザー側に任せることで、柔軟性の高いマクロ運用ができる
特に、データ件数が多い業務や、マクロの実行時間が長くなる作業では、キャンセル可能な仕組みを入れておくだけで安心感がまったく違ってきます。
まとめ
VBAでは、処理が始まると通常はユーザーが止める方法がありません。
ですが、ユーザーフォーム+フラグ変数+DoEvents を組み合わせれば、処理中でも「やめたい」と思ったら即中断できるマクロが実現できます。
- ユーザーフォームを「キャンセルボタン」として使う
vbModelessで表示して、並行操作を可能にするCancelFlgでキャンセル判断を反映するDoEventsでマクロ中の操作反映を可能にする
この仕組みは、ただ便利というだけでなく、マクロの安全性とユーザー体験を高めるための大切な工夫です。
ぜひ一度、あなたのマクロに取り入れてみてください。処理の信頼性と柔軟性が大きく向上します。
