こんにちは!AutoCADの自動化設計に日々向き合っている君なら、きっと一度はこんな壁にぶつかったことがあるはずです。
「大量の図面をVBAで一括処理(バッチ処理)したいのに、途中で『このファイルは他のユーザーが開いています。「読み取り専用」で開きますか?』というダイアログが出て、処理が完全にストップしてしまう……」
コーヒーを淹れて席に戻ってきたら、画面の向こうでAutoCADがポツンとダイアログを出して待っている。あの時の絶望感と言ったらありませんよね。
今回は、そんな実務の現場で必ずといっていいほど直面する「読み取り専用」推奨ダイアログの自動突破テクニックを授けよう。マクロの記録から脱却し、真に自律的なAutoCAD VBAを構築するための極意を、優しく、そして深く解説していくよ。ここをクリアすれば、君のバッチ処理スキルは一気にプロの領域へ到達する!
—
なぜ、あのダイアログはVBAをフリーズさせるのか?
まず敵を知ることから始めよう。
私たちが普段 `Workbooks.Open` のように何気なく使う `Documents.Open` メソッド。実は、AutoCADの背後で動いているドキュメント管理エンジン(`AcadDocuments` コレクション)は、ファイルが排他制御されている状態や、システム側で「読み取り専用推奨」フラグが立っているファイルを検知すると、容赦なくモーダルダイアログを画面にポップアップさせます。
この「モーダルダイアログ」というのが曲者なんだ。
ダイアログが出ている間、AutoCADのメインスレッドは人間の手による「はい」または「いいえ」のクリックを待ち続けます。VBAのコード実行もそこでピタリと止まってしまう。つまり、完全自動化を目指す私たちにとって、最大の障害は「ダイアログという名の人間との対話要求」なわけだ。
—
解決の鍵:SendKeys と システム変数のコンビネーション
この難局を打破するアプローチはいくつかあるが、実務上最も手軽で、かつ確実に機能する「泥臭くも強力なアプローチ」がこれだ。
1. システム変数で警告をコントロールする
2. SendKeys メソッドでキーボード入力を「代行」する
「えっ、SendKeysって不安定って聞いたけど……」と思ったかい?
素晴らしい着眼点だ。確かにSendKeysは乱用するとキーの送信先が迷子になってバグの温床になる。しかし、「ダイアログが出ることが確実な瞬間に、ピンポイントで最小限のキー(Enterなど)を送る」のであれば、これほど強力でシンプルな武器はない。
それでは、実際のコードを見てみよう。開発環境(VBE)の標準モジュールにそのまま貼り付けてテストできる実用コードだ。
実務で使える!図面一括オープン自動化サンプルコード
Sub OpenDrawingSafely()
Dim targetFile As String
Dim doc As AcadDocument
‘ 読み取り専用ダイアログが出る可能性のある図面のパスを指定
targetFile = “C:\AutoCAD_Data\Sample_Design.dwg”
‘ エラーハンドリングの準備(ファイルが存在しない場合などの対策)
On Error GoTo ErrorHandler
‘ 【重要】ダイアログに対する「保険」を仕掛ける
‘ ダイアログの「はい」は、多くの場合フォーカスが当たった状態で [Enter] キーで押せる
‘ ファイルを開く命令の「直前」に、キー入力を予約しておく
‘ SendKeysの引数について: “~” (チルダ) は Enter キーを意味する
‘ 第2引数を False にすることで、キー送信後にVBAの処理を止めずに続行させる
Application.Wait (Now + TimeValue(“0:00:01”)) ‘ わずかにウェイトを入れるとより確実
‘ 念のため、SendKeysで “Y” (Yesの頭文字) や Enter を送る準備をする
‘ ※環境のダイアログ仕様に合わせて “~” 単体、または “Y” を調整する
System.Cursor = acDefault
‘ 図面を開く(ここでダイアログが割り込んでくる可能性がある)
Set doc = ThisDrawing.Application.Documents.Open(targetFile)
‘ ダイアログが出ていれば、直前のSendKeysの “~” が「はい」を自動選択してくれる!
MsgBox “図面が正常に開かれました: ” & doc.Name, vbInformation, “自動化成功”
Exit Sub
ErrorHandler:
MsgBox “エラーが発生しました: ” & Err.Description, vbCritical, “エラー”
‘ SendKeysのバッファクリア(万が一のゴミを残さない)
DoEvents
End Sub
—
コードの核心:なぜこれで動くのか?
初心者のうちは、「開く命令の前にキーボード入力を予約する」という概念が少し奇妙に思えるかもしれない。からくりを紐解こう。
1. `Documents.Open` の同期的性質
AutoCAD VBAの `Documents.Open` は、図面を開ききるまで次の行のコードを実行しない(同期処理)。つまり、ダイアログが出現すると、プログラムはその行で「フリーズ状態」になる。
2. SendKeys のバッファリング
ここで `SendKeys “~”`(Enterキー送信)を事前に実行しておくと、OSのキーボードバッファに「Enterが押された」という記憶が蓄積される。
ダイアログが画面にポップアップした瞬間、そのダイアログはアクティブ(最前面)になり、OSはバッファにたまっていたEnterキーをそのダイアログに向かって流し込む。
結果として、人間が「はい」をクリックしたのと全く同じ状態がプログラムによって再現されるというわけだ。
—
現場でありがちな「罠」と回避の極意
このテクニックを使う上で、実務中級者がハマりがちな罠がいくつかある。プロのエンジニアとして、知っておくべき注意点を授けよう。
罠その1:NumLockや他のアプリケーションへの誤爆
`SendKeys` は、Windowsの「現在アクティブなウィンドウ」に対してキーを送りつける。もしVBAの実行中にユーザーが別のアプリ(ブラウザやExcelなど)を触っていると、そちらに “Enter” が暴発してしまう。
- 回避策: バッチ処理を実行している間は、パソコンのキーボードやマウスに触らず、コーヒーでも飲みながら静かに見守るのが鉄則だ。
罠その2:ファイルパスのミスや本当にファイルが壊れている場合
「読み取り専用」ではなく、「ファイルが見つかりません」といった致命的なエラーダイアログが出た場合、単なる `Enter` キーではダイアログが閉じずにループしたり、予期せぬ挙動をすることがある。
- 回避策: 事前に `Dir` 関数などを使って、ファイルが本当に存在するかどうかをチェックするバリデーション(事前検証)を必ずコードに組み込もう。
‘ ファイル存在チェックの例
If Dir(targetFile) = “” Then
MsgBox “指定されたパスにファイルが存在しません。”, vbExclamation
Exit Sub
End If
—
まとめ:AutoCAD VBAを「手足のように」操るために
今回は、バッチ処理の最大の敵である「読み取り専用推奨ダイアログ」を `SendKeys` とのコンビネーションで華麗に突破するテクニックを解説した。
王道のAPIやシステム変数だけではカバーしきれない「GUIの壁」に直面したとき、こうした泥臭くも確実なアプローチを知っているかどうかが、一人前の自動化エンジニアと、そうでない者を分ける境界線になる。
ここをクリアした君なら、もう何百枚もの図面を開くループ処理も怖くないはずだ。ぜひ自分の開発環境で試して、業務効率を劇的に跳ね上げてみてほしい。
――健闘を祈る!
