図面は「データ」ではなく「メッセージ」である。
検図者の視線を操る、AutoCAD VBAによる「視覚的申し送り」の極意
こんにちは。現場の自動化を支えるアーキテクトです。
AutoCADを使っていると、「ファイルを保存して渡したのに、相手から『どこを見ればいいの?』と聞かれた」なんて経験はありませんか?
図面を開いたとき、画面には広大な座標系が広がっています。検図者やクライアントがファイルを開いた瞬間、「今、どこに注目すべきか」を視覚的に提示できているか。 これは、単なる操作の差ではなく、エンジニアとしての「情報の渡し方」の質を決める重要な要素です。
今日は、マクロの記録から一歩踏み出し、「図面内の特定のマークを自動で見つけ出し、そこを画面いっぱいに表示(ズーム)した状態で保存する」という、実務に直結する高度なテクニックを伝授します。
これをマスターすれば、あなたの作成する図面は「ただのデータ」から「親切なメッセージ」へと進化します。
1. 戦略を立てる:どうやって「注釈」を見つけるか?
いきなりコードを書き始めるのは素人の仕事です。プロのエンジニアは、まず「ロジック(論理)」を組み立てます。
今回のゴールは、「特定の名前(例:`REV_MARK`)を持つブロック」を探し、その範囲をズームして保存することです。
実装のステップ
1. 探索: モデル空間内の全てのオブジェクトをスキャンし、特定の名前を持つブロックを探す。
2. 計算: 見つかったマークの「左下(最小座標)」と「右上(最大座標)」を特定する(これを境界ボックス/Bounding Boxと呼びます)。
3. 制御: 算出した範囲を使って、図面の表示領域(Viewport)をズームする。
4. 確定: その表示状態を維持したまま、図面を保存する。
ここで重要なのは、「マークが複数あった場合、それらすべてを囲むようにズームする」という配慮です。これこそが、中級者への入り口です。
2. 実装:魂を込めたコード例
それでは、実際に動作するコードを見ていきましょう。このコードは、初心者の方でも読みやすいよう、丁寧にコメントを添えています。
Option Explicit
''' <summary>
''' 特定のブロック(変更箇所マーク)を検索し、
''' その範囲をズームしてから図面を保存するメインルーチン
''' </summary>
Sub SaveWithFocusOnMarks()
Dim acadDoc As AcadDocument
Set acadDoc = ThisDrawing
Dim objEntity As AcadEntity
Dim targetBlockName As String
Dim foundCount As Integer
' --- 設定エリア ---
' 検索したいブロックの名前を指定してください
targetBlockName = "REV_MARK"
' ------------------
foundCount = 0
' 境界ボックス(ズーム範囲)を保持するための変数
Dim minX As Double, minY As Double, maxX As Double, maxY As Double
Dim firstFound As Boolean
firstFound = True
On Error GoTo ErrorHandler
' 1. モデル空間内の全オブジェクトを走査
' ※ 大規模図面ではレイヤーでフィルタリングするのがプロの技ですが、
' 今回は基本を学ぶため、全探索を行います。
For Each objEntity In acadDoc.ModelSpace
' オブジェクトが「ブロック参照」かつ「名前が一致」するか判定
If TypeOf objEntity Is AcadBlockReference Then
If objEntity.Name = targetBlockName Then
' 2. 境界ボックス(表示範囲)の計算
' ブロックの挿入点とスケールから、その範囲を特定します
Dim insPt As Variant
insPt = objEntity.InsertionPoint
' ここでは簡易的に、ブロックの挿入点を基準に計算します。
' 本来はブロックのサイズ(BoundingBox)を取得するのが理想的です。
' 今回は「マークの周囲を囲む」ため、挿入点を中心とした矩形を作ります。
' マークの「中心」を基準に、上下左右の広がりを計算(例:100ユニット分)
Dim offset As Double
offset = 50
If firstFound Then
minX = insPt(0) - offset: maxX = insPt(0) + offset
minY = insPt(1) - offset: maxY = insPt(1) + offset
firstFound = False
Else
' 既に見つかった範囲を拡張していく(全マークを囲むため)
If insPt(0) - offset < minX Then minX = insPt(0) - offset
If insPt(1) - offset < minY Then minY = insPt(1) - offset
If insPt(0) + offset > maxX Then maxX = insPt(0) + offset
If insPt(1) + offset > maxY Then maxY = insPt(1) + offset
End If
foundCount = foundCount + 1
End If
End If
Next objEntity
' 3. ズームと保存の実行
If foundCount > 0 Then
' ズーム範囲を指定するための配列を作成
Dim zoomWindow As Variant
zoomWindow = Array(Array(minX, minY), Array(maxX, maxY))
' AutoCADのコマンドを使用してズームを実行
' VBAの標準メソッドよりも、SendCommandの方が確実な場合があります。
acadDoc.SendCommand "-ZOOM" & vbCr & "W" & vbCr & minX & "," & minY & vbCr & maxX & "," & maxY & vbCr
' 保存の実行
acadDoc.Save
MsgBox foundCount & " 個のマークが見つかりました。範囲をズームして保存しました。", vbInformation, "完了"
Else
MsgBox "指定されたマーク(" & targetBlockName & ")が見つかりませんでした。そのまま保存します。", vbExclamation, "警告"
acadDoc.Save
End If
Exit Sub
ErrorHandler:
MsgBox "エラーが発生しました: " & Err.Description, vbCritical, "エラー"
End Sub
3. コードの深淵:プロが教える「ここが重要」
このコードをただコピペするだけでは、あなたはまだ「マクロ使い」です。このコードの裏側にある「設計思想」を理解してこそ、真のエンジニアです。
① `SendCommand` を使う理由
AutoCAD VBAには、表示領域を制御する `View` オブジェクトがありますが、実は `SendCommand` を使って直接コマンド(`-ZOOM`)を叩くほうが、直感的で「図面として正しい表示」を得やすい場面が多いのです。これは、AutoCADの内部的な描画更新と同期させやすいためです。
② 境界ボックスの拡張ロジック
コード内の `If … Then … Else` の部分は、「最小値の更新」と「最大値の更新」を行っています。
- 新しい点が見つかるたびに、「今までの最小値より小さければ更新」「最大値より大きければ更新」を繰り返す。
- これにより、複数のマークが図面のあちこちに散らばっていても、「すべてのマークを一つの窓の中に収める」ことが可能になります。
③ オブジェクトのライフサイクルとパフォーマンス
今回のコードでは `For Each objEntity In acadDoc.ModelSpace` を使っています。
もし図面の中に10万個の線があったらどうなるでしょうか? 毎回全探索するのは非常に重い処理になります。
「実務での極意」を教えましょう。
> 「特定のレイヤーにマークを置くルール」を運用し、コード側では「そのレイヤーのオブジェクトだけを対象にする」ようにフィルタリングしてください。これだけで、処理速度は劇的に向上します。
4. 陥りやすいエラーと対策
初心者がこの手の開発で必ず躓くポイントが2つあります。
1. ブロックの名前間違い:
`targetBlockName = “REV_MARK”` と書いていても、図面上のブロック名が `rev_mark`(小文字)だったり、属性が含まれていて名前が異なっていたりすると、一つもヒットしません。
- 対策: `StrComp(objEntity.Name, targetBlockName, vbTextCompare) = 0` を使って、大文字小文字を区別せずに比較するようにしましょう。
2. 座標系の混乱:
AutoCADには「世界座標系(WCS)」と「ユーザー座標系(UCS)」があります。ズームする座標がズレる原因の多くは、UCSが回転していることです。
- 対策: ズーム操作を行う前に、`acadDoc.UCS` を `WCS` にリセットする処理を入れると、非常に堅牢なマクロになります。
最後に:自動化の先にあるもの
自動化の目的は「楽をすること」だけではありません。「ミスを減らし、価値の高い仕事に集中すること」です。
今回紹介した「視覚的な申し送り」ができる図面は、受け取った相手のストレスを劇的に減らします。その積み重ねが、あなたの信頼を築き、エンジニアとしての市場価値を高めていくのです。
「ここをクリアすれば、AutoCAD VBAの基本はバッチリですよ。」
さあ、次は自分なりの「独自のマーク」を作って、このコードをカスタマイズしてみてください。応援しています!
