【実務・中級編】【実務中級】図面内の全寸法オブジェクト(Dimension)のスタイルを、指定したスタイルに一括で変更する – AutoCAD VBA解析バイブル

スポンサーリンク

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` という条件分岐を入れることで、更新不要なオブジェクトに対する計算コストを削減している。これは大規模図面におけるパフォーマンス最適化の定石だ。

最後に:エンジニアへの提言

自動化ツールとは、単に手作業を置き換えるものではない。「手作業では見落としていたエラーを、システムが先回りして排除する仕組み」のことだ。

今回紹介したコードは、あくまでテンプレートである。現場によっては、レイヤーごとの制御や、特定のブロック内の寸法のみ除外する要件も発生するだろう。しかし、「前提条件の確認(スタイル確認)」「型安全な抽出(フィルタ)」「資源の管理(選択セット破棄)」という三原則さえ守れば、どのような拡張にも耐えうる堅牢なアーキテクチャが構築できる。

あなたのコードは、ただ動くだけのものではない。保守する者の負荷を減らし、図面の品質を担保する「エンジニアリング」であるべきだ。

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