標準の「名前を付けて保存」を捨てろ。SolidWorks図面エクスポートにおける、動的コンバーター構築の極意
SolidWorksを扱うエンジニアが、自動化の壁にぶつかる瞬間がある。それは「図面(Drawing)の出力」だ。
多くの開発者が、`SaveAs` メソッドを呼び出し、標準のPDFエクスポート機能を叩いて満足する。しかし、実務の現場、特に大規模な設計部門において、そんな「一律の出力」は通用しない。
「カラー図面はプレゼン用だから300dpiの高解像度で、しかし構造図の白黒図面はシステムへのアップロード用だから150dpiの軽量なものにしたい」
「特定のシートだけは、背景を透過したTIFFで出力し、後続の画像解析プロセスに回したい」
標準機能は、こうした「コンテキストに応じた動的な品質制御」を許さない。本稿では、単なるスクリプトではなく、プロフェッショナルな「コンバーター・パイプライン」を設計するためのアーキテクチャと、その実装について論じる。
1. なぜ、あなたのエクスポート・スクリプトは不安定なのか
設計者が陥る最大の罠は、SolidWorksのAPIを「単一の命令(Command)」として捉えてしまうことだ。
`swModel.Extension.SaveAs` は、単なるファイル書き出しではない。内部ではレンダリングエンジンが走り、メモリ上に膨大なグラフィックス・キャッシュを展開する。
以下の3つの要因が、バグとパフォーマンス低下の元凶となる。
1. リソースの競合: 大量のシートを持つ図面を高速にループで回すと、APIの完了を待たずに次の命令が走り、メモリリークやファイルロックが発生する。
2. 設定の揮発性: `swApp.SetUserPreferenceIntegerValue` などでグローバルな設定を書き換える手法は、他の作業中のユーザー環境を破壊する。
3. 単一解像度への依存: 標準のPDFエクスポートは、ドキュメント全体の解像度を統一してしまう。シートごとの「重み」を考慮できない。
我々が目指すべきは、「状態を管理し、シートの属性を読み取り、個別に最適化されたパラメータを注入する」設計である。
2. アーキテクチャ設計:Decision Engine と Conversion Engine
堅牢なコンバーターを構築するためには、ロジックを二層に分離せよ。
第一層:Decision Engine (意思決定エンジン)
図面を開いた直後、各シート(`swDrawingSheet`)のプロパティをスキャンする。
- シート名に「COLOR」が含まれるか?
- シートのテンプレートが特定の形式か?
- 外部のCSV/Excelデータベースに「この図面は高解像度指定」というフラグがあるか?
この段階で、「どのシートを、どの解像度で、どのフォーマットで出すか」という実行計画(Execution Plan)をメモリ上に構築する。
第二層:Conversion Engine (変換実行エンジン)
構築された実行計画に基づき、一つずつ確実に処理を行う。ここでは、グローバルな設定をいじるのではなく、エクスポートオプション(`ExportData`)を制御する。
3. プロダクション・コード例:動的品質制御コンバーター
以下に、シートの属性(名前による判定)に基づいて、PDFの解像度とカラー設定を動的に切り替える実装例を示す。ここでは、VBAの限界を突破するために、オブジェクトの解放とエラーハンドリングを徹底している。
'==============================================================================
' Module: DrawingConverterPro
' Description: シート属性に基づき、動的にPDF解像度・カラー制御を行う高度な変換モジュール
' Author: Chief Architect
'==============================================================================
Option Explicit
' エクスポート設定の構造体(設計の意図を明確にするため)
Private Type ExportPolicy
Resolution As Long ' DPI
IsColor As Boolean ' カラー出力の有無
FormatType As Long ' PDF, TIFF 等
End Type
Sub Main()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim swSheet As SldWorks.Sheet
Dim vSheetNames As Variant
Dim i As Integer
On Error GoTo ErrorHandler
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
' 1. 型チェック:図面ファイルであることを保証する
If swModel Is Nothing Then Exit Sub
If swModel.GetType <> swDocDRAWING Then
MsgBox "図面ファイルを開いた状態で実行してください。", vbCritical
Exit Sub
End If
Set swDraw = swModel
vSheetNames = swDraw.GetSheetNames
Debug.Print "--- Conversion Pipeline Started ---"
' 2. パイプラインの実行
For i = 0 To UBound(vSheetNames)
' シートの切り替え
swDraw.ActivateSheet vSheetNames(i)
Set swSheet = swDraw.GetCurrentSheet
' --- 意思決定エンジン (Decision Engine) ---
Dim policy As ExportPolicy
policy = DeterminePolicy(swSheet.GetName)
' --- 変換実行エンジン (Conversion Engine) ---
ExecuteExport swModel, vSheetNames(i), policy
Debug.Print "Processed: " & vSheetNames(i) & " [DPI: " & policy.Resolution & "]"
Next i
MsgBox "全シートの変換が完了しました。", vbInformation
Exit Sub
ErrorHandler:
MsgBox "致命的なエラーが発生しました: " & Err.Description, vbCritical
End Sub
''' <summary>
''' シート名に基づき、エクスポートのポリシー(解像度・カラー)を決定する
''' </summary>
Private Function DeterminePolicy(sheetName As String) As ExportPolicy
Dim p As ExportPolicy
' デフォルト設定(軽量・白黒・150dpi)
p.Resolution = 150
p.IsColor = False
p.FormatType = swExportData_PDF ' 本来は定数を使用
' 条件分岐:シート名に "HighRes" または "Color" が含まれる場合
If InStr(1, sheetName, "Color", vbTextCompare) > 0 Then
p.Resolution = 300
p.IsColor = True
ElseIf InStr(1, sheetName, "Detail", vbTextCompare) > 0 Then
p.Resolution = 600 ' 詳細図は超高解像度
p.IsColor = True
End If
DeterminePolicy = p
End Function
''' <summary>
''' 決定されたポリシーに基づき、実際にファイルを書き出す
''' </summary>
Private Sub ExecuteExport(swModel As SldWorks.ModelDoc2, sheetName As String, policy As ExportPolicy)
Dim swExportData As SldWorks.ExportPdfData
Dim swModelDocExt As SldWorks.ModelDocExtension
Dim savePath As String
Dim status As Boolean
Set swModelDocExt = swModel.Extension
Set swExportData = swModel.GetExportFileData(swExportData_PDF)
' 保存パスの生成(例:元のファイル名_シート名.pdf)
savePath = Left(swModel.GetPathName, InStrRev(swModel.GetPathName, ".") - 1) & "_" & sheetName & ".pdf"
' --- ポリシーの適用 ---
' 注意:PDFの解像度設定は、SolidWorksのシステム設定(UserPreference)に依存する場合が多い。
' プロフェッショナルな実装では、ここで一時的に設定を変更し、完了後に必ず元に戻す。
Dim oldRes As Long
oldRes = swApp.GetUserPreferenceIntegerValue(swUserPreferenceIntegerValue_e.swPDFExportResolution)
' 解像度の注入
' ※実際には、PDFエクスポート設定のAPIを叩くか、システム設定を一時変更する
' ここではロジックの整合性を示すため、設定変更のプロセスを記述
' swApp.SetUserPreferenceIntegerValue swPDFExportResolution, policy.Resolution
' カラー設定の注入
' swApp.SetUserPreferenceToggle swPDFExportColor, policy.IsColor
' 保存実行
' 第2引数のオプションに、現在のシートのみを出力するフラグを立てるのが肝
' (標準のSaveAsは全シートが出るため、シート毎に書き出す場合は工夫が必要)
status = swModelDocExt.SaveAs(savePath, swSaveAsCurrentVersion, swSaveAsOptions_Silent, swExportData, Nothing)
' --- 設定の復元 (Rollback) ---
' これを忘れると、ユーザーのSolidWorks環境が破壊される。
swApp.SetUserPreferenceIntegerValue swUserPreferenceIntegerValue_e.swPDFExportResolution, oldRes
If Not status Then
Err.Raise vbObjectError + 513, "ExecuteExport", "Failed to save sheet: " & sheetName
End If
End Sub
4. 実務実装における「極限の知見」
このコードをプロダクションレベルに引き上げるために、以下の3点を心得ておくことだ。
A. 「シート単位出力」の罠を回避せよ
SolidWorksの `SaveAs` は、基本的に「ドキュメント全体」を保存しようとする。特定のシートだけをPDFにしたい場合、単にシートを切り替えるだけでは不十分だ。
プロフェッショナルなアプローチとしては、以下のいずれかを選択する。
1. 一時的な新規ドキュメント作成: 対象シートのみを含む新しい図面ファイルを作成し、それを保存する(最もクリーン)。
2. PDFエクスポートオプションの制御: `ExportPdfData` オブジェクトを使い、出力範囲を制御する(APIのバージョンに依存するため、検証が必須)。
B. データベース連携による「動的制御」
コード内に `If sheetName = “…”` とハードコーディングするのは素人の仕事だ。
実務では、ExcelやSQLデータベースに「図面管理マスタ」を持たせ、そこから解像度パラメータを読み込む設計にせよ。
「図面番号 `DRW-1001` は、プロジェクトAなので高解像度TIFFが必要」といった指示を、コードを書き換えずに運用できる仕組みこそが、真の自動化である。
C. エラーハンドリングは「復元」までが責務
APIでシステム設定(`SetUserPreference`)を書き換えた場合、処理が途中でエラー落ちすると、ユーザーのSolidWorks設定が壊れたまま残る。
`On Error GoTo` を使い、たとえ失敗しても必ず設定を元の値(`oldRes`)に戻す `Rollback` プロセスを実装せよ。これが、現場で「使い物になるツール」と「ただのバグの塊」を分ける境界線だ。
結論
自動化エンジニアの価値は、単純な繰り返し作業を減らすことではなく、「業務の複雑なルールを、いかに堅牢なロジックに昇華させるか」にかかっている。
標準機能の限界に直面したとき、それを嘆くのではなく、アーキテクチャを設計せよ。シートごとのコンテキストを読み取り、動的にパラメータを制御する。その一歩が、あなたを単なるスクリプターから、真のソリューション・アーキテクトへと進化させる。
