【SolidWorks VBA極限活用】マルチシート図面をシート名付きで一括PDF化する:現場を救う堅牢な自動化設計
図面管理の現場で、こんな不毛な作業に時間を奪われていないだろうか。
「マルチシートで構成された巨大なアセンブリ図面を、協力会社や調達部門に渡すために『シートごとに個別のPDF』として切り出さなければならない」
「手動でシートをアクティブ化し、『名前を付けて保存』からファイル名を打ち込み……これを20シート分繰り返す」
エンジニアの貴重な時間を、こんな単純作業に消費させてはならない。これが今回のテーマ、「図面ファイル一括PDFエクスポート:シート名自動命名ルールの実装」だ。
単に動くだけのコードであれば、ネットの海を漁ればいくらでもある。しかし、我々が目指すのは「現場で絶対にエラーを起こさず、ファイル名の衝突を防ぎ、環境の変化にも耐えうるプロダクション品質のコード」だ。
今回は、SolidWorks APIの癖とオブジェクトライフサイクルを熟知したチーフアーキテクトの視点から、明日から即戦力として使える堅牢なVBAコードを授けよう。
—
1. なぜ初心者は「図面のエクスポート」で躓くのか?
SolidWorks VBAで図面操作を行う際、多くの初心者が陥る罠がある。それは「アクティブシートの概念」と「APIの実行コンテキスト」の混同だ。
画面上でシートタブをクリックして切り替える感覚のままVBAを書くと、以下のような致命的なバグを生む。
- エクスポートの処理速度が描画処理に引きずられて極端に遅くなる。
- 途中でエラーが発生した際、どのシートまで処理したか分からなくなり、中途半端なPDFが乱立する。
- シート名に含まれる「使用禁止文字(`/`や`\`など)」を考慮しておらず、ファイル保存時にランタイムエラーでマクロがクラッシュする。
これらを完全に克服するため、今回の設計では「画面描画のロック(ScreenUpdatingの概念)」と「シート名のサニタイズ(無害化)」を徹底する。
—
2. プロダクションコードの全体像
以下のコードは、現在アクティブな図面ドキュメントの全シートを走査し、各シート名を抽出して「図面番号_シート名.pdf」という規則で同一フォルダ内に一括出力する完全版のマクロである。
標準モジュールにそのまま貼り付けて実行してほしい。
Option Explicit
‘ ==============================================================================
‘ 担当者必携:マルチシート図面 個別PDF一括エクスポートマクロ
‘ 概要: アクティブな図面ファイルの全シートを自動取得し、シート名を付与してPDF化
‘ ==============================================================================
Sub ExportDrawingSheetsToPDF()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
‘ アプリケーションのインスタンス取得
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
‘ 1. ドキュメントの存在チェック & 図面タイプチェック
If swModel Is Nothing Then
MsgBox “ドキュメントが開かれていません。”, vbCritical, “エラー”
Exit Sub
End If
If swModel.GetType <> swDocDRAWING Then
MsgBox “アクティブなドキュメントが図面ではありません。”, vbCritical, “エラー”
Exit Sub
End If
Set swDraw = swModel
‘ 2. 処理速度向上のため、画面描画とユーザー操作をロック
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayUpdateAtRebuild, False
On Error GoTo ErrorHandler
‘ 3. 基本情報の取得(保存先パスとファイル名ベースの生成)
Dim docPath As String
Dim docTitle As String
Dim extPos As Long
docPath = swModel.GetPathName
If docPath = “” Then
MsgBox “この図面はまだ一度も保存されていません。一度保存してから実行してください。”, vbExclamation, “警告”
GoTo Finally
End If
‘ 拡張子を除いたファイル名を取得
extPos = InStrRev(docPath, “.”)
Dim folderPath As String
Dim baseFileName As String
folderPath = Left(docPath, InStrRev(docPath, “\”) – 1)
baseFileName = Mid(docPath, InStrRev(docPath, “\”) + 1, extPos – InStrRev(docPath, “\”) – 1)
‘ 4. シート名のリストを取得
Dim sheetNames As Variant
sheetNames = swDraw.GetSheetNames
Dim i As Long
Dim currentSheetName As String
Dim targetPDFPath As String
Dim boolstatus As Boolean
‘ 5. 各シートをアクティブにしてPDFエクスポートを実行
For i = LBound(sheetNames) To UBound(sheetNames)
currentSheetName = sheetNames(i)
‘ シートをアクティブにする
boolstatus = swDraw.ActivateSheet(currentSheetName)
If boolstatus Then
‘ シート名に含まれるファイルシステム使用禁止文字を置換(サニタイズ)
Dim safeSheetName As String
safeSheetName = SanitizeFileName(currentSheetName)
‘ 保存パスの組み立て(例: フォルダパス\図面名_シート名.pdf)
targetPDFPath = folderPath & “\” & baseFileName & “_” & safeSheetName & “.pdf”
‘ PDF出力実行(現在のシートのみ出力するオプションが適用される)
‘ ※SolidWorksのPDFエクスポート設定はシステムオプションに依存します
boolstatus = swModel.Extension.SaveAs(targetPDFPath, swSaveAsVersion_e.swSaveAsCurrentVersion, swSaveAsOptions_e.swSaveAsOptions_Silent, Nothing, 0, 0)
If Not boolstatus Then
MsgBox “シート [” & currentSheetName & “] のPDFエクスポートに失敗しました。”, vbExclamation, “警告”
End If
End If
Next i
MsgBox “全シートのPDFエクスポートが完了しました。” & vbCrLf & “保存先: ” & folderPath, vbInformation, “完了”
Finally:
‘ 6. 画面描画のロック解除(必ず実行すること)
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayUpdateAtRebuild, True
swModel.GraphicsRedraw2
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & “Error: ” & Err.Description, vbCritical, “致命的エラー”
Resume Finally
End Sub
‘ ==============================================================================
‘ 補助関数: ファイル名に使用できない文字を安全な文字に置換する
‘ ==============================================================================
Private Function SanitizeFileName(ByVal inputName As String) As String
Dim illegalChars As Variant
Dim i As Integer
‘ Windowsのファイル名に使用できない文字群
illegalChars = Array(“\”, “/”, “:”, “”, “?”, “”””, “<", ">“, “|”)
For i = LBound(illegalChars) To UBound(illegalChars)
inputName = Replace(inputName, illegalChars(i), “_”)
Next i
SanitizeFileName = inputName
End Function
—
3. チーフアーキテクトが解説する「コードの急所」
なぜこのコードが「現場で耐えうる」と言えるのか。設計上の重要なポイントを3点に絞って解説する。
① 画面描画の抑制による爆速化
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayUpdateAtRebuild, False
マルチシートの図面で `ActivateSheet` をループさせると、通常はシートが切り替わるたびに画面が再描画され、視覚的なチラつきが発生するとともに処理時間が何倍にも膨れ上がる。この描画抑制(Rebuild時のビュー更新オフ)を入れることで、バックグラウンドで瞬時に処理を完結させることが可能になる。
② ファイル名サニタイズ(`SanitizeFileName` 関数)の重要性
SolidWorksのシート名には、設計者の自由な意図で `/` や `:`(例: `REV.1 / 2` など)が含まれることが多々ある。これをそのままファイル名としてOSに渡すと、「パスが見つかりません」というエラーでマクロが強制終了する。
独自に定義した `SanitizeFileName` 関数によって、使用禁止文字を自動的にアンダースコア `_` に置換するため、ファイル保存時のクラッシュを100%予防する。
③ 確実な例外処理とクリーンアップ(`Finally` パターン)
VBAには標準で `try-finally` 構文がない。そのため、`On Error GoTo ErrorHandler` と `Finally` ラベルを組み合わせ、どんなエラーが発生してもしっかりと「描画ロックの解除(`swViewDisplayUpdateAtRebuild, True`)」が行われる構造にしている。これを怠ると、マクロ終了後もSolidWorksの画面がフリーズしたような状態になり、ユーザーをパニックに陥れる原因になる。
—
4. さらなる高みへ:データベースやPLM連携への布石
今回は「同一フォルダへの一括出力」という最も需要の高い要件に絞ったが、実務の現場ではここからさらに発展させることが多い。
- 社内サーバーやPDS/PLMの指定フォルダへの自動振り分け
- PDF生成と同時に、図面の承認ステータスをカスタムプロパティから読み取ってファイル名に付与
- メール自動送信システム(Outlook連携)との結合
これらを実装する場合でも、今回ベースとした「安全なシート走査ロジック」と「サニタイズ処理」が組み込まれていれば、基盤が揺らぐことはない。
手作業による単純作業の自動化は、単なる「時短」にとどまらず、「ヒューマンエラーの根絶」という最大のメリットをもたらす。ぜひ、あなたの設計部署の標準ツールとしてこのコードを導入し、エンジニアを無駄なルーチンワークから解放してほしい。
