こんにちは。SolidWorks APIの世界へようこそ。
私はこれまで、数えきれないほどの自動化ツールを設計し、数百万行のコードを世に送り出してきました。
多くの初心者が最初にぶつかる壁。それは「マクロの記録」から卒業しようとした瞬間に現れる「実行時エラー」です。
「面を選んで処理するはずが、ユーザーがエッジを選んでしまったためにマクロが止まる」
「何も選んでいない状態で実行してエラーになる」
こうした不安定なマクロを、プロフェッショナルな「道具」へと昇華させるための鍵が、今回解説する選択要素のタイプ判別です。今回は、`ModelDoc2.SelectionManager` を通じて、`GetSelectedObjectType3` や `GetSelectionInfo` を使いこなし、どんな選択にも動じない堅牢なコードを書く方法を伝授しましょう。
ここをマスターすれば、あなたのマクロは「ただ動くもの」から「信頼できるツール」へと進化します。
—
1. なぜ「型」を確認する必要があるのか?
SolidWorksのモデル空間には、面(Face)、エッジ(Edge)、頂点(Vertex)、そしてフィーチャ(Feature)など、多種多様なオブジェクトが混在しています。
VBAのコードで「選択された面の色を変える」という処理を書くとき、プログラム内部では以下のようなことが起きています。
1. SelectionManagerから選択物を取ってくる
2. 取ってきたものを Face2(面) という型に無理やり当てはめる(キャスト)
3. もし、中身が Edge(エッジ) だったら……?
ここで「型が一致しません」という冷酷なエラーが出て、マクロは停止します。
「君が掴んだのは面だと言ったけれど、実際はエッジだったよ。だからもう動けないよ」と、コンピュータが匙を投げてしまうのです。
これを防ぐのが、今回紹介する「タイプ判別」のロジックです。
—
2. 鉄壁のガード:選択タイプ判別の基本フロー
プロのコードでは、必ず「処理に入る前の検品」を行います。
1. そもそも何かが選択されているか?(Count > 0)
2. 選択されているものの「正体」は何か?(Type IDの確認)
3. 正体が分かってから、専用の変数に格納する。
これを実現するための、最もスマートで安全なコードを見てみましょう。
実践コード:安全なオブジェクト取得
Option Explicit
‘ SolidWorksの定数(swSelectType_e)を利用するための宣言
‘ ※通常、参照設定が済んでいれば自動で補完されます
Sub SafeSelectionSample()
‘ — 1. 定義と初期化 —
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swSelMgr As SldWorks.SelectionMgr
Dim i As Long
Dim selCount As Long
Dim selType As Long
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
‘ ドキュメントが開かれていない場合のガード
If swModel Is Nothing Then
MsgBox “パーツファイルを開いてから実行してください。”, vbExclamation
Exit Sub
End If
‘ SelectionManager(選択を管理する司令塔)を取得
Set swSelMgr = swModel.SelectionManager
‘ — 2. 選択数の確認 —
selCount = swSelMgr.GetSelectedObjectCount2(-1)
If selCount = 0 Then
MsgBox “何か要素(面やフィーチャ)を選択してください。”, vbInformation
Exit Sub
End If
‘ — 3. 選択要素のループ処理とタイプ判別 —
For i = 1 To selCount
‘ 選択タイプのIDを取得 (swSelectType_e 列挙型を返す)
selType = swSelMgr.GetSelectedObjectType3(i, -1)
Debug.Print “選択インデックス ” & i & ” のタイプID: ” & selType
‘ タイプに応じた安全な処理
Select Case selType
Case swSelectType_e.swSelFACES
‘ 【面】が選択されている場合
Dim swFace As SldWorks.Face2
Set swFace = swSelMgr.GetSelectedObject6(i, -1)
MsgBox “インデックス ” & i & ” は「面」です。面積を取得できます。”
‘ ここに面に対する処理を書く
Case swSelectType_e.swSelEDGES
‘ 【エッジ】が選択されている場合
Dim swEdge As SldWorks.Edge
Set swEdge = swSelMgr.GetSelectedObject6(i, -1)
MsgBox “インデックス ” & i & ” は「エッジ」です。長さを取得できます。”
‘ ここにエッジに対する処理を書く
Case swSelectType_e.swSelBODYFEATURES
‘ 【フィーチャ】が選択されている場合
Dim swFeat As SldWorks.Feature
Set swFeat = swSelMgr.GetSelectedObject6(i, -1)
MsgBox “インデックス ” & i & ” はフィーチャ「” & swFeat.Name & “」です。”
Case Else
‘ 想定外のものが選ばれている場合
MsgBox “インデックス ” & i & ” は、このマクロではサポートしていない種類です(ID:” & selType & “)”
End Select
Next i
End Sub
—
3. 深掘り:GetSelectionInfo2 とは何者か?
今回のテーマにある `ModelDoc2.Extension.GetSelectionInfo2` について、少し踏み込んだ話をしましょう。
多くの初心者は `SelectionMgr` だけを見ますが、中級者への階段を登るには「選択のメタ情報」を扱う `SelectionInfo` オブジェクトが重要になります。
なぜ SelectionInfo が必要なのか?
通常、`GetSelectedObjectType3` だけで事足ります。しかし、「マーク(Mark)」 という概念を使う複雑なコマンド(例:ロフトやスイープの自動生成)を作る際、`SelectionInfo` は強力な味方になります。
- マーク値の取得: 「このエッジは、ガイド曲線として選択されたのか?それとも輪郭としてか?」といった、選択時の「役割(マーク)」を判別できます。
- より詳細なコンテキスト: `GetSelectionInfo2` を使うと、その選択がどのプロパティマネージャーページ(PMP)で行われたかなどの付随情報を管理できるようになります。
初心者の方は、まずは上のコード例のように `GetSelectedObjectType3` で「種類」を判別することに慣れてください。それができたら、次のステップとして `SelectionInfo` で選択の「意味(マーク)」を操る領域へ進みましょう。
—
4. 陥りやすいエラーと回避策
① 「型が一致しません」エラー
`GetSelectedObject6` で取得したものを、いきなり `Dim swFace As SldWorks.Face2` に代入しようとすると発生します。
回避策: 必ず `Select Case` や `If` 文で、`GetSelectedObjectType3` の戻り値を確認してから代入(Set)してください。
② 何も選択されていない時の「オブジェクト参照エラー」
`GetSelectedObjectCount2` が 0 のときに処理を続行すると、後のコードで必ずエラーになります。
回避策: マクロの冒頭で「選択数が 0 なら終了する」という ガード句 を入れましょう。
③ インデックスの開始番号
SolidWorks APIの多くは `1` から始まるインデックスを採用していますが、一部 `0` から始まるものもあります。
SelectionManager の取得メソッド(`GetSelectedObject6` など)は 1から始まる ことを忘れないでください。
—
5. 最後に:マクロを「芸術」に変えるために
マクロの記録で生成されるコードは、いわば「独り言」です。ユーザーが何をしようと、記録された通りにしか動けません。
しかし、今回学んだ 「選択状態を自ら判断するロジック」 を組み込むことで、あなたのマクロは「対話のできる知的なツール」へと生まれ変わります。
「面を選んでください」というメッセージを出す。
間違ったものが選ばれたら「それはエッジですよ」と優しく教える。
こうした配慮の一つひとつが、設計現場のミスを減らし、自動化の価値を高めます。
まずは、自分がよく使うフィーチャや面のタイプID(`swSelFACES`など)を調べることから始めてみてください。
SolidWorks VBAの広大な海は、ここからさらに深く、そして面白くなっていきます。一歩ずつ、確実に進んでいきましょう。応援していますよ。
