スイープ操作の闇を断つ:SolidWorks APIにおける「選択順序」と「メモリ生存戦略」の極意
SolidWorks APIを操る多くのエンジニアが、`FeatureManager.InsertSweptRefSurface2` や `BossSwept2` の壁に突き当たる。特に「選択の不安定さ」による実行時エラーは、自動化システムにおいて最も避けるべき“技術的負債”の温床だ。
今日は、UI上のクリック操作を再現するだけの脆弱なコードから脱却し、トポロジー変化に耐えうる「堅牢なスイープ生成」の極限解法を伝授する。
—
1. 選択順序の崩壊を防ぐ:なぜ「SelectByID2」に頼るのか
多くの初心者は `swModel.Extension.SelectByID2` をループ内で使い、パスや輪郭を選択しようとする。しかし、これは「現在表示されているモデルのID」に依存するため、フィーチャの再構築やトポロジーの入れ替わりで容易に破綻する。
真の解決策:`IEntity` インターフェースによるダイレクト参照
フィーチャ(スケッチ)を作成した直後に、そのオブジェクトを `IEntity` としてキャッシュする。これにより、GUI上の選択状態に依存することなく、メモリ上のアドレスを直接指定してスイープを実行できる。
実装の骨子:堅牢なスイープ生成
‘ スイープ生成の黄金テンプレート
Public Sub CreateRobustSweep(swModel As SldWorks.ModelDoc2, swProfile As Object, swPath As Object)
Dim swFeatMgr As SldWorks.FeatureManager
Set swFeatMgr = swModel.FeatureManager
‘ 1. 明示的な選択解除(予期せぬ選択残りを防ぐ)
swModel.ClearSelection2 True
‘ 2. IEntityを使用して選択を確定させる(IDベースの選択は避ける)
Dim swEntProfile As SldWorks.Entity
Dim swEntPath As SldWorks.Entity
Set swEntProfile = swProfile
Set swEntPath = swPath
swEntProfile.Select4 False, Nothing
swEntPath.Select4 True, Nothing ‘ Trueで追加選択
‘ 3. スイープの実行
‘ BossSwept2の戻り値判定は必須。エラーコードを確認せよ
Dim swFeat As SldWorks.Feature
Set swFeat = swFeatMgr.InsertSweptRefSurface2(False, False, False, False, 0, 0, False, False, 0, 0, 0, 0, False, False, False)
‘ 4. メモリ解放(重要:VBA環境では明示的にNothingを代入し、参照カウントを減らす)
Set swEntProfile = Nothing
Set swEntPath = Nothing
Set swFeat = Nothing
End Sub
—
2. メモリ最適化とオブジェクトのライフサイクル管理
SolidWorksのAPIはCOMベースである。VBAにおける `Set swObj = Nothing` は、単なるポインタの解除ではなく、COMサーバー側の参照カウントをデクリメントする重要な命令だ。
ループ処理内でオブジェクトを生成し続け、解放を怠れば、SolidWorksのプロセスは確実に肥大化し、数千回のスイープ生成でメモリリークによるクラッシュを引き起こす。
- 鉄則1: `Feature` を取得したら、処理終了後に必ず `Set swFeat = Nothing` を行うこと。
- 鉄則2: `IModelDoc2` のようなルートオブジェクトは保持し続け、ループ内での再取得(`ActiveDoc`の呼び出し)は避ける。
—
3. レガシー環境と「Windows API」の境界線
極稀に、SolidWorks APIが提供するラッパーでは制御しきれない「ダイアログの割り込み」や「非同期の再構築エラー」に遭遇することがある。その際、安易に `DoEvents` を連発するのは愚策だ。
システム開発の現場では、`Sleep` 関数による物理的な待機ではなく、`swModel.EditRebuild3` の戻り値による再構築完了のポーリングを実装すべきである。
‘ 再構築の完了を待機するループの構築例
Private Function WaitUntilRebuild(swModel As SldWorks.ModelDoc2) As Boolean
Dim i As Integer
‘ 最大10秒待機
For i = 0 To 100
If swModel.EditRebuild3() = 0 Then ‘ 0 = Success
WaitUntilRebuild = True
Exit Function
End If
Sleep 100 ‘ Windows API Sleep (kernel32)
Next i
WaitUntilRebuild = False
End Function
—
4. チーフアーキテクトからの提言
自動化エンジニアにとって最大の敵は「モデルの形状変化」である。
コードを書く際、常に「このスケッチが消滅したり、エッジのIDが再生成されたりしても、このコードは動くか?」という問いを立ててほしい。
- 名前参照を避けろ: スケッチ名やフィーチャ名を文字列で指定するのは、保守性を殺す行為だ。
- インターフェース指向: `Object` 型ではなく、`ISketchSegment` や `IEdge` といった具体的なインターフェースで型定義を行え。これにより、コンパイル時(VBAなら実行前)の型チェックが強化され、デバッグコストが劇的に下がる。
SolidWorks VBAは、単なるスクリプト言語ではない。SolidWorksという巨大な幾何学エンジンを操作する「特権的インターフェース」である。その重みを理解したコードだけが、現場で何年も生き残り続ける。
健闘を祈る。
