【SolidWorks VBA】マルチシート図面自動生成の極意:`NewSheet4`と`SetProperties2`で構築する堅牢な全自動レイアウトエンジン
単一の3Dモデルから、用途に応じた用紙サイズ(A3・A4)や尺度、投影図の構成を切り替え、複数シートの図面を一括生成する——。実務において最も要望が強く、そして最も挫折しやすいのが「図面シート管理の自動化」です。
ネット上に転がっているサンプルコードを切り貼りしただけのマクロは、シートを追加した瞬間にグラフィックスの再描画で極端に低速化したり、アクティブシートのコンテキストを見失って意図しないシートに図面ビューが配置されたり、最悪の場合はSolidWorksごと強制終了します。
本記事では、プログラクション環境に耐えうる「バグの起きない堅牢なマルチシート図面自動生成エンジン」の設計思想と実装を解説します。
—
1. 素人コードが陥る3つの致命的落とし穴
なぜ一般的なSolidWorks VBAスクリプトは、2シート以上の処理で破綻するのか?
チーフアーキテクトの視点から、原因を徹底的に解剖します。
① 画面描画(Redraw)の無駄打ちなよるパフォーマンス崩壊
`IDrawingDoc.NewSheet4`を呼び出すたび、SolidWorksは画面上の全ビュー、寸法、アノテーション、ツリー構造を完全再描画(Rebuild/Redraw)しようとします。シート数が増えるにつれ処理時間は幾何級数的に増大します。
プロの設計では、処理中のグラフィックス更新およびフィーチャーマネージャーの再描画を完全に凍結(フリーズ)させます。
② シートアクティベーションとコンテキストの誤認
SolidWorks APIでは、「現在アクティブなシート(Active Sheet)」と「メモリ上で参照を保持しているシート(Sheet Object)」が分離しています。
`Sheet.SetProperties2`を実行する際、対象のシートが完全にアクティブ化されていない場合、変更が無視されるか、直前にアクティブだった別シートのプロパティを上書き破壊します。
③ 用紙フォーマット(.slddrt)と図面テンプレート(.drwdot)の混同
`NewSheet4`の引数に指定すべきは、図面全体の枠組みである`ドキュメントテンプレート(.drwdot)`ではなく、用紙サイズや表題欄が定義された`シートフォーマット(.slddrt)`です。ここを誤ると、シートは追加されても白紙のまま、あるいはスケール設定が無視されるというバグを引き起こします。
—
2. 堅牢なマルチシート生成のアーキテクチャ
信頼性の高い自動生成エンジンを構築するため、処理を以下のフェーズに分離したパイプライン構造を採用します。
[3Dモデル取得]
│
▼
[描画・イベントの一時凍結] ── (パフォーマンスの劇的向上)
│
▼
[新規図面ドキュメントの生成]
│
▼
[シート生成ループ (NewSheet4 & SetProperties2)]
├─ Sheet1: A3横 / 全体配置図 (尺度 1:10, 第3角法)
└─ Sheet2: A4縦 / 詳細部品図 (尺度 1:2, 第3角法)
│
▼
[モデルビューの自動配置 & スケール同期]
│
▼
[描画凍結の解除 & 一括再計算 (Rebuild)]
—
3. プロダクショングレードのVBAコード例
以下は、実務の現場でそのまま組み込んで動作する、エラー処理およびパフォーマンス最適化済みの完全なVBAコードです。
Option Explicit
‘ ==============================================================================
‘ 機能: 3DモデルからA3/A4のマルチシート図面を自動生成する堅牢なマクロ
‘ 設計方針:
‘ 1. 画面描画の非表示化による高速化
‘ 2. シートプロパティの完全制御 (SetProperties2)
‘ 3. 例外発生時の安全なリソース解放と画面更新の復元
‘ ==============================================================================
‘ — 設定値の定数定義 (環境に合わせてパスを変更) —
Private Const SHEET_FORMAT_A3_LAND As String = “C:\ProgramData\SolidWorks\SOLIDWORKS 2023\lang\japanese\sheetformat\a3 – iso.slddrt”
Private Const SHEET_FORMAT_A4_PORT As String = “C:\ProgramData\SolidWorks\SOLIDWORKS 2023\lang\japanese\sheetformat\a4 – iso.slddrt”
Public Sub CreateMultiSheetDrawing_Production()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim swModelDocExt As SldWorks.ModelDocExtension
Dim modelPath As String
Dim boolStatus As Boolean
Dim longErrors As Long
Dim longWarnings As Long
‘ 1. SolidWorksインスタンスの取得
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
‘ 3Dモデルが開かれているかチェック
If swModel Is Nothing Then
MsgBox “対象となる3Dモデル(パーツまたはアセンブリ)を開いてから実行してください。”, vbExclamation, “エラー”
Exit Sub
End If
If swModel.GetType = swDocDRAWING Then
MsgBox “3Dモデルのウィンドウをアクティブにして実行してください。”, vbExclamation, “エラー”
Exit Sub
End If
modelPath = swModel.GetPathName
If modelPath = “” Then
MsgBox “モデルが保存されていません。一度保存してから再実行してください。”, vbExclamation, “エラー”
Exit Sub
End If
‘ — パフォーマンス最適化:描画・画面更新の凍結 —
On Error GoTo ErrorHandler
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDispStateUpdate, False
swApp.EnableGraphicsUpdate = False
‘ 2. 新規図面ドキュメントの作成 (デフォルトテンプレートを使用)
Dim defaultTemplate As String
defaultTemplate = swApp.GetUserPreferenceStringValue(swUserPreferenceStringValue_e.swDefaultTemplateDrawing)
Set swDraw = swApp.NewDocument(defaultTemplate, swDwgPaperA3size, 0, 0)
If swDraw Is Nothing Then Err.Raise vbObjectError + 513, , “新規図面の作成に失敗しました。”
Set swModelDocExt = swDraw.Extension
‘ ==========================================================================
‘ 【Sheet 1】 A3 横置き / 全体レイアウトシートの構築
‘ ==========================================================================
Dim swSheet1 As SldWorks.Sheet
Set swSheet1 = swDraw.GetCurrentSheet
swSheet1.SetName “Sheet1_Overall”
‘ シートプロパティの設定 (A3, 尺度1:10, 第3角法)
‘ SetProperties2(PaperSize, TemplateIn, Scale1, Scale2, FirstAngle, Width, Height, PropertyViewName)
boolStatus = swSheet1.SetProperties2( _
swDwgPaperA3size, _
swDwgTemplateCustom, _
1, 10, _
False, _
0.42, 0.297, _
“”, _
SHEET_FORMAT_A3_LAND, _
True _
)
‘ 図面ビューの配置 (等角図: Isometric)
Dim swView1 As SldWorks.View
Set swView1 = swDraw.CreateDrawViewFromModelView3(modelPath, “Isometric”, 0.15, 0.15, 0)
If Not swView1 Is Nothing Then
‘ シート尺度に従う設定
swView1.UseSheetScale = True
End If
‘ ==========================================================================
‘ 【Sheet 2】 A4 縦置き / 詳細シートの新規追加
‘ ==========================================================================
Dim boolSheetCreated As Boolean
‘ NewSheet4(Name, PaperSize, TemplateIn, Scale1, Scale2, FirstAngle, TemplateName, Width, Height, PropertyViewName, ZoneState)
boolSheetCreated = swDraw.NewSheet4( _
“Sheet2_Detail”, _
swDwgPaperA4size, _
swDwgTemplateCustom, _
1, 2, _
False, _
SHEET_FORMAT_A4_PORT, _
0.21, 0.297, _
“”, _
swHeaderQuery_e.swHeaderQuery_None _
)
If Not boolSheetCreated Then Err.Raise vbObjectError + 514, , “Sheet2の作成に失敗しました。”
‘ コンテキストを確実に維持するため対象シートを明示的にアクティブ化
boolStatus = swDraw.ActivateSheet(“Sheet2_Detail”)
Dim swSheet2 As SldWorks.Sheet
Set swSheet2 = swDraw.GetCurrentSheet
‘ プロパティの確実な再設定(A4縦、尺度1:2)
boolStatus = swSheet2.SetProperties2( _
swDwgPaperA4size, _
swDwgTemplateCustom, _
1, 2, _
False, _
0.21, 0.297, _
“”, _
SHEET_FORMAT_A4_PORT, _
True _
)
‘ 図面ビューの配置 (正面図: Front)
Dim swView2 As SldWorks.View
Set swView2 = swDraw.CreateDrawViewFromModelView3(modelPath, “Front”, 0.105, 0.15, 0)
If Not swView2 Is Nothing Then
swView2.UseSheetScale = True
End If
‘ ==========================================================================
‘ 終了処理:再計算と画面描画の解凍
‘ ==========================================================================
‘ Sheet1をアクティブに戻して保存表示を整える
swDraw.ActivateSheet(“Sheet1_Overall”)
‘ 図面全体を強制リビルド
swModelDocExt.Rebuild swRebuildAll
CleanUp:
‘ 描画の復元 (必ずクリーンアップ領域で実行)
swApp.EnableGraphicsUpdate = True
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDispStateUpdate, True
‘ 参照の解放
Set swView1 = Nothing
Set swView2 = Nothing
Set swSheet1 = Nothing
Set swSheet2 = Nothing
Set swDraw = Nothing
Set swModel = Nothing
Set swApp = Nothing
MsgBox “マルチシート図面の自動生成が完了しました。”, vbInformation, “成功”
Exit Sub
ErrorHandler:
Dim errDesc As String
errDesc = Err.Description
‘ エラー時も必ず画面更新をONに戻す(SolidWorksがフリーズしたように見えるのを防ぐ)
swApp.EnableGraphicsUpdate = True
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDispStateUpdate, True
MsgBox “エラーが発生しましたため処理を中断します。” & vbCrLf & errDesc, vbCritical, “致命的エラー”
Resume CleanUp
End Sub
—
4. チーフアーキテクトによるAPI解剖と解説
上記のコードには、単なるリファレンスには載っていない実務上の知恵が詰まっています。重要ポイントを解説します。
① `NewSheet4` と `SetProperties2` の二重適用による堅牢化
`NewSheet4` メソッドは引数としてテンプレートパスや尺度を受け取りますが、APIの内部挙動として指定した`.slddrt`(シートフォーマット)内の用紙サイズ設定と、引数で渡した`Width` / `Height`が衝突した場合、フォーマット側の設定が勝つという不具合に近い挙動を見せることがあります。
そのためコードでは、`NewSheet4` でシートを追加した直後に `ActivateSheet` で確実にそのシートへスイッチし、`Sheet.SetProperties2` を明示的に叩く設計にしています。これにより、用紙の向き(縦横)、尺度、投影法(第3角法)が100%意図通りに適用されます。
② ダブル型(メートル単位)による厳密な座標と寸法の指定
SolidWorks API内部での長さ・座標はすべてメートル(m)単位です。
- A3横: 幅 `0.42` m, 高さ `0.297` m
- A4縦: 幅 `0.21` m, 高さ `0.297` m
`CreateDrawViewFromModelView3` の位置指定(`X`, `Y`)もメートル単位で行う必要があります。A4縦(幅0.21m)の中央に配置したい場合は、`X = 0.105` を指定するのが幾何学的な正解です。
③ エラーハンドラにおける描画フリーズの強制解除
最もやってはいけない実装は、`swApp.EnableGraphicsUpdate = False` を実行したままマクロがエラーで落ちることです。これが起きるとSolidWorksのUIが完全にフリーズし、ユーザーはタスクマネージャーから強制終了するしかなくなります。
コード例のように、`On Error GoTo ErrorHandler` を仕込み、正常終了・異常終了のどちらのルートを通っても必ず `CleanUp` 節で `EnableGraphicsUpdate = True` を通過させる構造(Try-FinallyパターンのVBA的実装)が必須です。
—
5. PDM・データベース連携を見据えた拡張設計
この自動化エンジンを企業向けのバッチ処理システム(PDM連携やCSVからの自動一括図面生成)へ拡張する場合、以下のアーキテクチャ設計を推奨します。
1. テンプレートパスの動的解決
コード内に `.slddrt` のパスをハードコーディングするのは避け、設定ファイル(JSON/XML/INI)またはSolidWorksのシステムオプション(`swUserPreferenceStringValue_e.swDefaultTemplateSheetFormat`)から動的に取得する構造にします。
2. プロパティ(Custom Properties)の非同期伝播
`SetProperties2` の最後の引数 `PropertyViewName` にビュー名(例: `”図面ビュー1″`)を指定することで、「その図面ビューに配置された3Dモデルのカスタムプロパティ(部品番号、材質、設計者など)」を表題欄のテキストリンクとして流し込むことが可能です。
マルチシート自動化を行う際は、各シートの主たる図面ビューの名前を把握し、`SetProperties2` で正確に紐付ける設計を行ってください。
—
6. まとめ
SolidWorks VBAによる図面自動化は、単に「操作を記録して再生する」レベルから脱却し、オブジェクトのライフサイクル、描画更新のコスト、コンテキストの活性化を正しく制御することで初めて現場で使えるツールになります。
- `NewSheet4` と `SetProperties2` の2重適用で確実にプロパティを固定する
- `EnableGraphicsUpdate` で再描画を完全に止め、爆速化する
- エラーハンドリングで描画凍結解除を保証し、落とさないシステムを作る
この原則を守り、保守性の高い全自動レイアウトエンジンを構築してください。
