SolidWorks APIの深淵:アセンブリ重量・材質プロパティの超高速抽出術
現場のエンジニア諸君。SolidWorksの「質量特性」計算で、GUI越しに一つひとつ値を拾い上げるような徒労に時間を費やしていないだろうか。
アセンブリが大規模化すればするほど、`GetMassProperties`の呼び出しは、メモリ管理と再計算の罠を孕む。今回は、ただの「データ抽出」を超え、メモリリークを許さず、システム連携の基盤となり得る「堅牢な重量集計アーキテクチャ」の設計指針を授ける。
—
1. 質量特性取得の「作法」:再計算のコストを無視するな
多くの初学者は、アセンブリ内の全コンポーネントに対して安易に`GetMassProperties`を叩く。だが、SolidWorksのAPIにおいて、「再計算が必要な状態」でのプロパティ取得は、極めて重い処理だ。
我々が実装すべきは、常に「現状のモデルが正当か」を判断し、必要であれば`ForceRebuild`を最小限に抑えつつ、キャッシュを活用するアプローチである。
アーキテクチャの要諦
- 再帰的探索: アセンブリ構造をトップダウンでなめる際、`IComponent2`オブジェクトの参照を保持し続けると、メモリリークの温床となる。処理が終わるごとに明示的な `Nothing` 代入を徹底せよ。
- 質量特性の取得: `ModelDocExtension.GetMassProperties`を使い、座標系を指定して取得する。ここでの誤差を許容しないことが、後のコスト計算の精度を左右する。
—
2. 実装:堅牢な重量集計エンジン
以下に、大規模アセンブリでも耐えうる、最適化されたVBAコードの骨子を示す。Excelのセルへ書き出すまでのパイプラインを想定している。
Option Explicit
‘ 伝説的なエンジニアは、定数でコードの意図を固定する
Private Const SW_ERR_NONE As Long = 0
Public Sub ExportAssemblyMassProperties()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssy As SldWorks.AssemblyDoc
Dim swComp As SldWorks.Component2
‘ インスタンス取得:既存プロセスへのアタッチを優先
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Or swModel.GetType <> swDocASSEMBLY Then
MsgBox “対象はアセンブリのみです。”
Exit Sub
End If
Set swAssy = swModel
‘ 処理開始:メインループ
Call TraverseComponents(swAssy.GetComponents(False))
‘ 終了処理:メモリ解放の徹底
Set swAssy = Nothing
Set swModel = Nothing
Set swApp = Nothing
End Sub
Private Sub TraverseComponents(vComps As Variant)
Dim i As Long
Dim swComp As SldWorks.Component2
Dim swModelDoc As SldWorks.ModelDoc2
Dim swMass As SldWorks.MassProperty
Dim swModelExt As SldWorks.ModelDocExtension
For i = LBound(vComps) To UBound(vComps)
Set swComp = vComps(i)
‘ サプレッション状態をチェックし、計算対象を絞る
If swComp.GetSuppression <> swComponentSuppressed Then
Set swModelDoc = swComp.GetModelDoc2
If Not swModelDoc Is Nothing Then
Set swModelExt = swModelDoc.Extension
Set swMass = swModelExt.CreateMassProperty
‘ 質量特性の計算と出力
Debug.Print swComp.Name2 & ” | ” & swMass.Mass & ” kg”
‘ オブジェクトの明示的解放:これがメモリ管理の極意
Set swMass = Nothing
Set swModelExt = Nothing
End If
End If
‘ 再帰処理が必要な場合はここで行う
‘ If swComp.GetChildrenCount > 0 Then …
Set swComp = Nothing
Next i
End Sub
—
3. なぜこの実装が「極限」なのか
1. オブジェクトライフサイクルの管理
VBAのガベージコレクションは非常に遅い。`Set swMass = Nothing` をループ内で明示的に行うことで、SolidWorksのCOMプロセスが保持するメモリスタックを即座に開放している。大規模アセンブリで数千のパーツを扱う際、この一手間が「フリーズ」と「完走」の分かれ道となる。
2. 状態管理の優先順位
`GetSuppression`の判定を先頭に置くことで、サプレッション状態の不要なコンポーネントへのAPIアクセスを遮断している。APIのコール回数は、そのまま処理時間の累積に直結する。
3. システム間連携の拡張性
上記のコードは、Excelへ出力するだけでなく、そのままJSONやCSV形式へ変換してサーバーへ投げるアーキテクチャへの移行も容易だ。`Debug.Print`の部分を、社内のPDMシステムやコスト計算DBへのAPI発行に差し替えるだけで、貴社専用の「自動見積もり・重量管理システム」が完成する。
—
結びに:エンジニアとしての矜持
VBAは古い言語かもしれない。だが、SolidWorksのAPIという強力なバックボーンを掌握すれば、VBAは単なるスクリプトではなく、「設計意図を自動化する魔法の杖」へと昇華する。
もし、貴君の現場で「処理が重い」「よく落ちる」という嘆きが聞こえたら、それはコードが「メモリの重み」を理解していない証拠だ。オブジェクトを慈しみ、解放を忘れず、常に計算の最小化を追求せよ。
それが、我々エンジニアが備えるべき唯一の作法である。次回の講義では、`AssemblyDoc`の`Mate`(合致)構造を直接解析し、物理的干渉を事前に検知する高度な手法について解説する。期待していてほしい。
