マクロ記録の先へ。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側がまだ比較の計算をしている最中だと、エラーになります。「重い処理の後は、一呼吸置く」。これが、安定したマクロを作るコツです。
最後に
いかがでしたか?
「マクロの記録」は、あくまで「あなたがやった操作をなぞる」だけのものです。
しかし、今回学んだように、「コマンドの仕組み」と「オブジェクトの挙動」を理解して書くコードは、「あなたの意図を形にする」ための強力な武器になります。
最初はエラーが出るかもしれません。でも、エラーメッセージは敵ではなく、あなたが正解へ辿り着くためのガイドです。一つずつ、パスを修正し、タイミングを調整していってください。
その先に、退屈な作業から解放された、真のエンジニアとしての時間が待っています。
応援していますよ。さあ、コードを書いて、世界を変えましょう!
