こんにちは、チーフアーキテクトの私だ。
今回は、多くの現場でエンジニアが頭を悩ませる「マルチシート図面の動的生成と管理」について、実務に直結する極限の知見を授けよう。
何十ページにも及ぶプラントや大型機械の製品図面を、手作業で1枚ずつ作成し、プロパティを設定していく……。そんな不毛な作業に貴重なエンジニアリング時間を溶かしているチームが未だに散見される。これをVBAで完全自動化する。
今回は単に「シートを追加するコード」をばら撒くのではない。SolidWorks APIのライフサイクル、メモリ管理、そして実務で必ず直面する「予期せぬバグを完全に排除する堅牢な設計」の極意を叩き込む。
—
1. なぜ「手動」や「単純なマクロの記録」では破綻するのか?
SolidWorksの図面(`IDrawingDoc`)操作において、多くの初学者が陥る罠がある。
それは、「アクティブなドキュメントのコンテキスト(状態)に依存したコードを書くこと」だ。
「マクロの記録」を実行すると、以下のようなコードが出力されるはずだ。
‘ 悪夢のようなアンチパターン
SwApp.ActiveDoc.Extension.SelectByID2 …
この書き方は、画面の描画更新(UI)や選択状態(Selection Manager)に完全に依存している。少しでもユーザーが別のウィンドウをクリックしたり、フォーカスが外れたりした瞬間に、「ランタイムエラー 91: オブジェクト変数または With ブロック変数が設定されていません」という名のクラッシュ祭りが開幕する。
プロダクションコードに必要なのは、UIに依存せず、メモリ上でオブジェクトを確実に直叩きする「コンテキストフリーな設計」だ。
—
2. 図面シート生成の要:`NewSheet` と `SetProperties` の正しい作法
新しくシートを追加し、用紙サイズや投影法(第角法)をプログラム制御するためには、以下の2つのAPIを正確に連携させる必要がある。
1. `IDrawingDoc::NewSheet3` (または `NewSheet5`)
- シート名、用紙規格、テンプレート、幅、高さを指定してシートを作成する。
2. `ISheet::SetProperties`
- 作成(または取得)したシートオブジェクトに対し、尺度、用紙サイズ、標準(第1角法/第3角法)を再定義する。
ここで重要な知見として、「シート作成時のデフォルトテンプレート依存性を断ち切る」こと。テンプレート側に埋め込まれた余計なプロパティに引っかからないよう、生成直後に必ず `SetProperties` で明示的に上書きするのがプロの現場の鉄則だ。
—
3. 【プロダクションコード】マルチシート一括生成エンジン
外部のCSVやデータベース、あるいは社内の設計情報リストからデータを取得し、A3/A4混載のマルチシート図面を秒速で構築する実用コードを提示する。
エラーハンドリング、オブジェクトの解放、画面描画の凍結(パフォーマンス最適化)をすべて実装した、そのまま現場に投入できるレベルのコードだ。
Option Explicit
‘ ==============================================================================
‘ 業務自動化プロフェッショナル向け: マルチシート動的生成エンジン
‘ ==============================================================================
Sub GenerateMultiSheetDrawing()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim swSheet As SldWorks.Sheet
‘ パフォーマンス向上と予期せぬUI干渉を防ぐためのフラグ退避
Dim bRet As Boolean
‘ 1. アプリケーションインスタンスの確実な取得
Set swApp = Application.SldWorks
If swApp Is Nothing Then
MsgBox “SolidWorksが起動していません。”, vbCritical, “致命的エラー”
Exit Sub
End5 Sub
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。図面を開いてください。”, vbExclamation, “警告”
Exit Sub
End If
‘ ドキュメントタイプが図面(Drawing = 3)か厳格にチェック
If swModel.GetType() <> swDocDRAWING Then
MsgBox “このマクロは図面ドキュメントでのみ実行可能です。”, vbCritical, “型不一致エラー”
Exit Sub
End If
Set swDraw = swModel
‘ 2. 爆速化の極意:画面描画の凍結 (UI Redraw Suspend)
‘ これを行わないと、シートが1枚追加されるたびに画面が再描画され、処理が10倍以上遅くなる。
swModel.LockRefresh
On Error GoTo ErrorHandler
‘ — ここからデータ駆動のシート生成ループ(例として3枚のシートを動的生成) —
Dim sheetData(2, 3) As String
‘ sheetData(index, 0)=シート名, (index, 1)=用紙サイズ(1:A4, 3:A3等), (index, 2)=尺度分母
sheetData(0, 0) = “COVER_SHEET”: sheetData(0, 1) = “12”: sheetData(0, 2) = “1” ‘ A4縦 (swDrivSheetSize_A4_Portrait = 12 等)
sheetData(1, 0) = “ASSEMBLY_01”: sheetData(1, 1) = “3”: sheetData(1, 2) = “2” ‘ A3横 (swDrivSheetSize_A3_Landscape = 3 等)
sheetData(2, 0) = “PARTS_LIST”: sheetData(2, 1) = “12”: sheetData(2, 2) = “1” ‘ A4縦
Dim i As Long
For i = 0 To UBound(sheetData, 1)
Dim targetSheetName As String
targetSheetName = sheetData(i, 0)
‘ 既に同名シートが存在するかチェックする関数を通すのがベストだが、
‘ ここでは新規作成ロジックにフォーカスする
‘ NewSheet3 引数:
‘ Name, PaperSize, TemplateSize, Scale1, Scale2,
‘ FirstAngle(True=第1角法, False=第3角法), TemplateName, Width, Height, CustomProperties
bRet = swDraw.NewSheet3( _
targetSheetName, _
CLng(sheetData(i, 1)), _
0, _
1, CLng(sheetData(i, 2)), _
False, _ ‘ 第3角法 (Third Angle)
“”, _ ‘ 既定のテンプレートを使用
0.297, 0.21, _ ‘ 幅と高さ (A3などの場合は適切に変更)
“” _
)
If Not bRet Then
Err.Raise vbObjectError + 1000, “NewSheet”, “シート ‘” & targetSheetName & “‘ の生成に失敗しました。”
End If
‘ 生成したシートのオブジェクトを取得し、プロパティを確実に再適用・固定化
Set swSheet = swDraw.GetCurrentSheet()
If Not swSheet Is Nothing Then
‘ 例:プロパティの微調整が必要な場合はここでISheetメソッドを叩く
‘ swSheet.SetProperties(…)
End If
Next i
‘ 3. 終了処理とクリーンアップ
swModel.UnlockRefresh
swModel.GraphicsRedraw2
MsgBox “マルチシートの動的生成が正常に完了しました。”, vbInformation, “完了”
Exit Sub
ErrorHandler:
‘ 異常系でも必ず画面描画のロックを解除すること。これを怠るとSolidWorksがフリーズしたままになる。
swModel.UnlockRefresh
swModel.GraphicsRedraw2
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “異常終了”
End Sub
—
4. 保守性と拡張性を高めるアーキテクチャの心得
現場でこのシステムを運用していくにあたり、以下の3点を心掛けてほしい。
1. 「マジックナンバー」の排除
用紙サイズ(`swDrivSheetSize_e`)や投影法(`swDrivSymbol_e`)は、コード内に直書き(`3`や`12`など)せず、SolidWorksの型ライブラリ(Type Library)が提供する列挙体をそのまま使用するか、独自の定数定義モジュールに切り出せ。将来のAPI仕様変更に対する耐性が跳ね上がる。
2. データベース・CSV連携への布石
上記のコードでは配列(`sheetData`)でハードコーディングしているが、実務ではここを `ADODB.Recordset` や `Scripting.FileSystemObject` による外部CSV読み込みに差し替えるだけだ。データ構造とUI描画ロジックを完全に分離(SoC: Separation of Concerns)せよ。
3. エラー時の「デッドロック解除」の徹底
コード内でも強調したが、`LockRefresh` を使った場合は、必ず `On Error GoTo` を経由して `UnlockRefresh` を通るパスを保証すること。これを忘れると、デバッグ中にSolidWorksごと強制終了するリスクを抱えることになる。
—
総括
図面シートの動的生成は、単なる「お絵描きマクロ」の延長ではない。製品データの構造をドキュメントという形に変換する、極めてロジカルなアーキテクチャ設計だ。
オブジェクトのライフサイクルを理解し、無駄なUI描画を排し、堅牢なエラーハンドリングを仕込む。この基盤さえあれば、何百枚のシートを持つ巨大な図面群であっても、あなたのVBAプログラムは一瞬で、かつエラー一切なしで完遂するだろう。
現場の生産性を爆発的に引き上げる次世代の自動化基盤を、今すぐ君の手で実装してほしい。健闘を祈る。
