【入門編】【実務中級者向け】保存時の「DWG図面比較」自動実行:旧バージョンとの差分を検出し、変更箇所を明示した図面を別保存する – AutoCAD VBA解析バイブル

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

【実務中級者への登竜門】図面の「変化」を逃さない:DWG比較を自動化するスマート・セーブ・ワークフロー

こんにちは。AutoCADの自動化の世界へようこそ。

マクロの記録機能を使って「あ、これ便利だな」と感じる段階から、一歩踏み出そうとしているあなた。その姿勢こそが、エンジニアとして最も重要な「課題解決への渇望」です。

今日お話しするのは、単なる「保存の自動化」ではありません。「図面の履歴(状態)を管理し、変更点を可視化する」という、実務における極めて高度なワークフローの構築についてです。

「昨日と今日で、図面のどこが変わったんだっけ?」
「修正したつもりが、実は別の場所をいじっていた……」

そんな、ベテラン設計者でも陥るヒューマンエラーを、プログラムの力で根絶しましょう。ここをクリアすれば、あなたのAutoCAD VBAのスキルは「ツールを使う人」から「仕組みを作る人」へと進化します。

1. コンセプト:図面を「点」ではなく「線」で捉える

多くの初学者は、プログラムを「今開いている図面に対して何かをする(点)」という考え方で書きます。しかし、プロフェッショナルな自動化は、「現在の図面」と「過去の図面」の差異(線)に注目します。

今回実装するのは、以下のような「スマート・セーブ(賢い保存)」の仕組みです。

1. 現在の図面を保存する前に、
2. 前回保存したバックアップ図面との差分を、AutoCADの「DWG比較」機能を使って抽出する。
3. 差分が出た場合、その「差分図面」を別名で保存し、変更箇所を視覚的に残す。
4. 最後に、現在の図面を上書き保存し、バックアップを最新状態に更新する。

これを実現するために、VBAの「オブジェクトモデル」だけでなく、コマンドラインを直接操る「`SendCommand`」の技術を駆使します。

2. 技術的な核心:`SendCommand` と ファイルシステムの制御

このプログラムを実現するためには、2つの大きな壁があります。

壁①:AutoCADの強力な機能を「命令」で呼び出す

AutoCADには、VBAのオブジェクト(`ThisDrawing.Layers`など)からは直接触れない、強力な「コマンド」が数多く存在します。今回使う`DWGCOMPARE`(図面比較)もその一つです。
これをVBAから叩くには、`ThisDrawing.SendCommand` メソッドを使用します。これは、まるでユーザーがキーボードでコマンドを入力する動作を、プログラムからエミュレートする技術です。

壁②:ファイル管理の「確実性」

「ファイルが既にあるか?」「書き込み権限はあるか?」を判定せずに処理を進めると、プログラムは無慈悲にエラーで止まります。ここで、Windowsのファイル操作を司る `FileSystemObject` (FSO) の出番となります。

3. 実装コード:SmartSave_With_Compare

では、魂を込めて書いたコードを見ていきましょう。このコードは、そのままプロジェクトに組み込んで試せる構成にしています。

' =====================================================================
' プログラム名:SmartSave_With_Compare
' 概要:保存時にバックアップとの比較を行い、差分図面を自動生成する
' 作成者:伝説のチーフアーキテクト
' =====================================================================

Option Explicit

Sub SmartSaveWithCompare()
    Dim acadApp As AcadApplication
    Set acadApp = ThisDrawing.Application
    
    Dim currentDoc As AcadDocument
    Set currentDoc = ThisDrawing
    
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    Dim currentPath As String
    Dim backupPath As String
    Dim diffPath As String
    Dim baseName As String
    Dim extension As String
    
    ' 1. 現在の図面のパス情報を取得
    currentPath = currentDoc.FullName
    
    ' 未保存の図面(Drawing1など)の場合は処理を中断
    If currentPath = "" Then
        MsgBox "この図面はまだ一度も保存されていません。まずは通常の保存を行ってください。", vbExclamation
        Exit Sub
    End If
    
    ' ファイルパスの分解(拡張子を除いた名前を取得)
    baseName = fso.GetBaseName(currentPath)
    extension = fso.GetExtensionName(currentPath)
    
    ' バックアップと差分図面のパスを定義
    ' 例: drawing1.dwg -> drawing1_bak.dwg / drawing1_diff.dwg
    backupPath = fso.GetParentFolderName(currentPath) & "\" & baseName & "_bak." & extension
    diffPath = fso.GetParentFolderName(currentPath) & "\" & baseName & "_diff." & extension
    
    On Error GoTo ErrorHandler
    
    ' 2. バックアップの存在確認
    If fso.FileExists(backupPath) Then
        Debug.Print "比較を開始します: " & backupPath
        
        ' 3. DWG比較コマンドの実行
        ' SendCommandは、コマンドの末尾に「スペース」または「改行(vbCr)」が必要
        ' DWGCOMPARE [比較対象ファイル] の形式で実行
        ' ※注意: 比較結果の図面は一時的にアクティブになる挙動を想定
        currentDoc.SendCommand "DWGCOMPARE " & Chr(34) & backupPath & Chr(34) & vbCr
        
        ' コマンド実行の待ち時間を考慮(環境により調整が必要な場合があります)
        DoEvents
        
        ' 4. 差分図面の保存
        ' DWGCOMPAREの結果、新しい図面が開いている状態になるため、その図面をdiffPathで保存
        ' ここでは「現在アクティブな図面」に対して保存を試みる
        acadApp.ActiveDocument.SaveAs diffPath
        
        MsgBox "変更を検出し、差分図面を作成しました:" & vbCrLf & diffPath, vbInformation
    Else
        ' バックアップがない場合は、初回保存として扱う
        Debug.Print "バックアップが見つかりません。初回保存として処理します。"
    End If
    
    ' 5. 本体の保存とバックアップの更新
    currentDoc.Save
    
    ' 現在の図面をバックアップとしてコピー(上書き)
    fso.CopyFile currentPath, backupPath, True
    
    MsgBox "保存とバックアップの更新が完了しました。", vbInformation
    Exit Sub

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

4. プロの視点:陥りやすい「罠」と回避策

このコードを実際に動かす際、あなたは必ずいくつかの壁にぶつかるでしょう。それは失敗ではなく、「仕様を理解するためのステップ」です。

① `SendCommand` の「非同期性」という罠

`SendCommand` は、VBAのコードが次の行に進むのと、AutoCADがコマンドを処理し終えるタイミングが一致しないことがあります。
上記のコードでは `DoEvents` を入れていますが、もし比較ダイアログが立ち上がって止まってしまう場合は、コマンドライン引数をより詳細に指定するか、ユーザーに操作を促す設計にする必要があります。

② パスに含まれる「空白」の罠

ファイル名に `Project A.dwg` のようにスペースが含まれていると、AutoCADは `DWGCOMPARE Project` までがファイル名だと誤認してエラーを吐きます。
これを防ぐために、コード内で `Chr(34)`(ダブルクォーテーション)を使って、パスを `” “` で囲う処理を行っています。これは実務における鉄則です。

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

`DWGCOMPARE` を実行すると、AutoCADの「アクティブな図面(`ActiveDocument`)」が、比較結果の図面に切り替わります。
そのため、最後に `currentDoc.Save` を呼ぶとき、`currentDoc` という変数が「元の図面」を正しく指し示しているかどうかが重要になります。変数にオブジェクトをセットしておくことで、図面が切り替わっても迷子にならないように設計しています。

5. まとめ:次に目指すべき地平

今回のワークフローを導入することで、あなたは単に作業を速くしたのではなく、「図面の品質保証(QA)プロセス」を自動化したのです。

次にあなたが挑戦すべきは、このログをExcelに書き出し、「いつ、誰が、どの図面を、どれくらい変更したか」という変更管理データベースを構築することかもしれません。

AutoCAD VBAは、単なる自動化ツールではありません。あなたの思考を、図面という物理的な成果物に、正確かつ高速に反映させるための「思考の拡張装置」なのです。

一歩ずつ、確実に。コードの向こう側にある「効率化された未来」を楽しんでください。応援していますよ。

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