【テクニカル・上級編】【エラー対策】面やエッジのトポロジー変更で発生する「SelectByID2失敗」を回避する安全な参照取得術 – SolidWorks VBA解析バイブル

スポンサーリンク

「SelectByID2」という名の墓標:堅牢なSolidWorks自動化の真髄

SolidWorks APIを触り始めた者が必ず突き当たる壁。それが `SelectByID2` によるエンティティ選択だ。

「名前やIDで指定すれば動く」と信じて書かれたコードは、設計変更という名の容赦ないトポロジー変化の前に、いとも容易く沈黙する。フィーチャの再構築順序が変わればIDは再割り当てされ、エッジや面は別物として扱われる。この「脆い自動化」から脱却できない限り、君のコードは一生、手動修正の奴隷だ。

今日は、表面的なAPIのラッパーではなく、SolidWorksのメモリ構造とトポロジーを理解した者だけが辿り着ける「動的参照取得」の極意を伝授する。

1. なぜSelectByID2は「死の罠」なのか

`SelectByID2` は、特定の文字列(名前やID)をキーにして内部ポインタを解決しようとする。しかし、SolidWorksのモデルはグラフ構造だ。フィーチャの順序変更、面取りによるトポロジー分裂、ミラーによる対称性の反転。これらが発生した瞬間、IDは「過去の遺物」となる。

堅牢な自動化エンジニアは、「IDという虚像」ではなく「幾何学的属性(不変量)」を追跡する。 これが、メンテナンストラブルをゼロにする唯一の解だ。

2. 幾何学的属性による「動的参照取得」の実装術

面を取得する際、その「法線ベクトル」と「中心座標」は、フィーチャが変わっても比較的安定した物理量である。これらを用いた検索関数を実装せよ。

実装例:法線と位置による面の特定(VBA)

‘ @brief 特定の幾何学的条件を満たす面を取得する
‘ @param swPart ModelDoc2オブジェクト
‘ @param targetNormal 法線ベクトル(Double配列)
‘ @param targetPoint 位置ベクトル(Double配列)
‘ @return 取得したFace2オブジェクト(失敗時はNothing)
Public Function GetFaceByGeometricProperties(swPart As SldWorks.ModelDoc2, _
targetNormal() As Double, _
targetPoint() As Double) As SldWorks.Face2
Dim swBody As SldWorks.Body2
Dim swEnt As SldWorks.Entity
Dim swFace As SldWorks.Face2
Dim swSurf As SldWorks.Surface
Dim vNormal As Variant
Dim vPoint As Variant

‘ 厳密なメモリ管理:アクティブボディから走査する
Set swBody = swPart.Part.Body
Set swFace = swBody.GetFirstFace

Do While Not swFace Is Nothing
‘ 面の法線情報を取得
vNormal = swFace.Normal

‘ 閾値判定(浮動小数点誤差を考慮した判定が必須)
If IsVectorMatch(vNormal, targetNormal, 0.0001) Then
‘ ここで中心座標等のさらなる絞り込みを行う
Set GetFaceByGeometricProperties = swFace
Exit Function
End If

Set swFace = swFace.GetNextFace
Loop
End Function

‘ 浮動小数点比較のイディオム
Private Function IsVectorMatch(v1 As Variant, v2 As Variant, tol As Double) As Boolean
Dim i As Integer
For i = 0 To 2
If Abs(v1(i) – v2(i)) > tol Then Exit Function
Next i
IsVectorMatch = True
End Function

3. シニアエンジニアが守るべき「メモリ解放の掟」

VBAはガベージコレクションが極めて無能だ。SolidWorksのCOMオブジェクトを多用する環境では、明示的な解放を行わなければ、数千回のフィーチャ更新でSolidWorksプロセスは肥大化し、最後にはメモリリークでクラッシュする。

  • `Set Object = Nothing` をループ内で徹底せよ。
  • コレクションや配列にオブジェクトを格納した場合は、クリア時に必ず個別に破棄せよ。

特にAPIの `GetNextFace` や `GetNextFeature` を使用する際は、参照カウントを意識しろ。COMラッパーがメモリ上に残り続けると、SolidWorksはセッション終了までそのリソースを解放しない。

4. レガシー環境とWindows APIの接点

もし君が、さらに高度な制御(例えば、フィーチャマネージャーのツリー状態の監視や、Windowsメッセージによるプロセス間通信)を必要としているなら、`User32.dll` の `FindWindow` や `SendMessage` を使うことになるだろう。

だが、警告しておく。SolidWorksの内部ハンドルを直接操作するのは「禁忌」に近い。VBAからWindows APIを呼び出す際は、必ず `DoEvents` を適切に配置し、メインスレッドのブロッキングを回避せよ。 SolidWorksの再描画プロセスと干渉した瞬間、デッドロックが君のシステムを襲う。

アーキテクトからの提言

自動化ツールは「一度作って終わり」ではない。モデルの成長(進化)に追従できるコードのみが、真の資産となる。

1. IDには頼るな。 幾何学的な特徴量(不変量)をキーにせよ。
2. 型を信じるな。 常に `Nothing` チェックとエラーハンドリングを怠るな。
3. COMを飼い慣らせ。 メモリ解放は自動化の一部ではなく、コードの基盤である。

君のコードが、単なる「スクリプト」から「堅牢なシステム」へと昇華することを期待している。コードの中に魂を込めろ。それが、伝説的な自動化エンジニアへの第一歩だ。

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