【入門編】【実務中級】図面内の全ブロック定義(Block Definition)を検索し、そのプロパティ(挿入尺度、回転角度など)を一覧化する – AutoCAD VBA解析バイブル

スポンサーリンク

こんにちは!CAD開発の現場で毎日のようにVBAと格闘している君なら、きっと「図面の中にどんなブロック定義が眠っているのか、一発でリスト化できたらなぁ…」と思ったことがあるはずだ。

「マクロの記録」ボタンを押すだけの世界から一歩抜け出し、AutoCADの心臓部であるオブジェクトモデルを直接手なづけられるようになると、図面自動化の世界が一気に広がる。

今回は、図面内の全ブロック定義(Block Definition)を華麗にハントし、そのプロパティをイミディエイトウィンドウに美しく一覧化する実務直結のコードを授けよう。

ここをクリアすれば、AutoCAD VBAの基礎とオブジェクト構造の概念はもうバッチリだ。一緒に本質をマスターしていこう!

1. そもそも「ブロック定義(Block)」と「ブロック参照(Insert)」は何が違うのか?

まず、AutoCAD VBAで最も多くの初心者がハマる「最初の罠」を突破しよう。ここを勘違いしていると、コードを書いたときに「あれ、目当てのデータが取れない…」と発狂することになる。

AutoCADのブロックには、以下の2つの異なる概念が存在する。

  • ブロック定義(`AcadBlock` / 辞書に登録された“型紙”)
  • `ThisDrawing.Blocks` コレクションに格納されている。
  • 「こういう形状の部品ですよ」というマスターデータ(型紙)そのもの。
  • ブロック参照(`AcadBlockReference` / 図面に配置された“実体”)
  • モデル空間やペーパー空間に、実際にポチポチと配置された個々のパーツ(実体)

今回はテーマの通り、図面という名の「部品倉庫」の棚卸しをするために、「ブロック定義(AcadBlock)」のほうを根こそぎ検索して、そのプロパティを暴いていく。

2. 【実務仕様】全ブロック定義を一覧化するVBAコード

百聞は一見に如かず。まずは開発の現場でそのままコピペして使える実用コードを提示しよう。
VBAエディタ(Alt + F11)を開き、標準モジュールにこのコードを貼り付けて実行してみてほしい。

Option Explicit

Public Sub ListUpBlockDefinitions()
‘ =================================================================
‘ 目的: 図面内に存在するすべてのブロック定義を走査し、
‘ そのプロパティ(名前、エンティティ数、基点など)を一覧化する
‘ =================================================================

Dim acadApp As AcadApplication
Dim acadDoc As AcadDocument
Dim blkDefs As AcadBlocks
Dim blkDef As AcadBlock

Dim cntAnonymous As Long
Dim cntXref As Long
Dim cntNormal As Long

‘ 1. 現在アクティブなAutoCADセッションとドキュメントを掴む
Set acadDoc = ThisDrawing
Set blkDefs = acadDoc.Blocks

‘ カウンタの初期化
cntAnonymous = 0
cntXref = 0
cntNormal = 0

‘ 2. イミディエイトウィンドウの見出しを出力
Debug.Print “==========================================================”
Debug.Print ” 図面内ブロック定義 監査レポート”
Debug.Print ” 対象図面: ” & acadDoc.Name
Debug.Print “==========================================================”
Debug.Print “No. | ブロック名 | 要素数 | 属性 | 種別 | 基点 (X, Y, Z)”
Debug.Print “———————————————————-”

Dim i As Long
For i = 0 to blkDefs.Count – 1
Set blkDef = blkDefs.Item(i)

‘ 3. ブロックスペースの性質による分類判定
Dim blockType As String
If blkDef.IsLayout Then
‘ レイアウト(Model空間やLayout1/2など)はブロックの親戚だが除外判定
GoTo NextBlock
ElseIf Left$(blkDef.Name, 1) = “” Then
‘ アノニマスブロック(寸法図やハッチングが内部的に作る無名ブロック)
cntAnonymous = cntAnonymous + 1
blockType = “無名(System)”
ElseIf blkDef.IsXRef Then
‘ 外部参照(Xref)
cntXref = cntXref + 1
blockType = “外部参照(Xref)”
Else
‘ 私たちが普段手動で作成する通常のブロック
cntNormal = cntNormal + 1
blockType = “通常ブロック”
End If

‘ 4. 基点座標(Origin)の取得
‘ ※AcadBlock自体のプロパティにはOriginがないため、
‘ ブロック内の要素やバウンディングボックス、あるいは特殊な方法で取得しますが、
‘ 今回は簡易的に「基点座標のプレースホルダ」として安全に処理します。
‘ (厳密な基点が必要な場合はBlockTableRecordレベルの操作が必要ですが、初学者向けに安全なプロパティに絞ります)

Dim hasAtt As String
If blkDef.HasAttributes Then
hasAtt = “あり”
Else
hasAtt = “なし”
End If

‘ 5. イミディエイトウィンドウへ整形出力
Debug.Print Format(i, “000”) & ” | ” & _
Left$(blkDef.Name & Space(25), 25) & ” | ” & _
Format(blkDef.Count, “0000”) & ” | ” & _
hasAtt & ” | ” & _
Left$(blockType & Space(12), 12) & ” | ”

NextBlock:
Next i

‘ 6. 集計結果サマリーの出力
Debug.Print “==========================================================”
Debug.Print ” 【集計完了】”
Debug.Print ” ・通常ブロック定義: ” & cntNormal & ” 個”
Debug.Print ” ・外部参照(Xref) : ” & cntXref & ” 個”
Debug.Print ” ・無名(システム) : ” & cntAnonymous & ” 個”
Debug.Print ” ・総ブロック定義数: ” & blkDefs.Count & ” 個”
Debug.Print “==========================================================”

‘ 完了の合図
MsgBox “ブロック定義のリスト化が完了しました!” & vbCrLf & _
“VBAエディタの「イミディエイトウィンドウ (Ctrl + G)」を確認してください。”, _
vbInformation, “処理完了”
End Sub

3. コードの心臓部を徹底解説!知っておくべきプロパティの正体

このコードのなかで、AutoCAD VBAのオブジェクトモデルを理解する上で非常に重要なポイントをいくつかピックアップして解説しよう。

① `ThisDrawing.Blocks` という「辞書(コレクション)」

AutoCADの図面には、目に見える線や文字だけでなく、画層(Layer)、文字スタイル(Textstyle)、そしてブロック定義(Block)といった「リソースの辞書データ」が背後で管理されている。
`ThisDrawing.Blocks` は、その図面が持っているすべての「型紙の束」を指している。配列と同じように `Item(i)` や `For Each` で中身を1つずつ取り出すことができるんだ。

② なぜ `IsLayout` や `Left$(…, 1) = “”` で弾く必要があるのか?

ここが実務で一番つまずくポイントだ。
`ThisDrawing.Blocks` の中には、ユーザーが作ったブロックだけでなく、以下の「お邪魔キャラクター」が混ざっている。

1. モデル空間(Model)やレイアウト空間(Layout1など)

  • 実はAutoCADの内部仕様では、モデル空間やペーパー空間も「ブロック定義の一種」として扱われている。これを通常のブロックとして処理してしまうと、図面内の全エンティティが二重計上されて大混乱になる。そのため、`blkDef.IsLayout` で必ず弾く必要がある。

2. アノニマスブロック(無名ブロック:`Model_Space` や `U1` など)

  • 寸法線(Dim)や引き出し線、ハッチングなどが、AutoCADが勝手に内部で生成する使い捨てのブロック。名前が “ から始まる。これも通常のユーザーブロックとは区別してカウントしなければ、実務のブロック管理の邪魔になる。

この「ゴミ(システム内部データ)と宝(ユーザー定義ブロック)を綺麗に選別する」という視点こそが、プロのエンジニアと初心者の決定的な違いなんだ。

4. 陥りやすいエラーと回避の知見

実務でこのコードを走らせるとき、以下の罠に直面することがある。

  • エラー 424: オブジェクトが必要です
  • 原因: `ThisDrawing` はAutoCADのVBA環境(IDE)から実行した時は動くが、万が一外部のExcel VBAなどからCOM経由でAutoCADを操作している場合にこの書き方をするとエラーになる。
  • 対策: 外部連携の場合は `Dim acadApp As AcadApplication` から `GetActiveObject` 等で正しくドキュメントオブジェクトをバインドすること。
  • 「挿入尺度や回転角度」がブロック定義側から直接取れない?
  • 知見: 鋭い人なら気づいたかもしれないが、「挿入尺度(Scale)や回転角度(Rotation)」というプロパティは、ブロック定義(`AcadBlock`)側には存在しない。
  • なぜなら、型紙(定義)の段階では「大きさ」や「向き」は決まっておらず、図面に配置された実体(`AcadBlockReference`)になって初めて、「この場所に、2倍の大きさで、45度傾けて置く」という情報が生まれるからだ。
  • もし各配置ごとの尺度や角度を調べたい場合は、ブロック定義の名前をキーにして、モデル空間内の全エンティティから `AcadBlockReference` を探し出す2段構えの処理が必要になる。

まとめ

今回は、AutoCAD VBAにおけるオブジェクトモデルの核心である「ブロック定義(Block Definition)」の抽出と一覧化について解説した。

  • ブロック定義(型紙)とブロック参照(実体)は別物であること
  • `ThisDrawing.Blocks` にはモデル空間やシステム内部の無名ブロックも混ざっていること
  • レイアウトやアノニマスブロックを適切にフィルタリングする技術

これらを自分のものにできた君なら、もうマクロの記録の卒業生ではない。立派なAutoCAD自動化エンジニアの仲間入りだ。
このコードをベースに、「特定の名前のブロックを一括置換する」「使われていない孤立したブロック定義をパージ(削除)する」といった実務ツールへと発展させてみてほしい。

ここをクリアした君なら、もう怖いものなしだ。次のステップへ進もう!

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