こんにちは!SolidWorksの自動化の世界へようこそ。
マクロの記録ボタンを押して生成されたコードを眺める段階を卒業し、「いよいよ自分の手で実務に役立つツールを作りたい!」そう思っているあなたへ。
今回は、SolidWorks VBAにおいて最も重要であり、かつ多くの開発者がつまずく「ユーザーが画面上で選択したオブジェクトを安全に料理する方法」について、徹底的に解説していきます。
ここをクリアすれば、あなたの作るマクロは「フリーズしにくい、プロ仕様の堅牢なツール」へと生まれ変わります。一緒に一歩ずつ、本質を学んでいきましょう!
—
なぜ「選択オブジェクトの判定」でみんな悩むのか?
SolidWorksでマクロを作るとき、「ユーザーに何かを選ばせて、その図形に対して処理を行う」というシチュエーションは非常に多いです。例えば、「選んだ面をオフセットする」「選んだ円柱の穴の直径を取得する」といった具合ですね。
ここで初心者がやりがちなのが、こんなコードです。
‘ 【危なっかしいコードの例】
Dim swSelObj As Object
Set swSelObj = swSelectionMgr.GetSelectedObject6(1, -1)
‘ いきなりメソッドを呼ぶ!
swSelObj.MySpecialMethod
これ、何がいけないか分かりますか?
もしユーザーが何も選択していなかったら? あるいは、面を選んでほしいのに「エッジ(線)」を選んでしまっていたら?
答えは当然、「実行時エラー(25号や46号など)でマクロが強制終了」、あるいは最悪の場合、SolidWorksごとフリーズします。
実務で使うマクロに求められるのは、「何でもかんでも動く」ことではなく、「ユーザーが変な操作をしても、優しくエラーを伝えて止まらないこと」です。そのための最強の武器が、`GetSelectedObject6` と、これから解説する「型判定」のコンボ技なのです。
—
秘技:GetSelectedObject6 と SelectData の正体
SolidWorks APIの選択マネージャー(`SelectionMgr`)には、選択されたオブジェクトを取得するメソッドがいくつかありますが、現代のSolidWorks VBA開発において実質一択なのが `GetSelectedObject6` です。
まずは、そのシグネチャ(お作法)を確認しておきましょう。
Set 取得オブジェクト = SelectionMgr.GetSelectedObject6(Mark, Index)
- Mark(マーク): 選択セットのグループIDのようなものです。特定のマークがついた選択だけを狙い撃ちしたい時に使いますが、とりあえず全体から取得したい場合は `1` を指定しておけばOKです。
- Index(インデックス): 何番目に選択されたものを取得するかです。通常は `1`(最初に選択したもの)を指定します。
帰ってきたオブジェクトの「正体」を見破る
`GetSelectedObject6` が返すオブジェクトのデータ型は、VBAの基本型である `Object`(または `Dispatch`)です。つまり、「何が返ってくるか、受け取る瞬間には分からない(入れ物に入っているのが猫なのか犬なのか分からない)」状態になっています。
これを安全に判別するために、SolidWorks VBAでは `TypeOf … Is` という強力な演算子を使います。
—
【実践】面なのか? 円柱(Cylinder)なのか? を判定するコード
百聞は一見にしかず。実際に「ユーザーが選択したのが『面(Face2)』であり、かつそれが『円柱形状』であるか」を判定し、違ったら優しく警告する実用コードを見てみましょう。
Sub CheckSelectedFaceType()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swSelMgr As SldWorks.SelectionMgr
Dim swEntity As SldWorks.Entity
Dim swFace As SldWorks.Face2
Dim swSurface As SldWorks.Surface
‘ 1. アプリケーションとドキュメントの取得
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “ドキュメントが開かれていません。”, vbCritical
Exit Sub
End If
‘ 2. 選択マネージャーの取得
Set swSelMgr = swModel.Extension.GetSelectionManager
‘ 何も選択されていない場合のガード
If swSelMgr.GetSelectedObjectCount2(-1) = 0 Then
MsgBox “対象となる面が選択されていません。面を選択してから実行してください。”, vbExclamation
Exit Sub
End If
‘ 3. GetSelectedObject6でオブジェクトを取得 (Mark=1, Index=1)
‘ まずは汎用的な Entity インターフェースとして受けるのが安全
Set swEntity = swSelMgr.GetSelectedObject6(1, 1)
If swEntity Is Nothing Then
MsgBox “オブジェクトの取得に失敗しました。”, vbCritical
Exit Sub
End If
‘ 4. 【型判定の核心】本当に「面 (Face2)」が選ばれているか?
‘ TypeOf 演算子を使って、オブジェクトのクラスを厳密にチェックします
If TypeOf swEntity Is SldWorks.Face2 Then
Set swFace = swEntity
‘ 5. さらに踏み込み:面のジオメトリ(形状)が「円柱」であるか?
Set swSurface = swFace.GetSurface()
‘ SurfaceのTypeプロパティで形状を判定
‘ 4番が円柱(Cylinder)を表します
If swSurface.IsCylinder() Then
MsgBox “素晴らしい!「円柱の面」が正しく選択されています。”, vbInformation
‘ — ここに円柱に対するメイン処理を書く —
Else
MsgBox “選択された面は円柱ではありません。「平らな面」または「別の形状」です。”, vbExclamation
End If
Else
‘ 面以外(エッジや頂点、コンポーネントなど)が選ばれていた場合
MsgBox “「面」が選択されていません。エッジや他の要素が選ばれています。”, vbCritical
End If
End Sub
—
コードのポイントと、エンジニアの知見
上記のコードには、現場で生き残るためのテクニックが詰まっています。いくつか重要なポイントを解説しますね。
1. いきなり `Face2` にキャストしない
`Set swFace = swSelMgr.GetSelectedObject6(…)` といきなり型を決めつけて代入すると、ユーザーがエッジを選んでいた瞬間にVBAがクラッシュします。
ワンクッション置いて `Entity` 型(すべてのジオメトリの親のようなもの)で受け、`TypeOf … Is SldWorks.Face2` で安全確認を行ってから型変換(キャスト)するのが、プログラマの基本作法です。
2. Surface(サーフェス)オブジェクトの活用
SolidWorksの「面(Face2)」の裏側には、数学的な実体である「サーフェス(Surface)」が隠れています。
`swFace.GetSurface()` を呼び出すことで、その面が平ら(Plane)なのか、円柱(Cylinder)なのか、円錐(Cone)なのか、スプライン曲面なのかを判定する扉が開きます。今回は `IsCylinder()` メソッドを使いましたが、他にも `IsCone()` や `IsSphere()` などが用意されています。
—
陥りやすいエラーと回避のコツ
最後に、この実装を進める中で初心者がハマりやすい罠をシェアしておきます。
- 罠1:複数選択されているときのインデックス忘れ
- 症状: ユーザーが複数の面を選択している状態でマクロを動かすと、意図しない面が処理される。
- 対策: `GetSelectedObject6(1, 2)` のように2番目、3番目を取得したい場合は、ループを回すか、事前に選択数を `GetSelectedObjectCount2` でチェックする癖をつけましょう。
- 罠2: アセンブリ環境での選択
- 症状: パーツ単体では動くのに、アセンブリ(ASM)の中で使うと `GetSelectedObject6` がコンポーネントの参照を返してきて型が一致せずエラーになる。
- 対策: アセンブリの場合は、返ってくるオブジェクトから「どの部品のどの面か(`Component2`)」を考慮する必要がありますが、まずは「パーツファイル単体」での確実な判定ができるようになってから挑戦するのが近道です。
—
まとめ:ここをクリアすれば、もう初心者じゃない!
今回は、`GetSelectedObject6` を使った動的選択オブジェクトの安全な型判定と、ジオメトリ(円柱)の判別方法について解説しました。
- 選択されたものが何か分からないときは `Entity` で受ける
- `TypeOf` 演算子で型を安全にチェックする
- さらに `Surface` を使って形状(円柱など)まで見極める
この3ステップをマスターすれば、ユーザーがどんな無茶な選択をしても優しくエラーメッセージを返し、決してクラッシュしない「優良マクロ」が作れるようになります。
ここをクリアしたあなたは、もう「マクロの記録の奴隷」ではありません立派なSolidWorks自動化エンジニアの仲間入りです。ぜひご自身の環境でもコードを動かして、挙動を確かめてみてくださいね。それでは、次回の極限知見でお会いしましょう!
