【テクニカル・上級編】【実務中級】アセンブリ内の特定サブアセンブリのみをプログラムから外部STEPファイルへ個別エクスポートする自動化 – SolidWorks VBA解析バイブル

スポンサーリンク

SolidWorks APIの深淵:サブアセンブリの「外科的」切り出しとメモリ管理の流儀

アセンブリ全体をエクスポートするルーチンは、初学者が書くコードだ。しかし、巨大なトップアセンブリから特定のサブアセンブリだけを抽出し、クリーンなSTEPファイルとして吐き出す――この作業を自動化する際、メモリリークとCOMオブジェクトの残存に無頓着なコードは、数時間でSolidWorksのプロセスをクラッシュさせる。

今日、我々が扱うのは単なるエクスポートではない。「SolidWorksのメモリ空間を汚さず、かつ確実に特定のノードのみを切り出す」という、実戦的な外科手術のようなコードだ。

1. 探索アルゴリズムの選定:再帰か、イテレーションか

サブアセンブリを特定する場合、`IAssemblyDoc::GetComponents(False)`を使用し、再帰的に構造を辿るのが定石だ。ここで重要なのは、「対象を見つけた瞬間に処理を完結させる」こと。全モデルをメモリにロードするのは、パフォーマンス上の自殺行為である。

‘ 伝説的なエンジニアは、無駄なロードを許さない
Public Function GetTargetComponent(swAssy As SldWorks.AssemblyDoc, targetName As String) As SldWorks.Component2
Dim vComps As Variant
vComps = swAssy.GetComponents(False)

Dim i As Long
For i = 0 To UBound(vComps)
Dim swComp As SldWorks.Component2
Set swComp = vComps(i)

‘ 名称の一致を確認(完全パスか名称かは設計思想による)
If InStr(swComp.Name2, targetName) > 0 Then
Set GetTargetComponent = swComp
Exit Function
End If
Next i
End Function

2. なぜ「別プロセス」のような挙動が必要か

サブアセンブリを個別エクスポートする際、最も陥りやすい罠が「トップアセンブリのコンテキストを引きずること」だ。STEPエクスポートの精度を保つためには、そのコンポーネントを一度メモリ上のルートとして扱う必要がある。

ここで、`IModelDocExtension::SaveAs`を叩く前に、必ず「表示状態の最適化」を行うこと。非表示の構成部品が多いと、SolidWorksは無駄なグラフィック計算を行い、メモリを食いつぶす。

3. 実践:サブアセンブリの個別エクスポート・コード

以下は、メモリの解放を厳密に行う設計で組んだエクスポート・ルーチンだ。

Public Sub ExportSubAssemblyToStep(swApp As SldWorks.SldWorks, swComp As SldWorks.Component2, savePath As String)
Dim swModel As SldWorks.ModelDoc2
Dim swExt As SldWorks.ModelDocExtension
Dim status As Boolean

‘ コンポーネントを実体化し、モデルを取得
Set swModel = swComp.GetModelDoc2
If swModel Is Nothing Then
‘ メモリ上にロードされていない場合は呼び出す(パフォーマンスの代償)
Set swModel = swApp.OpenDoc6(swComp.GetPathName, swDocASSEMBLY, swOpenDocOptions_Silent, “”, 0, 0)
End If

Set swExt = swModel.Extension

‘ STEPエクスポート設定(ここをカスタマイズすることで精度を制御)
‘ 0: STEP AP203, 1: STEP AP214, 2: STEP AP242
status = swExt.SaveAs(savePath, swSaveAsCurrentVersion, swSaveAsOptions_Silent, Nothing, 0, 0)

‘ — メモリ最適化の極意 —
‘ 自身でロードしたモデルであれば、必ず破棄してメモリを解放する
If Not swModel Is Nothing Then
swApp.CloseDoc swModel.GetTitle
End If

‘ オブジェクトの明示的解放(VBAのGCに依存しない)
Set swExt = Nothing
Set swModel = Nothing
End Sub

4. シニアエンジニアが守るべき3つの鉄則

1. COMオブジェクトの解放: `Set obj = Nothing` を怠るな。特にループ内で生成されるオブジェクトは、即座に解放しなければ数千個の構成部品を処理する際にプロセスが肥大化する。
2. APIの戻り値チェック: `status` の成否を必ずログに出力すること。サイレントモード(`swOpenDocOptions_Silent`)は強力だが、エラー発生時に「なぜ止まったか」を追跡できなくなる。
3. Windows APIの介入: 極限の環境(数万部品のアセンブリ)では、`Sleep`や`DoEvents`を駆使し、SolidWorksの描画ループに隙間を作れ。CPUを100%占有させると、APIからの応答がタイムアウトする。

最後に:自動化は「道具」であって「目的」ではない

このコードを実装する君たちに伝えたい。自動化の目的は「楽をすること」ではない。設計者が本来向き合うべき「創造的な課題」に時間を割くために、ルーチンワークを機械に叩き込むことだ。

SolidWorks VBAはレガシーと言われることもあるが、APIの深層を理解すれば、これほど強力な武器はない。このコードを基盤に、君たちの現場のボトルネックを物理的に粉砕してほしい。

健闘を祈る。

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