AutoCAD VBAの深淵へ:一括処理を「ESCキー」で安全に制御するプロの作法
AutoCAD VBAで数百枚の図面を一括処理するマクロを書いたとき、誰もが一度は経験する恐怖があります。そう、「無限ループに陥ってAutoCADがフリーズし、タスクマネージャーで強制終了するしかない絶望」です。
マクロの記録から脱却し、エンジニアとしてステップアップしたいあなたへ。今日は、AutoCADを「止まらない暴走列車」にしないための、「ESCキーによる安全な中断処理」という奥義を伝授します。
—
なぜ「DoEvents」と「GetAsyncKeyState」が必要なのか?
通常、VBAが重い処理(ループ)を実行している間、AutoCADのインターフェースは「応答なし」状態になります。Windowsは「このプログラムは今忙しいから、ユーザーの入力(キーボードやマウス)を無視しよう」と判断するからです。
これを回避するために、以下の2つの武器を使います。
1. `DoEvents`関数: OSに「今、処理の合間だから、溜まっているマウス操作やキー入力のイベントを処理していいよ」と許可を出す魔法の関数。
2. `GetAsyncKeyState` API: Windowsのシステムレベルで、今ESCキーが押されているかを直接監視するスパイのような関数。
—
実装コード:安全な中断処理のテンプレート
このコードをモジュールの先頭に貼り付ければ、どんなループ処理も「ESCキーでいつでも停止可能」な、プロ仕様のツールに生まれ変わります。
‘ Windows APIの宣言:ESCキーの状態を監視する
If Win64 Then
Private Declare PtrSafe Function GetAsyncKeyState Lib “user32” (ByVal vKey As Long) As Integer
Else
Private Declare Function GetAsyncKeyState Lib “user32” (ByVal vKey As Long) As Integer
End If
‘ 仮想キーコード:ESCキー
Private Const VK_ESCAPE As Long = &H1B
Sub BatchProcessWithAbort()
Dim i As Long
‘ ユーザーに注意を促す
MsgBox “処理を開始します。ESCキーで中断可能です。”
‘ メインのループ処理(例として100回繰り返す)
For i = 1 To 100
‘ 1. 【極意】ここでWindowsに制御を戻し、イベントを処理させる
DoEvents
‘ 2. 【極意】ESCキーが押されているか監視
If (GetAsyncKeyState(VK_ESCAPE) And &H8000) Then
If MsgBox(“中断しますか?”, vbYesNo + vbQuestion) = vbYes Then
MsgBox “ユーザー操作により中断しました。”
Exit Sub ‘ 処理を安全に抜ける
End If
End If
‘ — ここに実際の業務処理を書く —
‘ 例: ThisDrawing.ModelSpace.AddCircle …
Debug.Print “処理中: ” & i & “枚目”
Next i
MsgBox “すべての処理が完了しました。”
End Sub
—
コード解説:ここがエンジニアの腕の見せ所
- なぜ`GetAsyncKeyState`を使うのか?
AutoCADの`ThisDrawing.Utility.GetInput`などもありますが、ループ中に挟み込むにはAPIが最も軽量で確実です。`&H8000`との論理積をとることで、「今まさに押されている」というフラグを正確に判定しています。
- `DoEvents`の副作用を知る
`DoEvents`は便利ですが、「ループの中で多用しすぎると処理速度が落ちる」という欠点があります。1000枚単位の図面を扱うなら、10枚ごとに`DoEvents`を実行するなど、処理負荷とのバランスを調整するのがベテランの流儀です。
- 安全な終了処理の重要性
単に`End`ステートでマクロを止めてはいけません。開いた図面を閉じる`Close`メソッドや、エラーハンドリングを通過させないと、メモリリークやAutoCAD本体の不安定化を招きます。必ず`Exit Sub`で「正常な手順を踏んで終了」させるのが鉄則です。
—
陥りやすい罠と対策
1. 「ESCキーを押しても反応しない」
→ `DoEvents`の配置場所が適切でない可能性があります。ループ内の「重い処理」の直前か、あるいはループの先頭に必ず置いてください。
2. 「中断した後にAutoCADが不安定になる」
→ ループ内で`Application.ScreenUpdating = False`などで画面更新を止めている場合、中断時に必ず`True`に戻す処理を忘れずに入れてください。
最後に:自動化は「責任」を伴う行為
AutoCAD VBAを極めるということは、単に便利なツールを作るだけでなく、「いざという時に制御を手放さない」という安全装置を設計することでもあります。
今回紹介した手法をマスターすれば、もう「フリーズによる強制終了」の恐怖に怯える必要はありません。自信を持って、より高度な一括処理の世界へ踏み出してください。
ここをクリアしたあなたなら、次は「エラーハンドリング(On Error GoTo)」を組み合わせて、より堅牢なシステムを構築できるはずです。応援していますよ!
