【実務・中級編】【実務中級】図面比較を自動化!2つの図面の差分を検出するVBAテクニック – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD VBAを掌握する:図面比較自動化の極意――「差分」を制する者は設計品質を制する

設計変更の嵐の中で、手作業の図面比較に命を削っていないだろうか?「A図面とB図面、どこが変わったのか?」という問いに対し、目視で追うのはエンジニアの仕事ではない。それはAutoCADという強力なエンジンに任せるべきタスクだ。

今回は、AutoCAD VBAを用いた「差分検出」のアーキテクチャを解説する。単にオブジェクトをなめるだけのスクリプトではない。大規模図面でも破綻せず、かつ実務で耐えうる「堅牢な比較ロジック」の神髄を伝授する。

1. なぜ「力技の比較」は失敗するのか

多くの初心者が陥る罠は、「すべてのオブジェクトを力技でループして比較する」という設計だ。

  • 非効率な設計の末路: オブジェクト数万個をメモリにロードし、総当たりで比較すれば、AutoCADは確実にハングアップする。
  • IDの罠: `Handle` はコピーやブロック化で変化する可能性がある。これを唯一の頼りにするのは脆弱だ。

プロフェッショナルがとるべき戦略

1. ハッシュベースの比較: オブジェクトの主要プロパティ(挿入点、半径、画層、色等)を文字列化し、ハッシュ値(またはそれに準ずるキー)を生成する。
2. 空間インデックスの活用: 全領域を走査するのではなく、バウンディングボックスの範囲で絞り込む。
3. 辞書オブジェクトの利用: VBAの `Scripting.Dictionary` を使い、O(1)の計算量で検索を行う。

2. 実装:差分検出エンジン(プロダクションコード)

以下のコードは、2つの図面を開いた状態で、「モデル空間内の円(Circle)」の差分を検出するプロトタイプだ。実務ではこれをポリラインやブロックに拡張してほしい。

‘ 参照設定: Microsoft Scripting Runtime を追加すること
Option Explicit

Public Sub CompareDrawings()
Dim docOld As AcadDocument, docNew As AcadDocument
Dim dictOld As New Scripting.Dictionary
Dim ent As AcadEntity
Dim key As String

‘ 図面が2つ開かれている前提
Set docOld = Application.Documents.Item(0)
Set docNew = Application.Documents.Item(1)

‘ 1. 旧図面の円を辞書に登録 (Key: 中心点と半径の文字列)
For Each ent In docOld.ModelSpace
If TypeOf ent Is AcadCircle Then
key = GetCircleKey(ent)
If Not dictOld.Exists(key) Then dictOld.Add key, True
End If
Next

‘ 2. 新図面を走査し、旧図面に存在しないものをハイライト
For Each ent In docNew.ModelSpace
If TypeOf ent Is AcadCircle Then
key = GetCircleKey(ent)
If Not dictOld.Exists(key) Then
‘ 差分発見!赤色に変更して目立たせる
ent.Color = acRed
ent.Update
End If
End If
Next

MsgBox “比較完了:変更・追加箇所を赤色でマークしました。”
End Sub

‘ ハッシュ用キー生成関数(浮動小数点の誤差を考慮し丸める)
Private Function GetCircleKey(cir As AcadCircle) As String
GetCircleKey = Format(cir.Center(0), “0.000”) & “|” & _
Format(cir.Center(1), “0.000”) & “|” & _
Format(cir.Radius, “0.000”)
End Function

3. 実務で「壊れない」ための3つの鉄則

① 浮動小数点の誤差を殺せ

`Double` 型の比較は `If a = b Then` では絶対に機能しない。`Format` 関数で文字列に落とし込むか、許容誤差(Epsilon)を用いた比較関数を自作すること。上記のコードでは `Format` を用いて簡易的な正規化を行っている。

② データベース/ログ出力の連携

比較結果を単に色を変えるだけで終わらせてはいけない。

  • ログ出力: 差分をCSVに書き出し、Excelで「設計変更履歴一覧」として自動生成する。
  • レイヤー管理: 差分オブジェクトを自動的に「DIFF_CHECK」という専用レイヤーに移動させると、設計者が後で一括管理しやすくなる。

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

`For Each` ループ内でオブジェクトを削除したり移動したりすると、イテレータが崩壊する可能性がある。

  • 削除・修正はスタックする: ループ内では「対象リスト(コレクション)」を作成するだけに留め、ループ終了後に一括処理する設計が、予期せぬクラッシュを防ぐ唯一の道だ。

結論:自動化は「思考」を省略することではない

AutoCAD VBAで比較ツールを作る目的は、単に「楽をする」ことではない。「人間が判断すべきクリティカルな変更点」を浮き彫りにし、設計者が本来集中すべき「設計品質」に時間を割かせることにある。

まずはこのコードをベースに、自社の標準画層やブロック属性に対応させてみてほしい。それが、君のエンジニアとしての価値を一段引き上げるはずだ。

コードは嘘をつかない。だが、設計思想が甘ければコードは裏切る。常に「もし数万オブジェクトあったらどうなるか?」という視点を忘れずに開発を続けてくれ。検討を祈る。

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