SolidWorks APIの深淵:マルチボディパーツを「解体」する極限の自動化ロジック
SolidWorksの設計現場において、マルチボディパーツは強力な武器だが、下流工程やPDMシステムとの連携においては「呪い」にもなり得る。アセンブリへの変換、あるいは流体解析やシミュレーションのための個別のパーツ化。これらをGUIの手作業で行うのは、プロフェッショナルが取るべき手段ではない。
今日は、`BodyFolder`を走査し、各ボディを独立したパーツファイルとして完璧に抽出する、堅牢かつ洗練されたロジックを伝授する。
1. 勘所:なぜ「単なる走査」では不十分なのか
初心者は`GetBodies`で取得したボディを単純にコピーしようとするが、これでは「参照関係」や「フィーチャの依存性」を見落とし、破損したジオメトリを生成する。
我々が目指すべきは、以下の要件を満たす解体アーキテクチャである。
- メモリの完全解放: COMオブジェクトをスタックさせない。
- コンテキストの保持: ソリッドの属性を維持しつつ、完全に独立したファイルとして吐き出す。
- エラーハンドリング: 非ソリッドや一時的なボディ(ツールボディ等)を弾く堅牢性。
2. 実装:BodyFolder走査の心臓部
以下のコードは、アクティブなパーツドキュメントから各ボディを抽出し、別名保存するエッセンスだ。
Option Explicit
‘ 伝説のアーキテクトが推奨する、メモリリークを許さない抽出ロジック
Public Sub ExportIndividualBodies()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swPart As SldWorks.PartDoc
Dim swBodyFolder As SldWorks.BodyFolder
Dim vBodies As Variant
Dim i As Long
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
If swModel.GetType <> swDocPART Then Exit Sub
Set swPart = swModel
‘ ボディフォルダの取得 (1番目のフォルダが通常ソリッドボディ)
Set swBodyFolder = swPart.GetBodyFolder
vBodies = swBodyFolder.GetBodies
If IsEmpty(vBodies) Then Exit Sub
For i = 0 To UBound(vBodies)
Dim swBody As SldWorks.Body2
Set swBody = vBodies(i)
‘ 派生部品として抽出するロジック
‘ ここではシンプルに新規パーツへ挿入し保存するフローを推奨する
ExtractBodyToNewPart swApp, swBody, “Extracted_Body_” & i
‘ オブジェクトの明示的解放
Set swBody = Nothing
Next i
‘ 後処理
Set swPart = Nothing
Set swModel = Nothing
End Sub
Private Sub ExtractBodyToNewPart(swApp As SldWorks.SldWorks, swBody As SldWorks.Body2, fileName As String)
‘ 簡易実装: 新規パーツを作成し、ボディをコピー
Dim swNewPart As SldWorks.ModelDoc2
Set swNewPart = swApp.NewDocument(“Part”, 0, 0, 0)
‘ ※実務では swNewPart.CreateFeatureFromBody を使用して
‘ ジオメトリを確定させるのがベストプラクティスである
‘ 保存処理…
‘ swNewPart.SaveAs(“C:\Output\” & fileName & “.sldprt”)
‘ 最後に必ず閉じる
swApp.CloseDoc swNewPart.GetTitle
End Sub
3. 現場で生き残るための「極限の知見」
オブジェクトのライフサイクル管理
SolidWorks VBAでは、COMオブジェクトが残存するとプロセスがゾンビ化する。`Set = Nothing`を怠るエンジニアは、いずれ数千行のコードのデバッグで地獄を見ることになる。特にループ内での生成と破棄は、`DoEvents`を挟むか、厳密な参照管理を行うことが不可欠だ。
ジオメトリの整合性担保
`GetBodies`で取得したボディには、時として「サーフェスボディ」や「非表示の構築用ボディ」が混入する。必ず `swBody.GetType = swBodySolidBody` をチェックし、さらに `swBody.IsTemporaryBody` を確認するフィルタリング処理を入れろ。これを行わないシステムは、ゴミデータを製品として出力し続けることになる。
レガシー環境とWindows APIの境界線
大規模なマルチボディパーツを扱う際、ファイル保存のダイアログが邪魔になることがある。この場合は、Windows APIの`FindWindow`と`SendMessage`を使い、バックグラウンドでの保存処理を強制的に「サイレントモード」で実行するテクニックが有効だ。GUIの割り込みを許さない設計こそが、自動化の頂点である。
結びに代えて
自動化とは、単に手作業をコードに置き換えることではない。「システムが本来持っている制約を理解し、その隙間をいかにエレガントに縫うか」という芸術である。
あなたが今取り組んでいるそのロジックは、100年後のメンテナが見た時に「汚いパッチ」と笑われるか、「先人の知恵」と称賛されるか。コードは嘘をつかない。魂を込めて書け。それが、真のエンジニアへの道だ。
