【実務・中級編】【初心者向け】ModelDoc2.Extension.GetSelectionInfo2を活用した選択要素のタイプ判別と安全な参照取得 – SolidWorks VBA解析バイブル

スポンサーリンク

選択を「祈り」で終わらせるな。

ModelDoc2.Extension.GetSelectionInfo2 で構築する、堅牢なジオメトリ操作の鉄則

SolidWorks VBAの世界へようこそ。私はこれまで数千、数万行のAPIコードを書き、そしてそれ以上に「動かなくなった他人のコード」を直してきた。

初心者が作成するマクロが実務で「使えない」と断じられる最大の理由は何か。それは、「ユーザーが意図した通りの操作をすることを前提にしている」点にある。

「面を選択してください」と指示したとき、ユーザーは誤ってエッジをクリックするかもしれない。あるいはフィーチャーマネージャーからフィーチャーを選択するかもしれない。この時、あなたのコードが即座にランタイムエラーを吐いて止まるのか、あるいは「それは面ではありません」と冷静に突き返すのか。この差が、ツールとしての「品格」と「信頼性」を分かつ。

今回は、選択要素の正体を暴き、安全にオブジェクトを捕捉するための核心部、`SelectionManager` と `swSelectType_e` 定数、そして実務レベルの判定ロジックを伝授する。

1. なぜ「型の判定」が最優先事項なのか

SolidWorks APIにおいて、選択されたオブジェクトはすべて `Object` 型(汎用型)として返される。これを `Face2` や `Feature` に無理やりキャスト(型変換)して操作しようとすると、型が一致しなかった瞬間にVBAは沈黙を破り、実行時エラーでクラッシュする。

プロフェッショナルのコードは、まず「お前は何者か?」をAPIに問い、正体が判明してから初めてその能力(メソッド)を引き出す。

ここで鍵となるのが `SelectionManager` だ。そして、選択された瞬間の情報をより詳細に、そして安全に取得するために `ModelDoc2.Extension.GetSelectionInfo2` を活用する設計思想を身に着けてほしい。

2. 実践:誤操作を許容しない「鋼鉄」の判定ロジック

以下のコードは、単に選択を取得するだけでなく、「今何が選ばれているか」を厳密にカタログ化し、安全に処理へ繋げるためのテンプレートだ。


‘ Module: SelectionRefiner
‘ Description: ユーザーの選択を検証し、安全に型を特定するプロフェッショナル・プロトコル

Option Explicit

Sub IdentifySelectedObject()
‘ SolidWorksの基底オブジェクト
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swSelMgr As SldWorks.SelectionMgr
Dim swSelData As SldWorks.SelectData

‘ 判定対象
Dim selType As Long
Dim i As Integer

Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc

‘ ドキュメントが開いているかのガード句
If swModel Is Nothing Then
MsgBox “パーツファイルを開いてください。”, vbCritical
Exit Sub
End If

‘ SelectionManagerの取得
Set swSelMgr = swModel.SelectionManager

‘ 選択されている個数を確認
Dim selCount As Long
selCount = swSelMgr.GetSelectedObjectCount2(-1)

If selCount = 0 Then
MsgBox “要素が選択されていません。面、エッジ、またはフィーチャーを選択してください。”, vbExclamation
Exit Sub
End If

‘ 最新の選択要素(インデックス 1)を解析
‘ GetSelectedObjectType3 は、定数 swSelectType_e を返す
selType = swSelMgr.GetSelectedObjectType3(1, -1)

‘ GetSelectionInfo2 を利用して、選択時の詳細なコンテキスト(SelectData)を生成
‘ これにより、アセンブリ内でのコンポーネント情報などを保持したまま安全に参照できる
Set swSelData = swSelMgr.CreateSelectData

Debug.Print “— 選択要素解析開始 —”

Select Case selType

Case swSelectType_e.swSelFACES
‘ 面が選択された場合の処理
Dim swFace As SldWorks.Face2
Set swFace = swSelMgr.GetSelectedObject6(1, -1)
ProcessFace swFace

Case swSelectType_e.swSelEDGES
‘ エッジが選択された場合の処理
Dim swEdge As SldWorks.Edge
Set swEdge = swSelMgr.GetSelectedObject6(1, -1)
ProcessEdge swEdge

Case swSelectType_e.swSelBODYFEATURES
‘ フィーチャー(押し出し、カット等)が選択された場合の処理
Dim swFeat As SldWorks.Feature
Set swFeat = swSelMgr.GetSelectedObject6(1, -1)
ProcessFeature swFeat

Case Else
‘ 想定外の型が選択された場合
MsgBox “未対応の要素タイプです (Type ID: ” & selType & “)”, vbInformation

End Select

Debug.Print “— 解析終了 —”
End Sub

‘ — 以下、各型に特化したサブプロシージャ —

Private Sub ProcessFace(ByVal swFace As SldWorks.Face2)
‘ 面の面積を取得するなど、具体的な業務ロジックをここに集約する
Dim area As Double
area = swFace.GetArea
Debug.Print “【判定:面】 面積: ” & Round(area 1000000, 2) & ” mm2″
End Sub

Private Sub ProcessEdge(ByVal swEdge As SldWorks.Edge)
‘ エッジの長さを取得するなど
Dim swCurve As SldWorks.Curve
Dim length As Double
‘ エッジからカーブ情報を抽出し、パラメータ範囲から長さを計算(実務で多用する手法)
‘ ※簡易化のためここでは型の特定まで
Debug.Print “【判定:エッジ】 頂点間の距離を測定可能…”
End Sub

Private Sub ProcessFeature(ByVal swFeat As SldWorks.Feature)
‘ フィーチャー名の取得や、パラメータの変更
Debug.Print “【判定:フィーチャー】 名称: ” & swFeat.Name
End Sub

3. チーフアーキテクトの視点:なぜこの設計なのか

① `GetSelectedObjectType3` による早期リターン

オブジェクトを `GetSelectedObject6` で取得する前に、`GetSelectedObjectType3` でその「正体(Long型の定数)」を確認している。これは、重いオブジェクト生成を行う前に、フィルタリングをかけるためだ。無駄なキャストはメモリと処理時間の浪費である。

② `Select Case` による責務の分離

`If…Then…ElseIf` の羅列は、保守性を著しく低下させる。`Select Case` を使い、各タイプごとの処理を専用のプライベートプロシージャ(`ProcessFace`など)に逃がすことで、メインロジックの可読性を劇的に向上させている。これが「スパゲッティコード」にならないための第一歩だ。

③ `GetSelectionInfo2` と `SelectData` の存在意義

今回は基礎的な判定に留めたが、実務がアセンブリ(Assembly)に及ぶ際、この `SelectData` が真価を発揮する。アセンブリ階層の中で「どのコンポーネントの面なのか」という情報を欠落させずに保持するためには、単なるオブジェクト取得ではなく、このコンテキスト情報の生成が不可欠になる。

4. データベースやファイル連携への布石

あなたが作っているのが「ただの自動化」ではなく「業務システム」であるなら、ここで得た `swFeat.Name` や `Face` のIDをデータベース(SQL ServerやExcel管理表)に飛ばすことになるだろう。

その際、「何も選択されていない状態」でDB書き込み処理が走れば、システムは即座に異常終了する。 上記コードに組み込んだ `If selCount = 0` のようなガード句は、単なるエラー回避ではなく、データの整合性を守るための「防波堤」なのだ。

結論

`ModelDoc2.Extension.GetSelectionInfo2` や `SelectionManager` を使いこなすことは、SolidWorks APIを制御下に置くことを意味する。

ユーザーの操作を疑え。
型を厳密に判定せよ。
そして、処理を細分化せよ。

この鉄則を守るだけで、あなたの書くVBAコードは、初心者レベルを脱し、現場で「資産」として重宝されるプロダクションコードへと昇華するはずだ。次は、取得したジオメトリから具体的な寸法パラメータを抽出するフェーズへ進もう。健闘を祈る。

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