選択を「祈り」で終わらせるな。
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コードは、初心者レベルを脱し、現場で「資産」として重宝されるプロダクションコードへと昇華するはずだ。次は、取得したジオメトリから具体的な寸法パラメータを抽出するフェーズへ進もう。健闘を祈る。
