マクロ記録の先へ:幾何学演算で手に入れる「ビューが重ならない」理想の図面自動レイアウト術
こんにちは。自動化の世界へようこそ。
「マクロの記録」ボタンを押して、録画されたコードを眺めて「ふーん、こうやって動いてるんだ」と思ったことはありませんか? もしそうなら、あなたは今、自動化エンジニアとしての最初の一歩を踏み出したばかりです。
しかし、現場で本当に求められるのは、記録された「決まった動き」ではありません。
「アセンブリの部品数が増えて、ビューのサイズが変わってしまったけれど、図面が重ならないように自動で整列してほしい」
そんな、状況に応じて判断を変える、知的なプログラムです。
今日は、プロの現場で使われる「幾何学演算」の考え方を取り入れ、ビュー同士が絶対に干渉しない、魔法のようなオートレイアウト・エンジンの作り方を伝授しましょう。
1. なぜ「座標の指定」だけでは失敗するのか?
初学者が最初に陥る罠があります。それは、「ビューの中心座標を 100mm, 100mm に置く」といった、静的な数値指定です。
図面の世界は、想像以上に動的です。
- 部品の形状が変われば、ビューの大きさ(外形)が変わる。
- 寸法線を追加すれば、ビューの占有範囲が広がる。
- アセンブリの構成が変われば、投影される図形の密度が変わる。
もし、あなたが「ビューAは座標(0,0)に置く。ビューBは(100,0)に置く」というコードを書いたとしましょう。もしビューAが巨大化して、横幅が150mmになったらどうなるでしょうか? ビューAとビューBは、無残にも重なってしまいます。
これを解決する鍵が、「バウンディングボックス(Bounding Box)」の概念です。
2. 核心概念:バウンディングボックスによる「不可侵領域」の定義
「バウンディングボックス」とは、ある物体をすっぽりと包み込む「最小の直立長方形」のことです。
図面におけるビューのバウンディングボックスを計算するということは、「そのビューが、寸法線や注記を含めて、結局どれくらいの面積を占有しているのか?」をプログラムに理解させることを意味します。
理想的な配置アルゴリズムの思考プロセス
1. 計測: 1つ目のビューのバウンディングボックス(左端、右端、上端、下端の座標)を取得する。
2. 予測: 「次に置くべき位置」を、`現在のビューの右端座標 + 安全マージン` として計算する。
3. 配置: 計算した座標に、次のビューを配置する。
4. 反復: これをすべてのビューに対して繰り返す。
この「前のビューの大きさを測ってから、次の場所を決める」という動的なプロセスこそが、プロの自動化です。
3. 実践:ビュー非干渉レイアウト・エンジン
それでは、実際に使えるVBAコードを見ていきましょう。
ここでは、シート上のすべてのビューを、左から右へ、重ならないように順番に並べるエンジンを実装します。
Option Explicit
' ==============================================================================
' テーマ:DrawingViewのバウンディングボックスによる非干渉レイアウト
' 概要:ビューの実際の占有範囲を計算し、重ならないように横一列に整列させる
' ==============================================================================
Sub AutoLayoutDrawingViews()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim swSheet As SldWorks.Sheet
Dim swView As SldWorks.View
Dim vViews As Variant
Dim i As Integer
' 座標計算用の変数
Dim box As Variant ' GetBoundingBoxの結果を受け取る配列
Dim margin As Double ' ビュー間の安全マージン (m)
Dim currentX As Double
Dim currentY As Double
Dim viewWidth As Double
Dim viewHeight As Double
' --- 設定エリア ---
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
' 図面ファイルが開かれているかチェック
If swModel Is Nothing Or swModel.GetType <> swDocDRAWING Then
MsgBox "図面ファイルを開いてから実行してください。", vbCritical
Exit Sub
End If
Set swDraw = swModel
Set swSheet = swDraw.GetCurrentSheet
' マージンの設定 (例: 20mm = 0.02m)
' SolidWorksの内部単位は常に「メートル」であることを忘れないでください!
margin = 0.02
' 配置を開始する初期位置 (シートの左下付近)
currentX = 0.05
currentY = 0.1 ' シートの下から100mmの位置から開始
' ------------------
' 全ビューを取得
vViews = swDraw.GetViews
' 注意:GetViewsは「シート自体」も含む場合があるため、
' 実際のループではビューのプロパティを確認してスキップする制御が必要です。
' ※簡易化のため、ビューの配列を直接ループします
' 実際には、最初のビュー(シートそのもの)を飛ばす処理が必要です
' 描画更新を一時停止(パフォーマンス向上のため)
swModel.ActiveView.EnableGraphicsUpdate = False
' 配列の要素数を確認
Dim viewCount As Integer
viewCount = UBound(vViews)
' 最初のビュー(シート)はインデックス0にあることが多いため、1から開始
For i = 1 To viewCount
Set swView = vViews(i)
' 1. ビューのバウンディングボックスを取得
' box(0) = MinX, box(1) = MinY, box(2) = MaxX, box(3) = MaxY
box = swView.GetBoundingBox
' 2. ビューの幅と高さを計算
viewWidth = box(2) - box(0)
viewHeight = box(3) - box(1)
' 3. ビューを現在の計算座標に移動させる
' 注意:ビューの座標指定は「中心」ではなく「左下」や「中心」など
' APIの仕様に合わせて、中心座標を計算してセットします。
Dim centerX As Double
Dim centerY As Double
centerX = currentX + (viewWidth / 2)
centerY = currentY + (viewHeight / 2)
' ビューの位置を更新
swView.SetPosition centerX, centerY
' 4. 次のビューのための「開始X座標」を更新
' 「現在のビューの右端 + マージン」を次の開始点にする
currentX = currentX + viewWidth + margin
' もし横に並べすぎてシートをはみ出しそうなら、改行するロジックをここに追加できます
' (今回はシンプルに横一列の例)
Debug.Print "View " & i & " placed at: " & centerX & ", " & centerY
Next i
' 再描画して結果を表示
swModel.EditRebuild3
swModel.ActiveView.EnableGraphicsUpdate = True
MsgBox "レイアウト完了!", vbInformation
End Sub
4. 伝説のアーキテクトからのアドバイス:陥りやすい「3つの罠」
このコードを動かす際、あるいは自分で拡張する際に、必ず突き当たる壁があります。これを知っているだけで、デバッグ時間は半分になります。
① 単位の罠(Meter vs Millimeter)
SolidWorks APIの内部単位は、常に「メートル (m)」です。
マクロの記録では `0.1` と書いてあるところが、設計図面上では `100mm` を意味しています。
「なぜかビューが豆粒みたいに小さくなった!」「どこか遠くに飛んでいった!」と思ったら、まず単位を確認してください。
② 再構築(Rebuild)の罠
バウンディングボックスの計算は、「今、画面に見えている状態」に基づきます。
もし、プログラムの途中でビューのスケールを変えたり、寸法を追加したりした場合は、必ず `swModel.EditRebuild3` を実行して、幾何学情報を更新させてください。再構築せずに計算すると、古い(間違った)サイズで計算してしまいます。
③ 座標系の罠
`GetBoundingBox` が返す値は、「シートの原点」からの絶対座標です。
一方で、ビューの配置操作(`SetPosition`)が「ビューの中心」を指すのか「左下」を指すのかは、APIのメソッドによって異なります。
- `View.GetPosition` / `SetPosition` は、多くの場合「ビューの中心」を操作します。
- `GetBoundingBox` は「四隅の座標」を返します。
この「中心」と「端」の差を計算(`viewWidth / 2`)するのが、幾何学演算の醍醐味です。
5. まとめ:ここをクリアすれば、あなたはもう「記録」の奴隷ではない
「マクロの記録」は、いわば「答え」を書き写しているだけです。
しかし、今回学んだ「バウンディングボックスを使った幾何学演算」は、「答えの出し方(ロジック)」を組み立てる技術です。
- 測る(GetBoundingBox)
- 計算する(Width + Margin)
- 動かす(SetPosition)
このサイクルをマスターすれば、ビューの配置だけでなく、部品の自動選定、注記の自動整列、さらには複雑な検査図面の自動生成まで、あなたの手でコントロールできるようになります。
一歩ずつ、コードの裏側にある「数学的な意味」を理解していってください。その先に、真の自動化エンジニアとしての景色が待っていますよ。
応援しています。頑張ってくださいね!
