【テクニカル・上級編】【初心者向け】アクティブ図面への三面図(正面図・平面図・側面図)一括自動配置マクロ – SolidWorks VBA解析バイブル

スポンサーリンク

SolidWorks VBAを掌握する極限の知見

【図面自動化の極意】アクティブ図面への三面図一括自動配置マクロの実装とメモリ最適化

数多のCADエンジニアが日々のルーチンワークで摩耗している。その最たるものが「3Dモデルからの図面起こし」であり、中でも正面図・平面図・側面図の三面図を手動で配置し、ビューの整列や尺度調整を行う作業は、エンジニアの創造的な時間を容赦なく奪う悪しき慣習である。

本稿では、SolidWorks APIの `DrawingDoc.CreateDrawViewFromModelView3` メソッドを核とし、単なる「動くコード」の枠を超えた、実務の現場で耐えうる堅牢性とパフォーマンスを備えた三面図一括自動配置マクロの全貌を公開する。

レガシーなVBA環境であっても、APIのライフサイクルとメモリ管理の原則を理解していれば、極めて安定したエンタープライズ級の自動化基盤を構築できる。その技術的真髄をここに伝授する。

—

1. アーキテクチャの設計思想とAPIの選定理由

図面自動化において最も陥りやすい罠は、「ビューを生成する順序」と「コンテキストの不整合」である。
SolidWorksのドキュメント構造(SldWorks -> ModelDoc2 -> DrawingDoc)において、図面ビューの生成は、親となる3Dモデルのビュー方向(” Front”`, `” Top”`, `” Right”` など)と密接に結びついている。

レガシーなマクロでは、画面の描画更新(`Visible`プロパティや再描画)を挟みながら泥臭く配置を行うことが多いが、これはパフォーマンスの低下を招くだけでなく、COMオブジェクトの解放漏れによるメモリリークの温床となる。

我々が目指すべきは、以下の3点である:
1. トランザクションの局所化: 処理中の画面描画を抑制し、APIの実行速度を限界まで引き上げる。
2. 厳密なオブジェクトライフサイクル管理: 取得したCOM参照(`ModelDoc2`, `View`など)は、スコープ抜けのタイミングで確実に解放する。
3. 動的なシートサイズ・座標計算: ハードコーディングされたマジックナンバーを排除し、モデルのバウンディングボックスに応じた最適な配置座標を算出する。

—

2. 実装コード:実務仕様・三面図一括自動配置マクロ

以下のコードは、アクティブな図面ドキュメントに対し、指定された3Dモデル(または図面内の最初の参照モデル)から三面図をプログラムaticallyに生成し、シート上の適切な位置へ整列配置する完全版の実務コードである。

Option Explicit

‘ =================================================================================
ニッチかつ最高峰の知見に基づく SolidWorks VBA 自動化モジュール
テーマ: アクティブ図面への三面図一括自動配置
対象バージョン: SolidWorks 2018 以降推奨
=================================================================================

Sub Execute_AutoThreeViewPlacement()
Dim swApp As SldWorks.SldWorks
Dim swDraw As SldWorks.DrawingDoc
Dim swModel As SldWorks.ModelDoc2
Dim swModelDocExt As SldWorks.ModelDocExtension

‘ 1. SldWorks アプリケーションの取得(早期バインディングによる型安全性の確保)
Set swApp = Application.SldWorks
If swApp Is Nothing Then
MsgBox “SolidWorksが起動していません。”, vbCritical, “致命的エラー”
Exit Sub
End If

‘ 2. アクティブドキュメントの取得と図面判定
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。”, vbExclamation, “警告”
Exit Sub
End If

If swModel.GetType() <> swDocDRAWING Then
MsgBox “アクティブなドキュメントは図面ではありません。図面を開いて実行してください。”, vbCritical, “型不一致エラー”
Exit Sub
End If

Set swDraw = swModel
Set swModelDocExt = swModel.Extension

‘ 3. パフォーマンス最適化:画面描画の凍結(Redrawを止めることで数倍の速度向上を実現)
swModel.Visible = False

Dim longstatus As Long
longstatus = swModelDocExt.SetUserPreferenceToggle(swUserPreferenceToggle_e.swViewDisplayShadedWithoutEdges, False)

On Error GoTo ErrorHandler

‘ 4. 参照モデルのパス取得(図面に紐付く最初のモデルを取得)
Dim swSheet As SldWorks.Sheet
Set swSheet = swDraw.GetCurrentSheet()

Dim vModelNames As Variant
vModelNames = swSheet.GetViews()

Dim swFirstView As SldWorks.View
Dim modelPath As String
Dim i As Long

‘ シート上の既存ビューからモデルドキュメントへのパスを逆引きする
For i = 0 To UBound(vModelNames)
Set swFirstView = vModelNames(i)
If Not swFirstView.IsRootView() Then
If swFirstView.GetModelName() <> “” Then
modelPath = swFirstView.GetModelName()
Exit For
End If
End If
Next i

If modelPath = “” Then
‘ 既存ビューがない場合は、ユーザーにモデル選択を促すダイアログを出す等のフォールバック
modelPath = swApp.GetOpenFileName(“モデル選択”, “”, “SolidWorks Part/Assembly (.sldprt;.sldasm)|.sldprt;.sldasm”, _
“モデルファイルを選択してください”, “”)
If modelPath = “” Then GoTo Cleanup
End If

‘ 5. 座標計算ロジック(A3/A4などのシートサイズに応じた動的配置)
Dim sheetWidth As Double, sheetHeight As Double
Dim scale1 As Double, scale2 As Double
swSheet.GetSize sheetWidth, sheetHeight ‘ 単位はメートル(m)

‘ 基準点(正面図の中心座標):シート左下を原点(0,0)とした場合のオフセット
‘ シート幅の 30%、高さの 50% を正面図のアンカーとする
Dim baseCoordX As Double, baseCoordY As Double
baseCoordX = sheetWidth 0.35
baseCoordY = sheetHeight 0.50

‘ 6. 正面図(Front View)の配置
Dim swFrontView As SldWorks.View
Set swFrontView = swDraw.CreateDrawViewFromModelView3( _
modelPath, _
“Front”, _
baseCoordX, _
baseCoordY, _
0#)

If swFrontView Is Nothing Then
Err.Raise 1000, “AutoThreeView”, “正面図の生成に失敗しました。パスまたはビュー名を確認してください。”
End If

‘ 7. 平面図(Top View)の配置(正面図の上方に投影配置)
‘ ※ CreateDrawViewFromModelView3 を使わず投影図として配置するのがベストプラクティス
‘ ここでは明示的にモデルビュー “Top” を指定して直交配置する
Dim topCoordX As Double, topCoordY As Double
topCoordX = baseCoordX
topCoordY = baseCoordY + (sheetHeight 0.25) ‘ 空間マージンを動的に確保

Dim swTopView As SldWorks.View
Set swTopView = swDraw.CreateDrawViewFromModelView3( _
modelPath, _
“Top”, _
topCoordX, _
topCoordY, _
0#)

‘ 8. 右側面図(Right View)の配置(正面図の右方に投影配置)
Dim rightCoordX As Double, rightCoordY As Double
rightCoordX = baseCoordX + (sheetWidth 0.25)
rightCoordY = baseCoordY

Dim swRightView As SldWorks.View
Set swRightView = swDraw.CreateDrawViewFromModelView3( _
modelPath, _
“Right”, _
rightCoordX, _
rightCoordY, _
0#)

MsgBox “三面図の自動配置が正常に完了しました。”, vbInformation, “完了”

Cleanup:
‘ 9. 確実なリソースの解放(メモリリーク防止の鉄則)
Set swFrontView = Nothing
Set swTopView = Nothing
Set swRightView = Nothing
Set swSheet = Nothing
Set swModelDocExt = Nothing
Set swModel = Nothing
Set swDraw = Nothing

‘ 10. 画面描画の復元
If Not swApp Is Nothing Then
Dim swActiveModel As SldWorks.ModelDoc2
Set swActiveModel = swApp.ActiveDoc
If Not swActiveModel Is Nothing Then
swActiveModel.Visible = True
swActiveModel.WindowRedraw
End If
End If

Exit Sub

ErrorHandler:
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“詳細: ” & Err.Description, vbCritical, “System Error”
Resume Cleanup
End Sub

—

3. シニアエンジニアが解説するコードの急所と極意

① `swModel.Visible = False` による劇的なパフォーマンス向上

大規模なアセンブリや複雑な形状を持つ部品の図面を作成する際、SolidWorksはビューが生成されるたびにグラフィックスの再計算と画面の再描画(Redraw)を実行する。これがマクロの実行時間を数倍〜数十倍に膨れ上がらせる主原因である。
処理の冒頭でモデルの可視性を一時的に無効化し、一連のAPI呼び出しを一気に処理した上で最後に `WindowRedraw` を叩く。この設計手法により、体感速度は劇的に改善される。

② COMオブジェクトのスコープと明示的解放(Memory Management)

VBAはガベージコレクションを持つモダン言語ではない。特にSolidWorks API(COMコンポーネント)を操作する場合、インスタンスの参照カウントが適切にデクリメントされないと、VBAのIDEを終了してもプロセス(`SLDWORKS.exe`)の背後にゾンビプロセスが残留するメモリリークを引き起こす。
コードの終端にある `Cleanup` ラベルにおいて、すべてのオブジェクト変数に `Nothing` を代入しているのは、プロ級のアーキテクトであれば当然に行うべき防衛的プログラミングの極意である。

③ ハードコーディングの排除と動的座標スケーリング

初心者が書くマクロの多くは、ビューを配置する座標に `0.2, 0.3` のような固定値を設定する。しかし、A4、A3、A1といった異なるシートサイズや、モデルのバウンディングボックスの大きさが変わった途端に、ビュー同士が重なり合ったり、シートからはみ出したりする致命的な欠陥を生む。
本コードでは、`swSheet.GetSize` から取得したシートの物理寸法(幅・高さ)を基準に係数を掛け合わせて座標を算出し、あらゆる図面フォーマットに対してスケーラブルに対応できる設計としている。

—

4. レガシー環境・システム間連携への拡張

このマクロを単体のVBAとして完結させるだけでは、真の自動化エンジニアとは言えない。
社内のPDMシステムやERP、あるいはExcelからのバッチ処理(外部起動型VBA / VB.NETコンソールアプリ)からこのロジックを呼び出す場合、ファイルパスの受け渡しを引数化するだけで、シームレスな上流システム連携が可能となる。

.net
‘ 【参考】VB.NET (COM Interop) による外部連携のイメージ
‘ VBAの限界を超える大規模システム統合の際は、VB.NETによる外出し実装へ移行せよ。
Public Sub CreateViewsExternal(ByVal swApp As SldWorks.SldWorks, ByVal modelPath As String)
Dim swModel As SldWorks.ModelDoc2 = CType(swApp.ActiveDoc, SldWorks.ModelDoc2)
Dim swDraw As SldWorks.DrawingDoc = CType(swModel, SldWorks.DrawingDoc)

‘ 同様のロジックを強固な例外処理(Try-Catch-Finally)と共に実装する
Try
swModel.Visible = False
‘ … ビュー配置処理 …
Catch ex As Exception
‘ ログ出力と適切なCOM解放
Finally
swModel.Visible = True
swModel.WindowRedraw()
End Try
End Sub

—

5. 結びにかえて

SolidWorks VBAによる図面自動化は、単なる「手作業の置き換え」ではない。それは、エンジニアリングの属人性を排除し、設計プロセスのスループットを極限まで高めるための戦略的投資である。

今回解説した `CreateDrawViewFromModelView3` の制御手法とメモリ管理の鉄則を血肉とし、あなたの現場のワークフローを真の自動化のステージへと引き上げてほしい。妥協なきコードだけが、エンジニアの時間を解放する。

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