AutoCAD VBAの深淵:二重起動の罠と「安全なドキュメント制御」の設計思想
AutoCADのオートメーションにおいて、最も初歩的でありながら、同時に最も現場を疲弊させる問題が「ファイルロック」と「二重オープン」の制御だ。
新人プログラマーは`Documents.Open`を叩くだけで満足するが、我々のようなシステムアーキテクトにとって、それは「地雷原を裸足で歩く」に等しい。AutoCADのCOM APIは、バックグラウンドで発生するドキュメントの初期化ラグや、非同期的なロック状態を必ずしも正確にハンドリングしてくれない。
本稿では、単なる「ループによるチェック」を超えた、堅牢なシステム構築のための設計論を提示する。
—
1. なぜ「単純なループ」だけでは不十分なのか
初心者は`For Each`でファイル名を比較するロジックを組むだろう。しかし、プロフェッショナルは以下の3点を見落とさない。
1. 大文字・小文字の不一致: Windowsのファイルシステムはケースインセンシティブだが、VBAの文字列比較は環境依存する。
2. パスの完全修飾: `FullName`プロパティでの比較は必須である。相対パスやショートファイル名(8.3形式)の混在を考慮しなければならない。
3. オブジェクトの生存期間: `Documents`コレクションの参照を保持し続けることによるメモリリークの温床を排除する。
2. 実装:堅牢なドキュメント・アクセサ
以下に、実戦でそのまま使用可能な、型安全性を考慮したオープンロジックを提示する。
‘ —————————————————————————
‘ @Description: 指定パスの図面を安全にオープンする設計
‘ @Author: Chief Architect
‘ —————————————————————————
Public Function OpenDrawingSafe(ByVal filePath As String) As AcadDocument
Dim doc As AcadDocument
Dim targetPath As String
‘ 正規化: 比較ミスを避けるためフルパスに変換し、大文字で統一する
targetPath = UCase$(CreateObject(“Scripting.FileSystemObject”).GetAbsolutePathName(filePath))
‘ 既に開いているドキュメントを確認
For Each doc In ThisDrawing.Application.Documents
If UCase$(doc.FullName) = targetPath Then
‘ 既に開いている場合はそのインスタンスを返却(アクティブ化)
doc.Activate
Set OpenDrawingSafe = doc
Exit Function
End If
Next
‘ 開かれていない場合のみオープンを試みる
‘ エラーハンドリングを忘れずに(ファイルが存在しない、権限がない等)
On Error Resume Next
Set OpenDrawingSafe = ThisDrawing.Application.Documents.Open(targetPath)
If Err.Number <> 0 Then
MsgBox “オープン失敗: ” & Err.Description, vbCritical
Set OpenDrawingSafe = Nothing
End If
On Error GoTo 0
End Function
—
3. レガシー環境とメモリ管理の極意
VBAはガベージコレクションを持たない。特にAutoCADのような長期間起動し続けるプロセスでは、「オブジェクト参照の明示的破棄」がシステム安定性の要だ。
- Set Nothingの徹底: ループ内で使用した一時的なオブジェクト参照は、処理終了後に必ず `Set obj = Nothing` を行うこと。これを行わないだけで、AutoCADのプロセスは徐々にメモリを食い荒らす「ゾンビ」と化す。
- APIによるロックチェック: ネットワーク上の共有ファイルを扱う場合、VBAの`Documents.Open`が失敗する前に、Win32 APIの `CreateFile` を `GENERIC_WRITE` モードで呼び出し、ファイル共有違反を事前に検知する手法も有効だ。これにより、AutoCADがエラーを吐く前に「使用中」であることをユーザーに通知できる。
4. チーフアーキテクトからの助言
AutoCAD VBAはレガシーと言われることもある。しかし、その強力なAPI群は、現代のC#/.NET環境においても根本的なアーキテクチャは変わっていない。
重要なのは「自分が書いたコードが、どのような状態でAutoCADという巨大なマザーオブジェクトに寄生しているか」を常に意識することだ。「エラーをキャッチする」のではなく「エラーを発生させない状態を設計する」ことこそが、自動化エンジニアの真髄である。
システムが大規模になればなるほど、この小さなチェックロジックが、プロジェクト全体の信頼性を左右する盾となる。明日からのコードに、この「重み」を込めてほしい。
