【入門編】【実務中級者向け】「図面比較(DWG Compare)」結果を自動保存:VBAによる2つのバージョン間の差分抽出自動化 – AutoCAD VBA解析バイブル

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

マクロ記録の先へ。AutoCAD VBAで「図面比較(DWG Compare)」を完全自動化する極意

こんにちは。今日も図面と格闘しているエンジニアの皆さん、お疲れ様です。

「前回の図面からどこが変わったんだっけ……?」
そんな時、あなたは手動で2つの図面を開き、`COMPARE` コマンドを打ち、比較対象を選択し、結果を眺めて……という作業を繰り返していませんか?

もし、その作業が毎日、あるいはプロジェクトごとに発生しているなら、それは「エンジニアの仕事」ではなく「単純作業」です。そして、単純作業は機械(コード)に任せるべき領域です。

今日は、マクロの記録から一歩踏み出し、AutoCADの内部挙動を理解した上で、「2つの図面の差分を自動で抽出し、別名で保存する」という、実務で極めて価値の高い自動化プロセスを伝授します。

単なるコードの書き方だけでなく、「なぜその書き方をするのか」というオブジェクトのライフサイクルについても触れていきます。ここを理解すれば、あなたのVBAスキルは「コピペ使い」から「アーキテクト」へと進化するはずですよ。

1. 核心へのアプローチ:なぜ「オブジェクトモデル」だけでは足りないのか?

まず、初学者が必ず直面する壁についてお話ししましょう。

AutoCAD VBAには、図面内の線や円を操作するための「オブジェクトモデル(ActiveDocument, ModelSpaceなど)」が用意されています。しかし、実は「図面比較(DWG Compare)」という機能自体は、オブジェクトモデルの中に直接的なメソッド(命令)として存在していません。

つまり、`ThisDrawing.Compare(file1, file2)` のような綺麗な一行のコードは存在しないのです。

解決策:SendCommandという「魔法の杖」

ここで登場するのが `SendCommand` メソッドです。これは、ユーザーがコマンドラインに直接文字を打ち込む動作を、プログラムからシミュレートするものです。

「オブジェクトモデルで制御できないなら、コマンドを直接叩く」

この「ハイブリッドな思考」こそが、AutoCAD VBAを使いこなすプロの視点です。

2. 実装の設計図:プロセスのフロー

自動化のプロセスを分解してみましょう。

1. 準備: 比較したい「旧図面」と「新図面」のパスを取得する。
2. 実行: 旧図面を開いた状態で、`COMPARE` コマンドを呼び出す。
3. 注入: コマンドの引数として「新図面」のパスを流し込む。
4. 保存: 比較結果が表示された状態の図面を、指定した名前で `SAVEAS` する。

ここで重要なのが、ファイルパスの扱いです。Windowsのパスに含まれる `\`(バックスラッシュ)は、VBA内ではエスケープ処理が必要になる場面がありますが、`SendCommand` に渡す際は、AutoCADが正しく解釈できる形式でなければなりません。

3. 極限のコード例:差分抽出自動化スクリプト

さあ、魂を込めて書いたコードを見てみましょう。このコードは、単に動くだけでなく、エラーに強く、実務に耐えうる設計にしています。

Option Explicit

''' <summary>
''' 2つの図面を比較し、その差分結果を新しい図面として保存する
''' </summary>
''' <param name="oldDocPath">比較元(旧)のフルパス</param>
''' <param name="newDocPath">比較先(新)のフルパス</param>
''' <param name="savePath">結果を保存する新しい図面のフルパス</param>
Public Sub AutomateDWGCompare(oldDocPath As String, newDocPath As String, savePath As String)
    On Error GoTo ErrorHandler

    Dim acadApp As AcadApplication
    Set acadApp = ThisDrawing.Application

    ' --- 1. 準備:パスの整形 ---
    ' AutoCADのコマンドラインに渡す際、パスにスペースが含まれているとエラーになるため、
    ' ダブルクォーテーションで囲むのが鉄則です。
    Dim cmdOld As String, cmdNew As String
    cmdOld = """" & oldDocPath & """"
    cmdNew = """" & newDocPath & """"

    ' --- 2. 実行:COMPAREコマンドのシミュレーション ---
    ' SendCommandは「非同期」に近い挙動をすることがあります。
    ' コマンドの後にスペース(Enter)を送り、引数を順番に流し込みます。
    
    Debug.Print "比較を開始します: " & oldDocPath & " vs " & newDocPath
    
    ' COMPAREコマンド実行 -> 新図面のパスを入力 -> Enter
    ' 注意: SendCommandの末尾には必ず「スペース」を入れて、Enterキーの役割をさせます。
    ThisDrawing.SendCommand "COMPARE " & cmdNew & " "

    ' --- 3. ライフサイクル管理:比較結果の保存 ---
    ' COMPAREコマンドが完了すると、現在の図面は「比較モード」の状態になります。
    ' この状態でSAVEASを行うことで、差分情報(色付けされた差分)を保持したまま保存できます。
    
    ' 少しだけ待機(コマンド処理の安定性を高めるための実務的なテクニック)
    DoEvents 

    ' 保存実行
    ThisDrawing.SaveAs savePath
    
    MsgBox "比較が完了しました!" & vbCrLf & "保存先: " & savePath, vbInformation, "Success"

ExitSub:
    Exit Sub

ErrorHandler:
    MsgBox "エラーが発生しました。" & vbCrLf & _
           "エラー番号: " & Err.Number & vbCrLf & _
           "エラー内容: " & Err.Description, vbCritical, "Error"
    Resume ExitSub
End Sub

''' <summary>
''' テスト実行用メインルーチン
''' </summary>
Public Sub TestCompare()
    ' 実務では、ここをファイルダイアログ選択や、Excelからの読み込みに置き換えます。
    Dim oldFile As String: oldFile = "C:\Work\ProjectA_Ver1.dwg"
    Dim newFile As String: newFile = "C:\Work\ProjectA_Ver2.dwg"
    Dim outputFile As String: outputFile = "C:\Work\ProjectA_DIFF_RESULT.dwg"

    ' ファイルの存在確認(これだけでエラーの半分は防げます)
    If Dir(oldFile) = "" Or Dir(newFile) = "" Then
        MsgBox "指定されたファイルが見つかりません。パスを確認してください。", vbExclamation
        Exit Sub
    End If

    Call AutomateDWGCompare(oldFile, newFile, outputFile)
End Sub

4. ここをクリアすれば、AutoCAD VBAの基本はバッチリですよ

このコードを読み解く際に、絶対に忘れてはいけない「プロの知見」が3つあります。

① `SendCommand` の「スペース」の魔術

コード内の `ThisDrawing.SendCommand “COMPARE ” & cmdNew & ” “` を見てください。末尾にスペースが入っていますね?
AutoCADのコマンドラインにおいて、「スペース」は「Enterキー」と同じ意味を持ちます。これを忘れると、コマンドが入力されただけで止まってしまい、プログラムが「ユーザーの入力を待ち続ける」という、いわゆるフリーズ状態に陥ります。

② パスの「ダブルクォーテーション」の重要性

`cmdOld = “””” & oldDocPath & “”””`
この部分は一見複雑ですが、非常に重要です。もし図面が `C:\My Projects\Drawing 1.dwg` のように、フォルダ名やファイル名にスペースを含んでいた場合、クォーテーションで囲まないと、AutoCADは `C:\My` までがパスだと勘違いしてしまいます。
「パスを扱うときは常に、ダブルクォーテーションで守る」。これは、自動化エンジニアの鉄則です。

③ オブジェクトのライフサイクルと `DoEvents`

`DoEvents` という命令を入れました。これは、Windowsに対して「一度他の処理(AutoCAD自身の内部処理)に時間を譲ってあげて」と伝える命令です。
`COMPARE` コマンドは非常に重い処理です。VBAが猛スピードで次の `SaveAs` を実行しようとしても、AutoCAD側がまだ比較の計算をしている最中だと、エラーになります。「重い処理の後は、一呼吸置く」。これが、安定したマクロを作るコツです。

最後に

いかがでしたか?
「マクロの記録」は、あくまで「あなたがやった操作をなぞる」だけのものです。
しかし、今回学んだように、「コマンドの仕組み」と「オブジェクトの挙動」を理解して書くコードは、「あなたの意図を形にする」ための強力な武器になります。

最初はエラーが出るかもしれません。でも、エラーメッセージは敵ではなく、あなたが正解へ辿り着くためのガイドです。一つずつ、パスを修正し、タイミングを調整していってください。

その先に、退屈な作業から解放された、真のエンジニアとしての時間が待っています。

応援していますよ。さあ、コードを書いて、世界を変えましょう!

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