SolidWorks VBAを掌握する極限の知見:図面ビュー座標制御の完全自動化
図面自動化の現場において、最も多くのエンジニアを絶望させるのは「図面ビューの配置崩れ」である。
モデルから図面(`.slddrw`)を生成した際、デフォルトのアルゴリズムに身を任せると、ビュー同士が重なり合ったり、シートからはみ出したり、不規則な配置になってしまったりする。これを人間が手動でドラッグして整列させるなどというのは、自動化の美学に反するだけでなく、莫大なエンジニアリングマンパワーの無駄遣いだ。
今回は、SolidWorks APIの `View.Position` プロパティを極限までハックし、複数の図面ビューを数学的に正確なグリッド状へ美しく整列させるための実践的かつ堅牢なVBAコードと、その裏にあるアーキテクチャの真髄を解説する。
—
1. 座標制御におけるSolidWorks APIの「隠された仕様」
`View.Position` プロパティを操作する際、多くの開発者がハマる罠がある。それは「座標系の原点と単位系」の誤解だ。
- 単位の絶対原則: SolidWorks APIの内部計算単位は常にメートル(m)である。VBA側でミリメートル(mm)として渡すと、ビューはシートの彼方に吹き飛ぶか、ミクロなサイズで点のように配置される。必ず `0.01` を乗算してメートルに換算しなければならない。
- シート座標系の原点: 図面ビューの `Position` が返す座標、および設定する座標は、シートの左下隅(0, 0)を起点とした相対座標(X, Y)である。
- ビューのバウンディングボックスの概念: ビューの「中心」を指定しているのか、「原点(モデルの原点投影位置)」を指定しているのか。`View.Position` が動かすのは「ビューの原点(Model Origin)」である。全体のバウンディングボックス(外形)ではないため、モデルの形状によっては意図した位置からオフセットが発生することを計算に入れたロジックを組む必要がある。
—
2. メモリ管理とパフォーマンスの極意
多数の図面ビューを一括処理するマクロにおいて、COMオブジェクトの解放を怠ると、SolidWorksのメモリリークや、最悪の場合はアプリケーションのクラッシュ(VBAの「メモリ不足です」エラー)を招く。
ループ内で生成される `View` オブジェクトや `DrawingDoc` オブジェクトは、使用後に必ず `Set 〇〇 = Nothing` で参照を断ち切り、VBAのガベージコレクションを促すこと。これがシニアエンジニアとアマチュアを分ける決定的な境界線である。
—
3. 実装コード:グリッドレイアウト自動整列マクロ
以下のコードは、アクティブな図面ドキュメント内に存在するすべての主要ビュー(アセンブリまたは部品の投影図)を検出し、指定したマージンと列数を基にして、自動的に綺麗にグリッド状に整列させる実用コードである。
Option Explicit
‘ =========================================================================
‘ プログラム名: 図面ビュー・グリッド自動レイアウトエンジン
‘ 概要 : 活性図面内の全図面ビューの座標を計算し、整然と整列させる
‘ 依存関係 : SolidWorks 201X以降 / 要参照設定
‘ =========================================================================
Public Sub AutoAlignDrawingViews()
‘ — 1. 宣言と初期化 —
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim swSheet As SldWorks.Sheet
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
‘ ドキュメントタイプチェック (3 = swDocDRAWING)
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。”, vbCritical, “API Error”
Exit Sub
End If
If swModel.GetType() <> swDocDRAWING Then
MsgBox “このマクロは図面ドキュメント(.slddrw)でのみ実行可能です。”, vbExclamation, “Type Mismatch”
Exit Sub
End If
Set swDraw = swModel
Set swSheet = swDraw.GetCurrentSheet()
‘ — 2. シートサイズの取得 (単位: mm -> m変換の準備) —
Dim sheetWidth As Double, sheetHeight As Double
Dim sheetProps As Variant
sheetProps = swSheet.GetProperties()
‘ sheetProps(2) = 幅(m), sheetProps(3) = 高さ(m)
sheetWidth = sheetProps(2)
sheetHeight = sheetProps(3)
‘ — 3. ビューの列挙 —
Dim vViews As Variant
vViews = swDraw.GetViews()
If IsEmpty(vViews) Then
MsgBox “配置されているビューがありません。”, vbInformation, “Info”
Exit Sub
End If
‘ — 4. レイアウト計算パラメータの設定 —
‘ ※ ここではシート左上を起点とし、右方向へ並べ、満たったら改行するアルゴリズムを実装
Dim startX As Double, startY As Double
Dim deltaX As Double, deltaY As Double
Dim maxColumns As Integer
startX = 0.05 ‘ 左マージン 50mm (0.05m)
startY = sheetHeight – 0.05 ‘ 上マージン 50mm下がり (m)
deltaX = 0.15 ‘ 列間隔 150mm (0.15m) – ビューサイズに応じ調整
deltaY = 0.15 ‘ 行間隔 150mm (0.15m)
maxColumns = 3 ‘ 1行あたりの最大ビュー数
Dim colIndex As Integer
Dim rowIndex As Integer
colIndex = 0
rowIndex = 0
Dim i As Long
Dim swView As SldWorks.View
‘ 画面描画を停止して処理速度を極限まで高める (パフォーマンス最適化)
swModel.Extension.EnableGraphics = False
‘ — 5. メインループによる座標書き換え —
For i = LBound(vViews) To UBound(vViews)
Set swView = vViews(i)
‘ シート名を保持しているルートビュー(” \\@Sheet ” 等)は除外する
‘ 通常のビューは Name がルート名を持つ
If swView.GetName() <> swSheet.GetName() Then
‘ シート境界チェックと座標計算
Dim targetX As Double
Dim targetY As Double
targetX = startX + (colIndex deltaX)
targetY = startY – (rowIndex deltaY)
‘ 座標適用 (View.Position は 2要素の配列 Double(0)=X, Double(1)=Y を要求)
Dim pos(1) As Double
pos(0) = targetX
pos(1) = targetY
Dim bRet As Boolean
bRet = swView.SetPosition2(pos(0), pos(1))
If Not bRet Then
Debug.Print “Warning: ビュー [” & swView.GetName() & “] の座標設定に失敗しました。”
End If
‘ インデックス進める
colIndex = colIndex + 1
If colIndex >= maxColumns Then
colIndex = 0
rowIndex = rowIndex + 1
End If
End If
‘ オブジェクトの明示的解放 (メモリリーク防止)
Set swView = Nothing
Next i
‘ — 6. 終了処理と画面復元 —
swModel.Extension.EnableGraphics = True
swModel.WindowRedraw
MsgBox “図面ビューの整列が完了しました。”, vbInformation, “Complete”
‘ 最終的なオブジェクト解放
Set swSheet = Nothing
Set swDraw = Nothing
Set swModel = Nothing
Set swApp = Nothing
End Sub
—
4. チーフアーキテクトからの実務アドバイス
1. `SetPosition` と `SetPosition2` の使い分け
古いレガシーコードでは `SetPosition` が使われているケースがあるが、現在のSolidWorks APIでは引数や戻り値のハンドリングが洗練された `SetPosition2` を使用するのが鉄則である。
2. `EnableGraphics = False` の魔力
複雑な図面で数十個のビューを一斉に動かす場合、描画更新が挟まると処理時間が何倍にも膨れ上がる。`swModel.Extension.EnableGraphics = False` を挟むことで、バックグラウンドでの一括計算となり、実行速度を劇的に向上させることが可能だ。
3. システム間連携への拡張
このVBAマクロ単体でも十分強力だが、PDM(Product Data Management)システムや外部ERPからのバッチ処理(タスクスケジューラ経由のヘッドレス実行)と組み合わせることで、「図面が生成された瞬間に、人間の手を介さず完璧にレイアウトされた図面が完成する」という完全自動化パイプラインの基盤となる。
小手先のテクニックに頼るな。APIの仕様を深く理解し、メモリとパフォーマンスを支配した者だけが、真の「自動化の王国」を築くことができるのだ。
