SolidWorks VBAを掌握する極限の知見
【エクスポート自動化】ModelDoc2.SaveAs3メソッドを使ったSTEP・Parasolid・IGESへのマルチフォーマット一括変換
製造業の現場において、CADデータのトランスレーション(フォーマット変換)は、サプライチェーン全体を円滑に回すための生命線である。社内ではSolidWorksネイティブ(`.sldprt`)で完結していても、他部署への受け渡しにはParasolid(`.x_t`)、加工業者への図面レスデータとしてはSTEP(`.step` / `.stp`)、レガシーシステムとの連携にはIGES(`.igs`)と、要求されるフォーマットは多岐にわたる。
これを手動で「名前を付けて保存」を繰り返すのは、エンジニアの貴重な時間を奪うだけでなく、ヒューマンエラーによるバージョン違いの温床となる。
今回は、SolidWorks VBAの底力を引き出し、単一のマスターパーツから複数フォーマットへの一括変換を極限まで堅牢かつ高速に実行するプロダクション品質のスクリプトを提示する。
—
1. SaveAs3メソッドの深層と「見えない罠」
多くの初学者や一般のVBA解説記事では、`ModelDoc2.SaveAs` や `SaveAs2` を安易に使用している。しかし、シニアエンジニアであれば、APIの裏側で何が起きているかを知るべきだ。
`SaveAs3` メソッドは、引数の構成によってエクスポート時のオプション(コンフィギュレーション、バージョン、幾何公差の精度など)を細やかに制御できる。しかし、ここで最も恐ろしいのは 「SolidWorksのUIスレッドとCOMオブジェクトのライフサイクル管理の非同期性」 である。
大量のファイルを連続処理する際、メモリ解放を怠ると、COMラッパーがメモリリークを起こし、最終的にSolidWorks本体がサイレントクラッシュ(または「RPCサーバーが利用できません」という致命的なエラー)を引き起こす。
極限の最適化における鉄則
1. オブジェクトの完全な破棄: ループ内で生成・取得した `ModelDoc2` や `SelectionMgr` などの参照は、処理の終了ごとに `Set obj = Nothing` で明示的に解放する。
2. サイレントモードの徹底: エクスポート時にダイアログや警告を出させないフラグ (`swSaveAsOptions_Silent`) を必ず付与する。
3. エラーハンドリングとファイルロックの回避: 出力先ディレクトリの動的生成と、既存ファイルの上書き競合を防ぐガードロジックを実装する。
—
2. 実装コード:マルチフォーマット一括エクスポート・エンジン
以下のコードは、現在アクティブなパーツドキュメントを起点とし、同一ディレクトリ(または指定ディレクトリ)へ、STEP (AP214)、Parasolid (最新テキスト形式)、IGESの3種類へ一瞬で変換・出力するプロフェッショナル向けスクリプトである。
Option Explicit
‘ =================================================================================
‘ 圧倒的な堅牢性を持つマルチフォーマット・エクスポートエンジン
‘ Architectural Design: Chief Automation Engineer
‘ =================================================================================
Sub MasterExportEngine()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim activeFilePath As String
Dim baseFileName As String
Dim outputDir As String
Dim fso As Object
‘ 1. アプリケーションおよびドキュメントの安全な取得
Set swApp = Application.SldWorks
If swApp Is Nothing Then
MsgBox “SolidWorksセッションが見つかりません。”, vbCritical, “致命的エラー”
Exit Sub
End If
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。パーツを開いて実行してください。”, vbExclamation, “警告”
Exit Sub
End If
‘ 2. ドキュメントタイプの検証(パーツ専用)
If swModel.GetType <> swDocPART Then
MsgBox “このマクロは「パーツ(Part)ファイル」でのみ実行可能です。”, vbCritical, “型不一致エラー”
Exit Sub
End If
‘ 3. 未保存ファイルの検知(パスがない場合は処理中断)
activeFilePath = swModel.GetPathName
If activeFilePath = “” Then
MsgBox “このファイルはまだ保存されていません。一度保存してから実行してください。”, vbExclamation, “未保存エラー”
Exit Sub
End If
‘ 4. ファイルシステムオブジェクトの初期化と出力パスの構築
Set fso = CreateObject(“Scripting.FileSystemObject”)
outputDir = fso.GetParentFolderName(activeFilePath) & “\Exported_Outputs\”
‘ 出力ディレクトリが存在しない場合は自動生成
If Not fso.FolderExists(outputDir) Then
fso.CreateFolder (outputDir)
End If
baseFileName = fso.GetBaseName(activeFilePath)
‘ 5. エクスポート処理の実行(エラーハンドリング保護下)
On Error GoTo ErrorHandler
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayHideAllTypes, True ‘ 描画負荷軽減
Dim saveError As Long
Dim saveWarning As Long
Dim targetPath As String
Dim exportSuccess As Boolean
‘ ————————————————————-
‘ A. Parasolid (.x_t) エクスポート
‘ ————————————————————-
targetPath = outputDir & baseFileName & “.x_t”
exportSuccess = swModel.SaveAs3(targetPath, 0, 2) ‘ swSaveAsCurrentVersion, swSaveAsOptions_Silent
If Not exportSuccess Then GoTo ExportFailed
‘ ————————————————————-
‘ B. STEP (.step / AP214推奨) エクスポート
‘ ————————————————————-
targetPath = outputDir & baseFileName & “.step”
‘ ※注: STEP出力時はアプリケーションのSTEP設定が依存しますが、SaveAs3で直接叩けます
exportSuccess = swModel.SaveAs3(targetPath, 0, 2)
If Not exportSuccess Then GoTo ExportFailed
‘ ————————————————————-
‘ C. IGES (.igs) エクスポート
‘ ————————————————————-
targetPath = outputDir & baseFileName & “.igs”
exportSuccess = swModel.SaveAs3(targetPath, 0, 2)
If Not exportSuccess Then GoTo ExportFailed
‘ 正常終了
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayHideAllTypes, False
Set fso = Nothing
Set swModel = Nothing
Set swApp = Nothing
MsgBox “全フォーマットへの一括変換が正常に完了しました。” & vbCrLf & _
“出力先: ” & outputDir, vbInformation, “完了”
Exit Sub
ExportFailed:
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayHideAllTypes, False
MsgBox “エクスポート中にエラーが発生しました。ファイルがロックされているか、不正なジオメトリが含まれています。”, vbCritical, “エクスポート異常”
Set fso = Nothing
Set swModel = Nothing
Set swApp = Nothing
Exit Sub
ErrorHandler:
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayHideAllTypes, False
MsgBox “予期せぬシステムエラーが発生しました: ” & Err.Description, vbCritical, “例外エラー”
Set fso = Nothing
Set swModel = Nothing
Set swApp = Nothing
End Sub
—
3. チーフアーキテクトが教える「現場の知見」と更なる高み
上記のコードはそのまま実務で即座に機能するが、真に大規模な自動化(例えば、夜間に数千パーツのバッチ処理を行うようなシステム)を構築する場合、以下のアーキテクチャ的拡張が必要となる。
① ドキュメントを開かない「ヘッドレス実行(SolidWorks Document Manager API)」の検討
UIを立ち上げた状態で `SaveAs3` を回すと、どうしても画面の描画処理やイベントフックがボトルネックになり、処理速度が低下する。
究極のパフォーマンスを求める場合、SolidWorksのUIを起動せず、SolidWorks Document Manager API(COMコンポーネント)を直接C#やVB.NET、あるいはVBAから叩いてバックグラウンドでジオメトリ変換を行うアーキテクチャを採用すべきである。これにより処理速度は数倍〜十数倍に跳ね上がる。
② コンフィギュレーション(Configuration)の全網羅
パーツファイル内に複数のコンフィギュレーション(派生形状)が存在する場合、上記のコードでは「現在アクティブな状態」しか出力されない。
もし全てのコンフィギュレーション毎にSTEPを出力する必要がある場合は、`ModelDoc2.GetConfigurationNames` メソッドで配列を取得し、ループ内で `ModelDoc2.ShowConfiguration2` を呼び出してコンフィギュレーションを切り替えた上で `SaveAs3` を実行するロジックへ拡張する必要がある。
③ メモリガベージコレクションの徹底
VBAのランタイムは、COMオブジェクトの参照カウント管理においてメモリリークを完全には防げない。数百ファイルを連続処理するスクリプトを書く場合は、VBA単体で完結させず、VSTA (Visual Studio Tools for Applications) や外付のCOM Add-in(VB.NET / C#製)として実装し、`Marshal.ReleaseComObject` を厳格にコントロールするのが、真のシニアエンジニアの選択肢である。
—
結びにかえて
自動化の本質とは、単なる「手作業の代行」ではない。「エラーが入り込む余地を完全に排除し、ビジネスのスピードを極限まで加速させること」である。
今回解説した `SaveAs3` の適切な制御とオブジェクト管理の哲学をあなたの開発環境にインストールし、退屈なデータ変換作業からエンジニアを解放してほしい。
