AutoCAD VBAの深淵:全寸法スタイル一括置換に見る「堅牢な自動化」の作法
AutoCADの自動化において、最も初歩的でありながら、最も現場の生産性を左右するのが「オブジェクトの一括プロパティ操作」だ。多くのエンジニアが「ループを回して代入するだけ」と考えがちだが、そこに落とし穴がある。
今回は、図面内の全寸法スタイルを統一する処理を題材に、「壊れないコード」をどう設計するかという視点で、AutoCAD APIの極意を伝授する。
—
1. なぜ「単純なループ」で事故が起きるのか?
初心者は、`ModelSpace`を`For Each`で回し、見つけた`AcadDimension`の`StyleName`プロパティを書き換えるコードを書きがちだ。しかし、これには以下のリスクが潜んでいる。
- 型不一致の罠: モデル空間には寸法だけでなく、ブロック参照や線分も混在している。安易なキャストはランタイムエラーを招く。
- レイヤーとスタイルの依存性: 指定したスタイルが図面内に存在しない場合、AutoCADは容赦なくエラーを吐く。
- 更新の非同期性: 一括置換後、図面データと表示結果の不整合が起きるケースがある。最低限の再描画命令を設計に組み込む必要がある。
我々プロフェッショナルは、「操作対象の選別」と「エラーハンドリング」の二重防壁を構築しなければならない。
—
2. プロダクション品質のコード実装
以下は、実務でそのまま運用可能な堅牢なコードである。単に動くだけでなく、「スタイルが存在するか」という前提条件の確認と、型安全な反復処理を徹底している。
Option Explicit
‘ ———————————————————
‘ 指定した寸法スタイルへ一括変換するプロシージャ
‘ ———————————————————
Public Sub BatchUpdateDimensionStyle(ByVal targetStyleName As String)
Dim doc As AcadDocument
Dim ss As AcadSelectionSet
Dim ent As AcadEntity
Dim dimObj As AcadDimension
Dim styleObj As AcadDimStyle
Set doc = ThisDrawing
‘ 1. スタイルの存在確認(これが抜けると運用で必ず詰む)
On Error Resume Next
Set styleObj = doc.DimStyles.Item(targetStyleName)
If Err.Number <> 0 Then
MsgBox “エラー: スタイル ‘” & targetStyleName & “‘ が存在しません。”, vbCritical
Exit Sub
End If
On Error GoTo 0
‘ 2. 選択セットの準備(高速化とメモリ保護)
Set ss = CreateSelectionSet(“DimSelection”)
‘ 3. フィルタ定義:寸法オブジェクトのみを抽出
Dim filterType(0) As Integer
Dim filterData(0) As Variant
filterType(0) = 0: filterData(0) = “DIMENSION”
ss.Select acSelectionSetAll, , , filterType, filterData
‘ 4. 一括置換処理
Dim count As Long
count = 0
For Each ent In ss
Set dimObj = ent
‘ 現在のスタイルと異なる場合のみ更新(無駄な更新処理を省く)
If dimObj.StyleName <> targetStyleName Then
dimObj.StyleName = targetStyleName
dimObj.Update
count = count + 1
End If
Next
‘ 5. 後処理
ss.Delete
doc.Regen acActiveViewport
MsgBox count & ” 個の寸法スタイルを ‘” & targetStyleName & “‘ に変更しました。”, vbInformation
End Sub
‘ 選択セット管理用ヘルパー関数(再利用性が高く、エラーを回避する)
Private Function CreateSelectionSet(setName As String) As AcadSelectionSet
On Error Resume Next
ThisDrawing.SelectionSets.Item(setName).Delete
Set CreateSelectionSet = ThisDrawing.SelectionSets.Add(setName)
On Error GoTo 0
End Function
—
3. 現場を統べるための設計指針
このコードには、単なる機能実装以上の「意図」がある。
1. 選択セット(SelectionSets)の明示的破棄:
AutoCADのVBAでは、一度作成した選択セットはメモリに残る。`CreateSelectionSet`内で既存の同名セットを削除(Delete)してから作成するロジックは、自動化ツールを長時間動かした際のメモリリークや「同名のオブジェクトが既に存在します」エラーを防ぐ生命線だ。
2. フィルタの活用:
`For Each`ですべてのエンティティを回すのは愚策だ。`ss.Select`で事前に`DIMENSION`だけをフィルタリングしておくことで、処理速度は劇的に向上する。数万オブジェクトある図面では、この差が作業待ち時間に直結する。
3. 無駄な更新(Update)の抑制:
`If dimObj.StyleName <> targetStyleName` という条件分岐を入れることで、更新不要なオブジェクトに対する計算コストを削減している。これは大規模図面におけるパフォーマンス最適化の定石だ。
最後に:エンジニアへの提言
自動化ツールとは、単に手作業を置き換えるものではない。「手作業では見落としていたエラーを、システムが先回りして排除する仕組み」のことだ。
今回紹介したコードは、あくまでテンプレートである。現場によっては、レイヤーごとの制御や、特定のブロック内の寸法のみ除外する要件も発生するだろう。しかし、「前提条件の確認(スタイル確認)」「型安全な抽出(フィルタ)」「資源の管理(選択セット破棄)」という三原則さえ守れば、どのような拡張にも耐えうる堅牢なアーキテクチャが構築できる。
あなたのコードは、ただ動くだけのものではない。保守する者の負荷を減らし、図面の品質を担保する「エンジニアリング」であるべきだ。
