ねらい:マクロ停止ボタンで「ユーザーが安心して中断できる」仕組みを作る
Excel VBAの長い処理では「やっぱり止めたい」と思うことがあります。通常は Escキー で中断できますが、初心者や利用者にとっては分かりにくい。そこで「停止ボタン」を用意して、ユーザーがクリックで安全に処理を止められるようにするのが親切です。
- 目的: 長時間処理をユーザーが自分で中断できるようにする
- 基本戦略: 「キャンセルフラグ」を用意し、ボタンを押すとフラグが立ち、ループ処理が中断される
- 重要ポイント(深掘り):
- 強制終了は危険:
Endステートメントで止めると後処理が実行されず、環境が壊れることがある - 安全な停止: 「フラグ判定→Exit Sub」で抜ける方式が最も安全
- UI応答:
DoEventsを挟むことでボタン操作が反映される
- 強制終了は危険:
基本テンプレート:キャンセルフラグ方式
' 標準モジュールに置く
Public gCancel As Boolean
Sub LongProcess()
gCancel = False
Dim i As Long
For i = 1 To 100000
' --- 本処理 ---
Dim s As String
s = "テスト" & i
' ----------------
' 停止判定
If gCancel Then
MsgBox "処理を中断しました。"
Exit Sub
End If
' UI応答を確保
If i Mod 100 = 0 Then DoEvents
Next
MsgBox "処理完了!"
End Sub
VB重要ポイント(深掘り)
- グローバル変数
gCancel: 停止ボタンが押されたかどうかを保持 DoEvents: これがないとボタン操作が反映されず、止められないExit Sub: 安全に処理を抜ける。後処理(画面更新やメッセージ)も実行可能
停止ボタンの作り方(フォームボタン)
- シート上に「フォームコントロールのボタン」を配置
- マクロに「StopProcess」などを割り当てる
Sub StopProcess()
gCancel = True
End Sub
VB- 重要ポイント(深掘り):
- ボタンを押すと
gCancel = Trueになり、次のループ判定で処理が止まる - 停止ボタンは「常に見える場所」に置くと安心
- ボタンを押すと
ユーザーフォームに停止ボタンを置く(UI強化)
- UserForm1 を作成
- CommandButtonCancel を配置(Caption: “停止”)
- コードを追加
' UserForm1 モジュール
Private Sub CommandButtonCancel_Click()
gCancel = True
Me.Label1.Caption = "停止要求中..."
End Sub
VB- 重要ポイント(深掘り):
- フォームを非モーダル表示(
UserForm1.Show vbModeless)にすると、処理中でもボタンが押せる - 停止要求中の表示を出すとユーザーが安心
- フォームを非モーダル表示(
例題で練習
- 例1:
LongProcessを実行 → 停止ボタンを押すと「処理を中断しました」と出る - 例2: 停止ボタンを押さずに最後まで実行 → 「処理完了!」と出る
- 例3: UserForm版を試す → 停止ボタンを押すと「停止要求中…」が表示され、処理が止まる
実務の落とし穴と対策
- 落とし穴1:強制終了で環境が壊れる
- 対策:
Endは使わず、フラグ判定で安全に抜ける
- 対策:
- 落とし穴2:DoEventsを入れないと止まらない
- 対策: 適度に
DoEventsを挟む(例:100件ごと)
- 対策: 適度に
- 落とし穴3:停止ボタンが見えない
- 対策: シート上のフォームボタンや非モーダルフォームで常に操作可能に
- 落とし穴4:停止後に後処理が抜ける
- 対策: 停止時も必ず「後片付け処理」を入れる(画面更新・メッセージなど)
スターター手順
- グローバル変数
gCancelを用意 - 停止ボタンを作成し、
StopProcessを割り当てる - 長処理ループに「If gCancel Then Exit Sub」と「DoEvents」を組み込む
- 停止後のメッセージや後処理を必ず入れる
