AutoCAD VBAを掌握する極限の知見:複数バージョン共存環境における`AcadApplication`の厳密な起動制御
AutoCAD VBAの開発において、最も厄介でありながら避けて通れない問題が、「複数バージョンの共存環境(マルチバージョン)」である。
クライアントの端末にAutoCAD 2022、2024、そして最新の2025が同居している。このような現場で、開発者が意図しないバージョンのAutoCADプロセスがバックグラウンドで起動し、APIの仕様差異(特にCOMコンポーネントのメソッド変更やドキュメント構造の変更)によって予期せぬクラッシュを引き起こす――これは、レガシーかつモダンなCADインフラの現場で幾度となく目撃されてきた悪夢だ。
本稿では、一般的な入門書が触れない「COMの裏側」「ProgIDのバインディングメカニズム」、そして「確実なプロセス制御とメモリ管理」の極限の知見を公開する。
—
1. 基礎的アプローチの罠:なぜ `CreateObject(“AutoCAD.Application”)` は破綻するのか
多くのプログラマが最初に直面するバグは、次のようなコードに起因する。
‘ 【アンチパターン】バージョンを固定しない起動
Dim acadApp As Object
Set acadApp = CreateObject(“AutoCAD.Application”)
このコードは一見して動くように見える。しかし、レジストリ(`HKEY_CLASSES_ROOT\AutoCAD.Application`)のデフォルト値が最後にインストールされた、あるいは最後にアクティブになったバージョンに書き換わるというWindowsのCOM仕様に依存している。
つまり、開発者が意図したバージョンとは異なるAutoCADが立ち上がり、APIのバージョン不整合(Type MismatchやMethod not found)を引き起こす原因となる。
ProgIDのバージョンサフィックス指定
これを防ぐ唯一の標準的な手段が、ProgIDへのバージョン番号の明示的な付与である。
- AutoCAD 2022: `AutoCAD.Application.24`
- AutoCAD 2023: `AutoCAD.Application.24.1`
- AutoCAD 2024: `AutoCAD.Application.24.2`
- AutoCAD 2025: `AutoCAD.Application.25`
しかし、これだけではプロフェッショナルなシステム要件を満たすことはできない。「指定したバージョンがインストールされていない場合のエラーハンドリング」や「既に起動している特定バージョンのプロセス(Single Instance / Multi Instance)のフック」を考慮する必要がある。
—
2. 【実践】バージョン指定アタッチ・起動の実装コード
以下に、指定したバージョン(例: AutoCAD 2024 / ProgID: `AutoCAD.Application.24.2`)を確実にターゲットにし、起動していなければ新規起動、起動していれば既存インスタンスを安全に取得する堅牢なVBAコードを提示する。
Option Explicit
‘ シニアエンジニアが実装すべき、バージョン指定型AutoCADファクトリー関数
Public Function GetSpecificAutoCAD(ByVal versionProgID As String) As Object
Dim acadApp As Object
On Error Resume Next
‘ 1. 実行中のインスタンスにアタッチを試みる(GetActiveObject)
‘ ※注意: 同一バージョンの複数起動がある場合、最初に登録されたインスタンスを掴む
Set acadApp = GetObject(, versionProgID)
If acadApp Is Nothing Then
Err.Clear
‘ 2. インスタンスが存在しない場合は新規起動(CreateObject)
Set acadApp = CreateObject(versionProgID)
If acadApp Is Nothing Then
MsgBox “指定されたAutoCAD (” & versionProgID & “) の起動に失敗しました。”, vbCritical, “致命的エラー”
Set GetSpecificAutoCAD = Nothing
Exit Function
End If
End If
On Error GoTo 0
‘ 3. 可視化の保証(COM経由での起動時はVisibleがFalseの場合があるため)
acadApp.Visible = True
Set GetSpecificAutoCAD = acadApp
End Function
‘ 呼び出しサンプル
Sub Main()
Dim targetCAD As Object
‘ AutoCAD 2024 を明示的に指定
Set targetCAD = GetSpecificAutoCAD(“AutoCAD.Application.24.2”)
If Not targetCAD Is Nothing Then
MsgBox “接続成功: ” & targetCAD.Name & ” (Version: ” & targetCAD.Version & “)”, vbInformation
‘ — ここに業務ロジックを記述 —
‘ 【重要】オブジェクトの明示的解放(メモリリーク防止)
Set targetCAD = Nothing
End If
End Sub
—
3. チーフアーキテクトが教える:COMのライフサイクルとメモリ最適化の極意
VBAのガーベージコレクション(GC)は曖昧であり、特にAutoCADのような巨大なCOMサーバーを操作する場合、「参照の解放漏れ」がAutoCADのバックグラウンド残留(ゾンビプロセス)を引き起こす。 タスクマネージャーに `acad.exe` が何重にも残り、メモリを圧迫し続ける現象の正体はこれだ。
ゾンビプロセスを防ぐための鉄則
1. ドキュメントとアプリケーションの階層を正確に逆順で解放する
オブジェクトを解放する際は、取得した階層の逆順(Document -> Application)で `Set xxx = Nothing` を明示する。
Dim doc As Object
Set doc = acadApp.ActiveDocument
‘ 業務処理…
‘ 解放順序
Set doc = Nothing
Set acadApp = Nothing
2. `On Error Resume Next` との付き合い方
COMエラーをハンドリングするために `On Error Resume Next` を多用するが、これによりエラーオブジェクトがクリアされず、意図しない変数保持やメモリ解放漏れが発生する。必ずエラー処理のスコープを最小限にし、`Err.Clear` を挟むこと。
3. レジストリ整合性の担保(上級者向け)
万が一、特定のProgID(例: `AutoCAD.Application.24.2`)のタイプライブラリがレジストリ上で破損している場合、`CreateObject` はエラー 429(コンポーネントはオブジェクトを作成できません)を返す。
この場合、VBAからレジストリ(`HKEY_CLASSES_ROOT`)を動的に参照してCLSIDを解決するか、インストーラー側でCOMコンポーネントの再登録(`acad.exe /regserver` のサイレント実行)を組み込むアーキテクチャ設計が求められる。
—
総括
複数バージョンが混在する企業インフラにおいて、AutoCAD VBAを「安定稼働させるシステム」に昇華させるか、「おまじない頼みの不安定なマクロ」で終わらせるかは、エンジニアのCOMモデルに対する解像度にかかっている。
ProgIDのハードコーディングによるバージョン固定化、`GetObject` と `CreateObject` の適切なフォールバック、そして厳密なメモリライフサイクル管理。これらを網羅したコードこそが、現場の信頼に耐えうる唯一の解である。
