【実務・中級編】【履歴ツリー構造の解析】Feature.GetFirstSubFeatureとGetNextFeatureを使ったフィーチャー巡回アルゴリズム – SolidWorks VBA解析バイブル

スポンサーリンク

【SolidWorks VBAを掌握する極限の知見】履歴ツリー構造の解析:Feature.GetFirstSubFeatureとGetNextFeatureを使った再帰的巡回アルゴリズム

こんにちは。開発プロジェクトの現場において、数々のCAD自動化の修羅場をくぐり抜けてきたチーフアーキテクトの私だ。

SolidWorks VBAのスキルを「マクロの記録の延長」から「堅牢なエンジニアリング」へと引き上げる時、避けて通れない最大の壁が「フィーチャーマネージャー・デザインツリー(履歴ツリー)の構造解析」である。

ネット上の散見されるサンプルコードの多くは、フラットな `GetFirstFeature` と `GetNextFeature` の無限ループに頼り、サブフィーチャー(フィレットの複数エッジ、パターンのインスタンス、フォルダ内の要素など)の階層構造を無視している。その結果、複雑なモデルを投入した瞬間にフリーズするか、重要なデータをドロップするバグを生む。

今回は、ツリーの親子関係を完全に把握し、実務のデータベース連携や自動設計検証に耐えうる、極限まで洗練された再帰的巡回アルゴリズムを伝授しよう。

1. なぜ「平坦な巡回」では実務で使い物にならないのか?

SolidWorksのAPIにおいて、モデルのフィーチャー構造は単なるリストではない。「木構造(Tree Structure)」だ。

親フィーチャー(例:スイープ、ロフト、あるいはフォルダー)の下には、子フィーチャーやサブフィーチャーがぶら下がっている。これを通常の `GetNextFeature` だけですべて取得しようとすると、以下の致命的な問題が発生する。

1. サブフィーチャーの取りこぼし:
マルチボディのカットや、単一フィーチャー内に内包される子要素(SubFeature)を見落とす。
2. コンテキストの喪失:
「どの親から派生した要素なのか」という階層関係(親子関係)が失われ、設計意図の解析や履歴のクリーンアップが不可能になる。
3. COMオブジェクトのメモリリーク:
VBA特有の参照管理の甘さから、階層を深く潜った際にメモリリークやポインタの解放漏れによるクラッシュが誘発される。

真にプロフェッショナルなマクロを書くのであれば、「深さ優先探索(DFS: Depth-First Search)」による再帰関数を構築しなければならない。

2. 堅牢なツリー解析のコア:API選定の極意

ツリーを巡回する際、以下の3つのメソッドを正確に使い分ける必要がある。

  • `ModelDoc2::FirstFeature`: ツリーの最上位(履歴の最初)のフィーチャーを取得する。
  • `Feature::GetNextFeature`: 同じ階層における「次の兄弟」フィーチャーを取得する。
  • `Feature::GetFirstSubFeature`: そのフィーチャーが持つ「最初の子(サブフィーチャー)」を取得する。

これらを組み合わせ、「兄弟を横に舐めつつ、子を見つけたら再帰的に潜る」というアルゴリズムを実装する。

3. 【プロダクションコード】実務対応・再帰的ツリー解析マクロ

以下のコードは、アクティブなモデルの履歴ツリーを根元から走査し、各フィーチャーの名称、タイプ、そして階層の深さ(Indentation)をイミディエイトウィンドウに出力、さらにCSV等へのデータ連携を見据えた構造化を行う実用コードだ。

‘ =========================================================================
‘ モジュール名: ModTreeInspector
‘ 概要 : SolidWorks 履歴ツリー再帰解析エンジン
‘ 著作権 : 業務自動化アーキテクト
‘ =========================================================================
Option Explicit

Public Sub RunFeatureTreeInspection()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim startTime As Double

startTime = Timer

‘ 1. アプリケーションとドキュメントの安全な取得
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc

If swModel Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。”, vbCritical, “エラー”
Exit Sub
End If

Debug.Print “=== ツリー解析開始: ” & swModel.GetPathName & ” ===”

‘ 2. 再帰処理の実行
Call TraverseTree(swModel.FirstFeature, 0)

Debug.Print “=== ツリー解析終了 (処理時間: ” & Format(Timer – startTime, “0.00秒”) & “) ===”
End Sub

‘ ————————————————————————-
‘ 関数名 : TraverseTree
‘ 概要 : 再帰的にフィーチャーを巡回するコアプロシージャ
‘ 引数 : swFeat – 対象フィーチャー, depth – 階層の深さ
‘ ————————————————————————-
Private Sub TraverseTree(ByVal swFeat As SldWorks.Feature, ByVal depth As Long)
Dim swSubFeat As SldWorks.Feature
Dim indent As String
Dim featName As String
Dim featType As String

‘ 階層に応じたインデントの生成(可視化用)
If depth > 0 Then
indent = String(depth 4, ” “) & “┣ ”
Else
indent = “”
End If

‘ ループの安全装置(フィーチャーがNothingなら抜ける)
Do While Not swFeat Is Nothing
On Error Resume Next
featName = swFeat.Name
featType = swFeat.GetTypeName2
On Error GoTo 0

‘ — [実務データ連携ポイント] —
‘ ここでデータベースへの書き込みや、特定の条件判定を行う
Debug.Print indent & “[” & featType & “] ” & featName

‘ 3. サブフィーチャー(子)が存在する場合は再帰的に潜る
Set swSubFeat = swFeat.GetFirstSubFeature
If Not swSubFeat Is Nothing Then
‘ 子階層を処理するため、depthをインクリメントして再帰呼び出し
Call TraverseTree(swSubFeat, depth + 1)
End If

‘ 4. 次の兄弟フィーチャーへ移動
Set swFeat = swFeat.GetNextFeature
Loop
End Sub

4. チーフアーキテクトが教える、バグを防ぐための設計上の注意点

このコードを実際の業務システムや大規模アセンブリ(数千部品)に適用する際、以下のポイントを抑えておかないと現場で痛い目を見る。

① 参照の循環とメモリ管理

VBAはガベージコレクションが特殊であるため、再帰呼び出しにおいてローカル変数として宣言した `SldWorks.Feature` オブジェクトは、スコープを抜ける際に自動解放される。しかし、グローバル変数に長期間保持し続けるとメモリリークの原因になる。必要な情報(名前やタイプなど)はプリミティブ型(StringやLong)に早期に変換し、オブジェクトへの参照を不必要に保持しないこと。

② 非表示・内部フィーチャー(Transient Features)の扱い

SolidWorksのツリーには、ユーザーが見るべきではない内部管理用のフィーチャー(`Origin` や 座標系、解析用フィーチャーなど)が含まれている場合がある。
必要に応じて `swFeat.IsSuppressed` の判定や、特定の `featType`(例: `”Auxiliary”` や `”FtrFolder”` など)をフィルタリングするロジックを `TraverseTree` 内に組み込むと、実務で使いやすいクリーンなデータが得られる。

③ データベース・外部ファイル連携への拡張

この再帰アルゴリズムで取得した `featName` と `featType` を、JSON形式でファイル出力したり、ADODB経由でSQL ServerやSQLiteなどのデータベースに直接インサートするように改造すれば、「全CADモデルの標準化チェックツール」「社内設計チェッカー」へと直結させることができる。

5. 結びに代えて

SolidWorks VBAの真髄は、APIのメソッドを覚えることではなく、「CADモデルが持つデータ構造のトポロジー(位相)を正しく理解し、コード上で美しく模倣すること」にある。

今回解説した `GetFirstSubFeature` と再帰呼出しのテクニックをマスターすれば、いかに複雑な履歴を持つモデルであっても、意のままに解析・操作できるようになるだろう。

あなたの開発するツールが、現場のエンジニアたちの手数を劇的に減らす強力な武器になることを確信している。健闘を祈る。

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