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

スポンサーリンク

SolidWorks APIの「SelectByID2」に依存するな:トポロジー変更を生き抜く堅牢な参照取得術

エンジニアの諸君、今日もSolidWorksのAPIと格闘しているだろうか。

マクロを作成していて、こんな経験はないだろうか。「最初は完璧に動いていたのに、モデルの形状を少し変更しただけで、翌日から『SelectByID2』がエラーを吐いてマクロが停止する」。

断言しよう。それはあなたのコードが「脆弱」だからだ。

SolidWorksのAPIにおいて、`SelectByID2`で面やエッジをID指定で選択する手法は、いわば「砂の城に柱を立てる」ようなものだ。再計算(Rebuild)やフィーチャの順序変更でトポロジーが変化すれば、IDは容赦なく書き換わる。本稿では、そんな「脆いコード」から卒業し、形状の変化に屈しない「真の堅牢な自動化」を実現するための設計思想を伝授する。

なぜ「SelectByID2」は罠なのか

SolidWorksのモデルは、フィーチャツリーの履歴に基づいてエンティティ(面・エッジ・頂点)にIDを割り振る。しかし、フィーチャの追加や削除、あるいはフィレットの半径変更一つで、そのIDは再構築される。

IDに依存するということは、「モデルの履歴」に依存しているということだ。自動化において、履歴に依存するのは最悪の設計である。我々が依存すべきなのは、「その面が持つ不変の幾何学的属性」である。

攻略の鍵:幾何学的属性による「動的探索」

特定の面を取得したいとき、IDではなく「そこにあるべき姿」を検索条件にする。具体的には以下のステップを踏む。

1. ボディの走査: `GetFirstFace` から巡回を開始する。
2. 属性の照合: 法線ベクトル、重心座標、あるいは面積を用いて、対象の面を「特定」する。
3. 選択の実行: 特定したオブジェクトに対して直接 `Select4` メソッドを叩く。

これなら、フィーチャツリーの構成が変わろうが、モデルが微修正されようが、目的の面がそこに存在し、幾何学的特徴が変わらない限り、マクロは止まらない。

【プロダクションコード】堅牢な面取得の実装例

以下に、特定の面(例:上向きの基準面)を幾何学的属性から特定して選択する汎用関数を示す。このロジックをテンプレートとして活用してほしい。

‘ —————————————————————————–
‘ 目的: 幾何学的属性(法線ベクトル)を用いて、堅牢に面を取得する
‘ —————————————————————————–
Public Function GetFaceByNormal(swPart As SldWorks.PartDoc, targetNormal As Variant) As SldWorks.Face2
Dim swBody As SldWorks.Body2
Dim swFace As SldWorks.Face2
Dim swSurf As SldWorks.Surface
Dim normal As Variant
Dim i As Integer

‘ 最初のソリッドボディを取得
Set swBody = swPart.Body(0) ‘ 複数ボディの場合はループ処理が必要
Set swFace = swBody.GetFirstFace

Do While Not swFace Is Nothing
‘ 面の法線ベクトルを取得 (中心点における法線)
normal = swFace.Normal

‘ 許容誤差範囲内で一致するか判定(実務ではEPSILONを設定すること)
If Abs(normal(0) – targetNormal(0)) < 0.001 And _ Abs(normal(1) - targetNormal(1)) < 0.001 And _ Abs(normal(2) - targetNormal(2)) < 0.001 Then Set GetFaceByNormal = swFace Exit Function End If Set swFace = swFace.GetNextFace Loop End Function ' ----------------------------------------------------------------------------- ' 実践例:取得した面を選択する(SelectByID2を使わない) ' ----------------------------------------------------------------------------- Public Sub SelectRobustFace() Dim swApp As SldWorks.SldWorks: Set swApp = Application.SldWorks Dim swModel As SldWorks.ModelDoc2: Set swModel = swApp.ActiveDoc ' 上向き(0, 1, 0)の面を探す Dim targetNormal(0 To 2) As Double targetNormal(0) = 0: targetNormal(1) = 1: targetNormal(2) = 0 Dim targetFace As SldWorks.Face2 Set targetFace = GetFaceByNormal(swModel, targetNormal) If Not targetFace Is Nothing Then ' Select4 を使用して選択(append=False) targetFace.Select4 False, Nothing Else MsgBox "対象の面が見つかりませんでした。" End If End Sub ---

アーキテクトからの助言:実務上の注意点

この手法を導入する際、以下のポイントを忘れないでほしい。

  • 許容誤差(Tolerance)の導入: 浮動小数点演算は常に誤差を伴う。`Abs(a – b) < 1E-6` といった閾値を必ず設けること。
  • ボディの管理: マルチボディパーツの場合、`Body(0)` だけで満足してはいけない。`GetBodies2` で全ボディをループする設計に拡張する必要がある。
  • データベース連携: もし外部データ(ExcelやDB)と連携させるなら、面に「属性(ユーザー定義属性)」を付与しておく手もある。`SetUserPreference` 等を活用し、設計意図をモデル側に埋め込んでおけば、検索精度は飛躍的に向上する。

まとめ

`SelectByID2` という「脆い呪縛」から解き放たれることは、SolidWorks自動化エンジニアとしての第一歩だ。

コードを書くとき、常に自問自答してほしい。「このコードは、モデルの履歴が変わったときに破綻しないか?」。幾何学的な特徴を追う実装こそが、変化の激しい開発現場における唯一の正解である。

さあ、今すぐ既存のコードをリファクタリングして、止まらない自動化システムを構築してくれ。諸君の健闘を祈る。

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