【実務・中級編】【初心者向け】AcadDocument.Blocksコレクションを走査し、図面内で使用されている「ブロック名」を重複なくリストアップする基礎コード – AutoCAD VBA解析バイブル

スポンサーリンク

AutoCAD VBAを掌握せよ:Blocksコレクションを「制する」最適化の極意

AutoCADの自動化において、`Blocks`コレクションの走査は避けて通れない登竜門だ。しかし、ただ「ループを回せばいい」と考えているうちは、まだエンジニアとは呼べない。

図面の複雑度が増せば増すほど、メモリ管理やオブジェクトの参照範囲、そして「ゴミ(無効なブロック)」の扱いでツールは崩壊する。今日は、単にブロック名をリストアップするだけのコードではなく、実務の現場で「止まらない、汚さない、速い」コードを書くための作法を伝授する。

1. なぜ「ただのループ」ではいけないのか?

初心者が陥りやすいのが、`Blocks`コレクションの性質を理解しないまま、全てのオブジェクトにアクセスしようとすることだ。

  • ModelSpace/PaperSpaceもBlocksの一部である: AutoCADの内部構造では、モデル空間やレイアウト空間も「ブロック定義」の一種として扱われる。これらを区別せずに処理すると、無意味なデータを抽出する羽目になる。
  • 「外部参照(Xref)」と「レイアウト」の罠: 外部参照やレイアウト空間の定義までリストアップしてしまい、後工程でエラーを吐くツールは現場で最も嫌われる。

これらを排除し、純粋な「ブロック定義」だけを抽出するフィルター設計が、堅牢なツールの第一歩だ。

2. 【実戦編】プロダクション品質のブロック抽出コード

このコードは、単なる列挙ではなく、「外部参照」や「レイアウト由来のブロック」を明確に除外する設計になっている。Excelへの書き出しを想定し、保守性を高めた構成だ。

Option Explicit

‘ ———————————————————
‘ @brief 図面内のブロック定義を重複なく取得し、イミディエイトウィンドウに出力する
‘ @description 実務での利用を想定し、Xrefやレイアウト由来のブロックを除外する堅牢なロジック
‘ ———————————————————
Public Sub GetBlockList_ProductionReady()
Dim acadDoc As AcadDocument
Dim blk As AcadBlock
Dim blkName As String

Set acadDoc = ThisDrawing

Debug.Print “— ブロックリスト抽出開始 —”

‘ Blocksコレクションを走査
For Each blk In acadDoc.Blocks

‘ 1. 「」で始まる匿名ブロック(寸法やハッチングの内部データ)は除外
‘ 2. IsLayout = True (レイアウト) を除外
‘ 3. IsXRef = True (外部参照) を除外
If Left(blk.Name, 1) <> “” And _
blk.IsLayout = False And _
blk.IsXRef = False Then

‘ ここでリストアップ
Debug.Print blk.Name

‘ ※実務ではここでCollectionオブジェクトに格納するか、
‘ Worksheets(“Sheet1”).Cells(row, 1).Value = blk.Name 等でExcel連携する
End If

Next blk

Debug.Print “— 抽出完了 —”
End Sub

3. コードの解説:ここが「プロ」の視点

  • `Left(blk.Name, 1) <> “”`:

AutoCADは寸法線や複雑なハッチングを「匿名ブロック(アスタリスクで始まる名前)」として自動生成する。これらを抽出対象に含めると、リストがゴミだらけになり、後続の集計処理でバグを誘発する。このフィルターは必須だ。

  • `blk.IsLayout` と `blk.IsXRef`:

これらは非常に重要だ。`IsLayout`を無視すると、モデル空間自体がブロックとしてリストアップされる。`IsXRef`を無視すると、外部ファイルをブロックとして誤認し、図面管理の整合性が取れなくなる。

  • コレクションの利用:

もしこのリストをさらに加工(ソートや重複排除)したい場合は、`Scripting.Dictionary`オブジェクトを併用することを推奨する。配列で管理するよりも、検索・追加のコストが圧倒的に低いからだ。

4. さらなる高みへ:システム設計の注意点

ツールを配布する場合、以下の点に留意してほしい。

1. エラーハンドリング: `On Error Resume Next` を多用してはいけない。特に大規模図面では、特定のブロックが破損している可能性がある。その場合は `Err.Number` をログに出力し、処理を中断せずにスキップする設計が望ましい。
2. Excel連携のオーバーヘッド: 1つずつセルに書き込むのは非効率だ。一度配列(Variant型)に格納し、最後に `Range.Value` で一括転記する手法を必ず採用せよ。
3. データベースとの連携: ブロック名をキーにして属性値を抽出する場合、`AcadBlockReference` の `GetAttributes` メソッドを併用するわけだが、これにはCPUリソースを食う。抽出頻度が高い場合は、事前に必要な情報だけを抽出する「キャッシュ機構」をVBA内に構築するのも一つの手だ。

最後に

AutoCAD VBAは古くからある技術だが、その分、洗練されたコードとそうでないコードの差が顕著に出る。今回紹介した「フィルターを通す」という思考法は、他のオブジェクト(レイヤー管理や線種管理)にも応用できる、極めて汎用性の高い設計思想だ。

まずはこのコードを動かし、自分の環境でどう出力されるかを確認してほしい。そこから先は、君の想像力次第で、どんな業務自動化ツールも構築できるはずだ。

君のコードが、設計者の工数を劇的に減らす武器になることを期待している。

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