【入門編】【上級プロフェッショナル向け】AutoCADの「マルチインスタンス」を跨いだドキュメント転送と同期保存のアーキテクチャ – AutoCAD VBA解析バイブル

スポンサーリンク
スポンサーリンク

【極限の知見】AutoCADの「壁」を越える:マルチインスタンス制御と安全なデータ連携の設計思想

こんにちは。AutoCAD VBAの世界へようこそ。
マクロの記録ボタンを押し、「動いた!ラッキー!」と喜んでいたフェーズはもう卒業ですね。ここからは、「プログラムがプログラムを、プロセスがプロセスを操る」という、一段上のアーキテクチャの領域へ足を踏み入れていただきます。

今日扱うテーマは、非常にエキサイティングで、かつ、多くのエンジニアが挫折する難所です。
それは、「複数のAutoCADプロセス(マルチインスタンス)を跨いだ、図面データの受け渡しと同期保存」。

「今動いているこのAutoCAD(インスタンスA)から、別のウィンドウで開いているAutoCAD(インスタンスB)の図面を操作したい」
あるいは「複数の図面を別々のプロセスで開き、一斉に整合性を保ちながら保存したい」

そんな願いを叶えるための、プロフェッショナルな設計思想を伝授しましょう。

1. 「ThisDrawing」という名の、心地よい檻

まず、あなたがこれまで慣れ親しんできた `ThisDrawing` というオブジェクトについて、その「正体」を再定義しましょう。

VBAを書いているとき、私たちは無意識に `ThisDrawing.ActiveDocument` と書いています。これは非常に便利ですが、実は「自分自身が属しているプロセス(檻)の中」でしか通用しない言葉なのです。

プロセスの境界線(Process Boundary)

AutoCADを2つ起動しているとき、Windowsのタスクマネージャーを見ると、`acad.exe` が2つ並んでいるはずです。これらは、たとえ同じAutoCADであっても、「全く別の宇宙(メモリ空間)」に住んでいます。

  • インスタンスAの宇宙: 独自のメモリ、独自のオブジェクト、独自の `ThisDrawing`
  • インスタンスBの宇宙: 独自のメモリ、独自のオブジェクト、独自の `ThisDrawing`

インスタンスAのVBAから、インスタンスBの `ThisDrawing` を直接触ろうとすると、VBAは「そんなオブジェクトは知らないよ!」とエラーを吐いて止まってしまいます。これが、初心者が最初にぶち当たる「プロセスの壁」です。

2. 壁を越える架け橋:COM(Component Object Model)

では、どうやってこの壁を越えるのか? そこで登場するのが COM (Component Object Model) という技術です。

Windowsには、実行中のアプリケーションをリストアップし、外部からそれらを操作するための「名簿」のような仕組み(ROT: Running Object Table)があります。これを利用して、別のプロセスにいるAutoCADを「捕まえる」ことができるのです。

インスタンスを捕まえるための「魔法の言葉」

通常、新しいAutoCADを立ち上げるには `CreateObject` を使いますが、「既に開いている別のAutoCAD」を捕まえるには `GetObject` を使います。

' --- 概念図 ---
' [ あなたのVBA ] --- (GetObject) ---> [ 別のAutoCADプロセス ]

3. 実践:マルチインスタンス・コントロール・アーキテクチャ

それでは、具体的なコードを見ていきましょう。単に「動く」コードではなく、「現場で壊れない」ための堅牢な設計を盛り込んでいます。

実装のポイント:オブジェクトではなく「データ」を渡せ

ここが最も重要な知見です。
インスタンスAからインスタンスBへ、「図形のオブジェクトそのもの」を渡そうとしてはいけません。 オブジェクトはメモリ上の住所(ポインタ)で管理されていますが、その住所はインスタンスAの中でしか意味をなさないからです。

「図面のパス」や「座標値」「属性値」といった「純粋なデータ」として受け渡しを行うこと。 これが、プロフェッショナルな設計の鉄則です。

Option Explicit

''' <summary>
''' 実行中の別のAutoCADインスタンスを取得し、指定した図面を保存する
''' </summary>
Sub SyncSaveInOtherInstance()
    Dim targetAcadApp As Object ' AutoCAD.Application
    Dim targetDoc As Object     ' AutoCAD.Document
    Dim targetFilePath As String
    
    ' 1. 操作対象となる図面のパスを指定(本来は引数などで渡す)
    targetFilePath = "C:\Work\Project_A.dwg"
    
    On Error Resume Next
    
    ' 2. 【重要】実行中のAutoCADインスタンスを捕まえる
    ' GetObject(, "AutoCAD.Application") は、現在起動中のAutoCADを探します
    Set targetAcadApp = GetObject(, "AutoCAD.Application")
    
    If Err.Number <> 0 Then
        MsgBox "実行中のAutoCADが見つかりません。AutoCADを起動してください。", vbCritical
        Exit Sub
    End If
    On Error GoTo ErrorHandler

    ' 3. ターゲットのアプリ内で、特定の図面を探す
    ' 注意:インスタンスAからインスタンスBの「どの図面」を触るかは、
    ' 図面名やフルパスで判定する必要があります。
    Dim doc As Object
    Dim found As Boolean
    found = False
    
    For Each doc In targetAcadApp.Documents
        ' ファイルパスを比較して、目的の図面を特定する
        If LCase(doc.FullName) = LCase(targetFilePath) Then
            Set targetDoc = doc
            found = True
            Exit For
        End If
    Next doc

    If Not found Then
        MsgBox "指定された図面がターゲットのAutoCAD内で開かれていません。", vbExclamation
        Exit Sub
    End If

    ' 4. 図面の同期保存を実行
    Debug.Print "保存を開始します: " & targetDoc.Name
    targetDoc.Save
    Debug.Print "保存が完了しました。"

    MsgBox "別インスタンスの図面を安全に保存しました。", vbInformation

CleanUp:
    ' オブジェクトの解放(メモリリーク防止)
    Set targetDoc = Nothing
    Set targetAcadApp = Nothing
    Exit Sub

ErrorHandler:
    MsgBox "エラーが発生しました: " & Err.Description, vbCritical
    Resume CleanUp
End Sub

4. 陥りやすい「地雷」を回避する

この技術を扱う際、ベテランでも時折踏んでしまう地雷がいくつかあります。

① ゾンビプロセスの恐怖

`GetObject` で接続した後に、プログラムが異常終了したり、正しく `Set object = Nothing` を行わなかったりすると、AutoCADのプロセスがメモリ上に残り続けることがあります。これを「ゾンビプロセス」と呼びます。
タスクマネージャーに `acad.exe` が大量に残っている場合は、これらが原因です。必ず `On Error` でエラーハンドリングを行い、確実にオブジェクトを解放する癖をつけましょう。

② バージョン不一致の罠

AutoCAD 2023 と 2024 が両方インストールされている環境では、`GetObject(, “AutoCAD.Application”)` がどちらを指すかは、Windowsのレジストリ登録順に依存します。
「特定のバージョンを操作したい」という場合は、`AutoCAD.Application.24`(バージョン番号を指定)のように、より具体的なProgIDを使用する検討が必要です。

③ パフォーマンスの重み

複数のインスタンスをループで回して大量の処理を行うのは、非常にコスト(負荷)が高い操作です。

  • 悪い例: 1つずつインスタンスを捕まえては、1つの図面を操作して、また閉じる。
  • 良い例: インスタンスを一度捕まえたら、その中の `Documents` コレクションを全て走査し、一括で処理を行う。

最後に:ここをクリアすれば、あなたはもう「マクロ使い」ではない

「複数のAutoCADを操る」という技術は、単なる自動化の枠を超え、「システム設計」の領域です。

オブジェクトの寿命を意識し、プロセスの壁を理解し、データとして情報をやり取りする。この一連の流れをマスターすれば、あなたは単に「作業を楽にする人」から、「業務プロセスそのものを設計するエンジニア」へと進化できます。

最初はエラーに泣かされるかもしれません。でも、そのエラーメッセージの一つ一つが、プロセスの境界線を教えてくれる貴重なガイドになります。

一歩ずつ、着実に進んでいきましょう。応援していますよ!

タイトルとURLをコピーしました