こんにちは!SolidWorksの自動化の世界へようこそ。
マクロの記録ボタンを押して生成されたコードを眺める段階は、もう卒業しましたか?
「画面上の図形を操作する」だけのマクロから一歩進んで、「SolidWorksの頭の中(=フィーチャーマネージャーのデザインツリー)」を完全に掌握することができれば、あなたの業務効率化のスキルは一気にプロの領域へと駆け上がります。
今回は、ツリーの奥深くへ潜り込み、親子関係にあるフィーチャーを余すことなく網羅的に解析する【履歴ツリー構造の解析】について、実践的なアルゴリズムを授けましょう。
ここをクリアすれば、SolidWorks VBAの基本はバッチリですよ。一緒に本質を理解していきましょう!
—
なぜ「フィーチャーの巡回」が必要なのか?
SolidWorksのモデルは、一本の太い幹(フィーチャー)から枝(サブフィーチャー)が生え、さらにその先に別の枝が生えるという、まるで植物のような「階層構造(ツリー構造)」を持っています。
例えば、以下のような構造を想像してください。
- 押し出しボス
- スケッチ1
- フィルレット1
これらをプログラムから操作する時、ただ上から順番に舐めるだけでは「どれがどの親に属しているのか」という文脈が分からなくなってしまいます。
「どのフィーチャーの下に、どんな子要素がぶら下がっているのか」を正確に把握する――これが、高度な設計チェッカーや、自動設計ツールを作る上での絶対的な前提条件になります。
—
ツリー構造を攻略する「2つの武器」
SolidWorks APIには、ツリーを渡り歩くための強力なメソッドが用意されています。
1. `Feature.GetFirstSubFeature`
- 「今いるフィーチャーから見て、最初の子要素(サブフィーチャー)を一つ取得する」
2. `Feature.GetNextFeature`
- 「今いるフィーチャーから見て、同じ階層にある次の兄弟フィーチャーを取得する」
この2つのメソッドを組み合わせることで、「兄弟を横に探し、子供を見つけたら奥へ潜る(再帰的アプローチ)」という巡回アルゴリズムが完成します。
—
実践:ツリー構造をイミディエイトウィンドウに描き出すVBAコード
それでは、現在アクティブなドキュメントの履歴ツリーを根こそぎ解析し、その構造をインデント付きで可視化する実用コードを公開します。
開発環境(VBE)の標準モジュールに貼り付けて、そのまま実行してみてください。
‘ ==============================================================================
‘ 【SolidWorks VBA】フィーチャーマネージャー ツリー構造解析マクロ
‘ 概要: アクティブモデルのフィーチャーを再帰的に巡回し、親子関係を解析する
‘ ==============================================================================
Sub Main()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
‘ アプリケーションとアクティブドキュメントの取得
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなモデルが開かれていません。”, vbCritical, “エラー”
Exit Sub
End If
Debug.Print “=== ツリー構造解析開始: ” & swModel.GetTitle & ” ===”
‘ ルート(最上位)のフィーチャーを取得して再帰処理へ
Dim swFeat As SldWorks.Feature
Set swFeat = swModel.FirstFeature
Do While Not swFeat Is Nothing
‘ 再帰プロシージャを呼び出し(インデントレベル0からスタート)
Call TraverseFeature(swFeat, 0)
‘ 次のメインフィーチャーへ移動
Set swFeat = swFeat.GetNextFeature
Loop
Debug.Print “=== ツリー構造解析終了 ===”
MsgBox “ツリー構造の解析が完了しました。イミディエイトウィンドウを確認してください。”, vbInformation, “完了”
End Sub
‘ ——————————————————————————
‘ 亜層・再帰巡回プロシージャ
‘ [引数] swFeat: 対象フィーチャー, indent: 階層の深さ(表示用)
‘ ——————————————————————————
Private Sub TraverseFeature(ByVal swFeat As SldWorks.Feature, ByVal indent As Integer)
If swFeat Is Nothing Then Exit Sub
‘ 1. 現在のフィーチャー情報を取得して出力(インデントで見やすさを演出)
Dim featName As String
Dim featTypeName As String
featName = swFeat.Name
featTypeName = swFeat.GetTypeName2()
‘ 階層に応じたスペースを生成してイミディエイトに出力
Debug.Print Space(indent 4) & “└─ [” & featTypeName & “] ” & featName
‘ 2. サブフィーチャー(子要素)が存在するか確認し、あれば再帰的に潜る
Dim swSubFeat As SldWorks.Feature
Set swSubFeat = swFeat.GetFirstSubFeature
Do While Not swSubFeat Is Nothing
‘ 子要素に対してインデントを1つ深くして自分自身を呼び出す
Call TraverseFeature(swSubFeat, indent + 1)
‘ 次のサブフィーチャー(兄弟)へ移動
Set swSubFeat = swSubFeat.GetNextFeature
Loop
End Sub
—
コードのポイントと「陥りやすい罠」
上記のコードには、SolidWorks APIを扱う上で知っておくべき極意が詰まっています。
1. 「再帰呼び出し(Recursion)」の美しさ
`TraverseFeature` というプロシージャの中で、自分自身を呼び出している点に注目してください。これにより、何階層下に子供がいようとも、無限の深さに対応できるエレガントなコードになっています。
2. ポインタの枯渇と無限ループの恐怖
APIを扱う上で最も恐ろしいのは、オブジェクトの参照切れやメモリリークです。特に `GetNextFeature` を使う際、「もし対象が存在しなくなったら確実にループを抜ける(`Not swFeat Is Nothing`)」というガード条件を怠ると、SolidWorksごとフリーズする地獄(無限ループ)に陥ります。上記のコードは安全弁がしっかり組み込まれているため安心してお使いいただけます。
3. `GetTypeName` と `GetTypeName2` の違い
今回のコードでは `GetTypeName2()` を使用しています。
古い `GetTypeName` は内部的なコード名を返すことが多く人間にとって解読困難ですが、`GetTypeName2` はより分かりやすいタイプ名(”Extrude”、”Fillet”、”RefPlane” など)を返してくれます。ログ解析の精度がグッと上がりますよ。
—
さぁ、次のステージへ
このツリー解析アルゴリズムをマスターすれば、例えば以下のような実務に直結する自動化ツールが作れるようになります。
- 「特定のモデルで、特定のフィーチャー(例:穴あけウィザード)がどのフィーチャーの配下にぶら下がっているか」を自動チェックする設計検証マクロ
- 特定の条件に合致するサブフィーチャーをすべて一括で非表示・抑制にするクリーンアップツール
「画面を操作するマクロ」から、「モデルの構造を理解し、思考するプログラム」へ。
あなたのSolidWorks VBAスキルは、確実に次のステージへと到達しました。
現場でバリバリと自動化を推し進め、周囲をあっと言わせるようなシステムを作り上げてくださいね。応援しています!
