【SolidWorks VBAを掌握する極限の知見】CreateDrawViewAt4を用いたマルチ構成部品に対する最適ビューレイアウト自動化
図面化作業という、エンジニアにとって最もクリエイティブティを削がれる単調労働。これを根絶するのがSolidWorks VBAの真骨頂だ。
特に、アセンブリのマルチ構成部品(コンフィギュレーション)展開や、複数パーツの図面化において、ビューの配置座標をハードコーディングして爆死する開発者を数多く見てきた。`CreateDrawViewAt4` は非常に強力なメソッドだが、その仕様とオブジェクトのライフサイクルを理解していないと、「ビューが重なる」「スケールが狂う」「謎のクラッシュを引き起こす」という悪夢を見る。
今回は、実務の現場で即座に機能し、保守性・堅牢性に優れた「図面ビュー動的配置エンジンの構築法」を、チーフアーキテクトである私から授けよう。
—
1. なぜ従来のビュー配置コードは「現場で使えない」のか?
ネット上に転がっているサンプルコードの多くは、単一のモデルに対して決まった座標にビューを貼るだけの、お遊戯レベルのものだ。実務の現場では以下の壁にぶ当たる。
1. バウンディングボックス(BBox)の動的変化を無視している
部品のサイズやコンフィギュレーションが変われば、ビューの外形寸法も変わる。固定座標で配置すると、正面図と側面図が重なったり、図面枠からはみ出したりする。
2. モデルドキュメントと図面ドキュメントのコンテキスト混同
`SldWorks` アプリケーション、`ModelDoc2`、`DrawingDoc` のポインタ管理を誤り、アクティブドキュメントのロストによる `NullReferenceException`(VBAでは実行時エラー91)が頻発する。
3. エラーハンドリングの欠如
指定したコンフィギュレーションが存在しない場合や、図面テンプレートのパス切れに対する防衛策がない。
これらを解決するのが、今回紹介する「図面外形を算出し、マージンを動的に計算してグリッド配置するアルゴリズム」である。
—
2. アーキテクチャ設計と `CreateDrawViewAt4` の核心
`DrawingDoc::CreateDrawViewAt4` メソッドは、指定した3Dモデルのパスとコンフィギュレーション名から、2D空間上の指定座標にビューを生成する。
Set swView = swDrawing.CreateDrawViewAt4( _
ModelPath, _
ConfigurationName, _
X_Coord, _
Y_Coord, _
Z_Coord _
)
ここで重要なのは、「引数で渡す座標はビューの『原点(通常はモデルの原点または重心)』の位置である」という点だ。つまり、ビューの幅と高さを事前に予測、あるいは生成後に取得してシフトさせなければ、意図したレイアウトにはならない。
堅牢なレイアウト戦略
- 基準ビュー(正面図)を原点(例: X=100mm, Y=150mm)に配置。
- 生成された正面図のバウンディングボックス(BBox)をAPI経由で取得。
- 正面図の幅と高さ、および設定したマージン(余白)を基に、右側面図(X方向オフセット)と平面図(Y方向オフセット)、さらに等角投影図(斜め上方オフセット)の座標を動的に算出して配置する。
—
3. 【プロダクションコード】マルチ構成対応・動的レイアウト自動化マクロ
以下のコードは、エラーハンドリングを完備し、指定した3Dモデルの複数のコンフィギュレーションを読み込んで、図面シート上に整然とビューを並べる実戦用のVBAモジュールだ。
Option Explicit
‘ =========================================================================
‘ ódulo名: 模範的図面自動レイアウトエンジン
‘ 概要: 指定された3Dモデルの特定コンフィギュレーション群を読み込み、
C 干渉のない最適座標に正面・側面・等角図を動的配置する。
‘ =========================================================================
Sub Main_AutoLayoutDrawing()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
‘ 1. 事前検証(アクティブドキュメントが図面か、または3Dモデルか)
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。”, vbCritical, “致命的エラー”
Exit Sub
End If
‘ ここでは既に図面が開かれている前提、あるいは新規図面を作成するフローとする
‘ 実務では社内標準図面テンプレート(.slddrw)を指定して新規作成することを推奨
Dim templatePath As String
templatePath = “C:\ProgramData\SolidWorks\SOLIDWORKS 2023\templates\Drawing.slddrw” ‘ 環境に合わせて変更
Dim docType As Long
docType = swModel.GetType
Dim modelPath As String
If docType = swDocDRAWING Then
Set swDraw = swModel
MsgBox “図面ドキュメントから実行されました。対象の3Dモデルをアタッチしてください。”, vbExclamation
Exit Sub
Else
modelPath = swModel.GetPathName
If modelPath = “” Then
MsgBox “対象モデルが一度も保存されていません。保存してから実行してください。”, vbCritical
Exit Sub
End If
‘ 新規図面作成
Set swDraw = swApp.NewDocument(templatePath, swDwgPaperA3size, 0.42, 0.297)
If swDraw Is Nothing Then
MsgBox “図面ドキュメントの作成に失敗しました。テンプレートパスを確認してください。”, vbCritical
Exit Sub
End If
End If
‘ 2. 処理対象コンフィギュレーションの配列定義(実務ではDBやCSVから動的取得も可)
Dim configNames() As String
configNames = Split(“DEFAULT,Type_A,Type_B”, “,”)
Dim i As Long
Dim startY As Double
startY = 200.0 ‘ 最初の行のY座標 (mm)
‘ 3. ループ処理によるマルチ構成展開
For i = LBound(configNames) to UBound(configNames)
Dim currentConfig As String
currentConfig = Trim(configNames(i))
‘ 座標計算(1行あたりに配置するレイアウトの起点)
Dim baseCoordX As Double
Dim baseCoordY As Double
baseCoordX = 80.0
baseCoordY = startY – (i 120.0) ‘ 1行につき120mm下方にずらす
Call DeployViewsForConfiguration(swDraw, modelPath, currentConfig, baseCoordX, baseCoordY)
Next i
‘ ビュー更新と再描画
swModel.EditRebuild3
MsgBox “すべての図面ビューの動的配置が完了しました。”, vbInformation, “完了”
End Sub
‘ ————————————————————————-
‘ 内部プロシージャ: 単一コンフィギュレーションに対する4面図(正・側・平・等角)の動的配置
‘ ————————————————————————-
Private Sub DeployViewsForConfiguration(ByRef swDraw As SldWorks.DrawingDoc, ByVal modelPath As String, ByVal configName As String, ByVal originX As Double, ByVal originY As Double)
Dim swViewFront As SldWorks.View
Dim swViewSide As SldWorks.View
Dim swViewTop As SldWorks.View
Dim swViewIso As SldWorks.View
‘ 1. 正面図の作成
Set swViewFront = swDraw.CreateDrawViewAt4(modelPath, configName, originX / 1000#, originY / 1000#, 0#)
If swViewFront Is Nothing Then
Debug.Print “Warning: コンフィギュレーション [” & configName & “] の正面図作成に失敗しました。”
Exit Sub
End If
‘ 正面図のスケール調整(必要に応じて)
swViewFront.ScaleDecimal = 0.5 ‘ 1/2スケール
‘ 2. バウンディングボックス(外形寸法)の取得による動的オフセット計算
‘ ※SolidWorks APIではメートル単位系が基本である点に注意
Dim box As Variant
box = swViewFront.GetBox
‘ GetBox戻り値: (0)=Xmin, (1)=Ymin, (2)=Zmin, (3)=Xmax, (4)=Ymax, (5)=Zmax
Dim viewWidth As Double
Dim viewHeight As Double
viewWidth = (box(3) – box(0)) 1000# ‘ mm換算
viewHeight = (box(4) – box(1)) 1000# ‘ mm換算
Dim margin As Double
margin = 15.0 ‘ ビュー間のマージン (mm)
‘ 3. 右側面図の配置 (正面図の右側)
Dim sideX As Double
Dim sideY As Double
sideX = originX + viewWidth + margin + (viewWidth / 2#)
sideY = originY
Set swViewSide = swDraw.CreateDrawViewAt4(modelPath, configName, sideX / 1000#, sideY / 1000#, 0#)
If Not swViewSide Is Nothing Then
swViewSide.ScaleDecimal = 0.5
‘ 投影関係の付与(必要であればAPIで制約をかけるが、座標配置のみでも可)
End If
‘ 4. 等角投影図(Isometric)の配置 (正面図の右上)
Dim isoX As Double
Dim isoY As Double
isoX = originX + viewWidth + margin + 20.0
isoY = originY + viewHeight + margin
‘ 等角図は専用のビュー向きを指定する必要があるため、ドキュメントのパラメータに依存
‘ CreateDrawViewAt4ではデフォルト向きになるため、後からOrientationTypeを変更する
Set swViewIso = swDraw.CreateDrawViewAt4(modelPath, configName, isoX / 1000#, isoY / 1000#, 0#)
If Not swViewIso Is Nothing Then
swViewIso.ScaleDecimal = 0.4
swViewIso.ReuseName = False
‘ 等角投影 (Isometric) への変更
swViewIso.Type = 3 ‘ swDrawingIsometric (環境によりenum値確認)
End If
End Sub
—
4. 現場で絶対に踏んではいけない「3つの地雷」と回避策
チーフアーキテクトとして、過去に後輩たちが踏み抜いてきたトラップを共有しよう。
① 単位系(MKS vs MMGS)の罠
SolidWorks APIの内部処理は、例外なく「メートル(m)」基準で動作する。
画面上では「ミリメートル(mm)」で思考しているため、座標やオフセット値(例: `100mm`)をそのまま渡すと、モデルが微小すぎて見えなくなるか、宇宙の彼方に吹っ飛ぶ。
> 対策: 座標や寸法の変数は必ず `1000.0` で割ってメートルに換算してからAPIに渡せ。
② メモリリークとオブジェクトの解放
VBAは自動ガベージコレクションを持つが、COMオブジェクト(`SldWorks`, `ModelDoc2`, `View` 等)の参照が残ったままだと、SolidWorksのプロセス背後でメモリリークが発生し、連続実行時に動作が重くなる、あるいはフリーズする。
> 対策: プロシージャの抜け際やループの終わりには、必ず明示的にオブジェクト変数に `Nothing` を代入して参照を断ち切れ。
>
> Set swViewFront = Nothing
> Set swDraw = Nothing
>
③ 存在しないコンフィギュレーション名による強制終了
アセンブリの設計変更でコンフィギュレーション名がリネームされたり削除されたりした場合、コード内でハードコーディングされた文字列を指定すると、APIがエラーを吐いてマクロが強制終了する。
> 対策: 処理の前に `ModelDoc2::GetConfigurationNames` を呼び出し、対象のコンフィギュレーションが本当に存在するかどうかを配列走査してバリデーションする防衛的コードを必ず挟むこと。
—
5. さらなる高みへ:データベース・外部CSV連携への拡張
今回のコードはコンフィギュレーション名をコード内に直書きしているが、真の自動化エンジニアを目指すなら、これをExcel管理表や生産管理DB(Access / SQL Server)からの外部入力に拡張すべきだ。
「どの製品群の、どのコンフィギュレーションを、どの図面フォーマットで一括製図するか」を外部からJSONやCSVで流し込み、夜間バッチのようにタスクスケジューラ経由でSolidWorksをヘッドレス起動(UI非表示)して図面を全自動生成する。ここまで構築できて初めて、「業務効率化を極めたプロフェッショナル」と名乗ることができる。
泥臭い手作業の図面レイアウトからエンジニアを解放せよ。コードの力で、モノづくりの本質に集中できる環境を君の手で創り出すのだ。
