【実務・中級編】【上級プロ向け】SolidWorks図面エクスポート時のカスタム「PDF/TIFFコンバーター」:ページごとの個別解像度・カラー制御 – SolidWorks VBA解析バイブル

スポンサーリンク
スポンサーリンク

標準の「名前を付けて保存」を捨てろ。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` プロセスを実装せよ。これが、現場で「使い物になるツール」と「ただのバグの塊」を分ける境界線だ。

結論

自動化エンジニアの価値は、単純な繰り返し作業を減らすことではなく、「業務の複雑なルールを、いかに堅牢なロジックに昇華させるか」にかかっている。

標準機能の限界に直面したとき、それを嘆くのではなく、アーキテクチャを設計せよ。シートごとのコンテキストを読み取り、動的にパラメータを制御する。その一歩が、あなたを単なるスクリプターから、真のソリューション・アーキテクトへと進化させる。

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