【極限の知見】AutoCAD VBAにおける「図面オープン」を極める:壊滅的エラーを回避するプロフェッショナル・リカバリ戦略
業務自動化の世界において、プログラムが「正常なデータ」を処理できるのは当たり前だ。しかし、現場に転がっているのは、誰かが編集中でロックされたファイル、ネットワーク越しで瞬断されるパス、あるいは構造が物理的に破損したDWGファイルである。
初心者は「開けなかったら飛ばす」コードを書く。
中級者は「On Error Resume Next」で茶を濁す。
だが、我々プロフェッショナルは、エラーが起きることを前提に「システムの整合性を維持し、沈黙のうちにリカバリする」設計を行う。
今回は、AutoCAD VBAにおける図面オープン処理の脆弱性を徹底的に排除し、エンタープライズ級の堅牢性を実現するための戦略を伝授する。
—
1. なぜ `Documents.Open` は牙を剥くのか
AutoCADの `Documents.Open` メソッドは、一見シンプルだが非常にデリケートな挙動を示す。以下の要因が重なると、VBAは即座に実行時エラーを吐くか、最悪の場合AutoCAD自体をフリーズさせる。
- 排他制御の衝突: 他のユーザーが既に開いている(.dwl / .dwl2 ファイルの存在)。
- ダイアログの割り込み: バージョン違い、フォント欠落、プロキシオブジェクトの警告など、UIが応答を待機してしまう。
- リソースの枯渇: 大容量ファイルを連続で開く際のメモリリーク。
- ファイルパスの不整合: 長すぎるパス(MAX_PATH制限)や、特殊文字。
これらを「開いてみるまでわからない」運任せの処理にしてはならない。
—
2. 堅牢なオープン処理の三原則
優れた自動化ツールを構築するための、チーフアーキテクトとしての設計指針を提示する。
1. プリ・フライト・チェック(事前検証): `Documents.Open` を呼ぶ前に、ファイルが存在するか、アクセス権があるかをOSレベルで確認する。
2. サイレント・モードの徹底: ユーザー入力を待つダイアログを徹底的に抑制する。
3. オブジェクト・ライフサイクルの完全管理: 失敗しても成功しても、必ず「クリーンな状態」へ戻す。
—
3. プロダクション・グレードの実装例
以下のコードは、単なるサンプルではない。現場の泥臭いエラーを網羅し、保守性と再利用性を極限まで高めたラッパー関数である。
”
‘ @description 図面を安全にオープンするためのプロフェッショナル・ラッパー
‘ @param filePath フルパス
‘ @param readOnly 読み取り専用で開くか
‘ @param password パスワード(必要な場合)
‘ @return AcadDocument 成功すればオブジェクトを返し、失敗すればNothingを返す
”
Public Function SafeOpenDrawing(ByVal filePath As String, _
Optional ByVal readOnly As Boolean = False, _
Optional ByVal password As String = “”) As AcadDocument
Dim targetDoc As AcadDocument
On Error GoTo ErrorHandler
‘ — 1. プリ・フライト・チェック —
‘ ファイル存在確認
If Dir(filePath) = “” Then
Debug.Print “Error: ファイルが存在しません -> ” & filePath
Exit Function
End If
‘ 書き込み権限チェック(readOnlyがFalseの場合のみ)
‘ .dwlファイル等のチェックをOSレベルで行うロジックをここに挟むのが理想
‘ — 2. AutoCAD環境の静音化 —
‘ ダイアログ表示を抑制(システム変数のバックアップは上位で行うこと)
ThisDrawing.SetVariable “FILEDIA”, 0
ThisDrawing.SetVariable “EXPERT”, 5
‘ — 3. 図面オープン実行 —
‘ エラーハンドリングを局所化
If password <> “” Then
Set targetDoc = Documents.Open(filePath, readOnly, password)
Else
Set targetDoc = Documents.Open(filePath, readOnly)
End If
‘ オープン直後の検証
If targetDoc Is Nothing Then
GoTo ErrorHandler
End If
‘ 正常終了
Set SafeOpenDrawing = targetDoc
Exit Function
ErrorHandler:
‘ — 4. リカバリ戦略 —
Dim errDesc As String: errDesc = Err.Description
Dim errNum As Long: errNum = Err.Number
‘ ログ出力(DBやテキストファイルへの記録を推奨)
Debug.Print “Failed to open: ” & filePath & ” | Error: ” & errNum & ” – ” & errDesc
‘ 後処理:もし中途半端にオブジェクトが生成されていたら破棄
If Not targetDoc Is Nothing Then
‘ 破損している可能性を考慮し、保存せずに閉じる試行
On Error Resume Next
targetDoc.Close False
Set targetDoc = Nothing
End If
‘ 必要に応じて、呼び出し側にカスタムエラーを投げるか、Nothingを返して継続させる
Set SafeOpenDrawing = Nothing
End Function
—
4. アーキテクトが教える「運用の急所」
DWLファイル(ロックファイル)の罠
AutoCADは図面を開くと、同じディレクトリに隠しファイル(.dwl)を作成する。VBAで大量の図面を高速に処理する場合、このロックファイルの生成・削除がOSのファイルシステム上で追いつかず、「先ほど閉じたばかりのファイルがまだロックされている」と誤認されるケースがある。
対策: `Documents.Open` の直前に数ミリ秒の `DoEvents` または `Sleep` を挟むか、再試行(リトライ)ロジックを組み込むのが実務上の定石だ。
メモリリークとプロセスの健全性
数百個のDWGを一つのAutoCADセッションで開き続けると、メモリ使用量は右肩上がりに増大する。
知見: プロフェッショナルなツールでは、50ファイルごとにAutoCADのインスタンスを再起動するか、`Set targetDoc = Nothing` を徹底し、COM参照カウントを確実にゼロにする設計を採る。
データベース連携時のトランザクション
図面を開いた後に外部データベース(SQL Server等)を更新する場合、図面オープンに失敗した時点でDB側のトランザクションもロールバックしなければならない。エラーハンドリングは単一の関数で完結させず、システム全体の「ステート(状態)」を管理する視点を持て。
—
5. 最後に:コードに魂を込める
我々が書く1行の `Documents.Open` の背後には、ユーザーが何時間もかけて作り上げた貴重な設計データがある。そのデータを不適切なエラー処理で破壊したり、処理を途中で投げ出したりすることは、エンジニアとしての怠慢である。
「例外は必ず起きる」という謙虚な姿勢と、「起きた例外はすべて制御下におく」という傲慢なまでの自信。この両輪が揃って初めて、真に価値のある業務自動化ツールが完成する。
君のコードが、現場のトラブルを未然に防ぐ「防波堤」となることを期待している。
