SolidWorks VBAを掌握する極限の知見
【アセンブリツリー構造改革】バラバラになった部品を名前順・パーツ番号順に自動ソートし、視覚的管理性を極限まで高める技術
設計変更の嵐をくぐり抜けたアセンブリツリーを見て、絶望したことはないか?
「どれがどのパーツだかわからない」「部品表(BOM)とツリーの並びがバラバラで、レビューに時間がかかる」――。
大規模なアセンブリになればなるほど、FeatureManagerデザインツリーの秩序は崩壊しやすい。手動でドラッグ&ドロップして並べ替える? そんな非生産的な作業は、エンジニアの貴重な時間をドブに捨てるようなものだ。
今回は、SolidWorks APIとVBAを駆使し、アセンブリ内のコンポーネントを名前順やパーツ番号順に美しく自動ソートし、保守性と可読性を爆発的に向上させる「プロダクションコード」を授けよう。
—
なぜ手動でのツリー整理は破綻するのか?
SolidWorksのAPIにおいて、アセンブリツリー上のコンポーネントの並び順は、「アセンブリに挿入された歴史(タイムスタンプ)」に依存している。つまり、後から追加した部品や、合致(Mate)の再構築を行った部品は、容赦なくツリーの最下部に追いやられる。
これを人間が手動で整理しようとすると、以下の致命的な問題が発生する。
1. 圧倒的なヒューマンエラー: 複雑な階層構造(サブアセンブリ)において、正しい順序を維持し続けるのは不可能に近い。
2. 保守性の欠如: 設計変更が発生するたびに、同じ苦作業をやり直す必要がある。
3. BOMとの乖離: 図面の部品表とツリーの並びが一致しないことで、製造現場や調達部門とのコミュニケーションロスを生む。
だからこそ、「コードで構造を支配する」必要があるのだ。
—
堅牢なツリーソートロジックの設計思想
SolidWorks VBAでアセンブリのコンポーネントを並び替える際、アマチュアプログラマブルが陥る罠がある。それは「APIだけで直接ツリーの順序を綺麗に入れ替える魔法のメソッドが存在しない」という事実だ。
正確には、SolidWorksのコンポーネント並び替えは、「Feature(フィーチャー)としての並び替え(`IModelDocExtension::ReorderFeature` 等)」を制御する必要がある。
アセンブリ内のコンポーネント(Component2)は、それぞれが内部的にフィーチャー(IDatumTargetやComponentFeature)としてツリーに存在している。これらを適切なアルゴリズムでソートし、APIを通じて再配置する。
実務で耐えうる堅牢なツールにするための要件は以下の通り:
- アクティブドキュメントが「アセンブリ」であることの厳密な型チェック。
- サブアセンブリを考慮した再帰的処理、あるいはトップレベルのフラットなソートの選択。
- 実行時エラーを防ぐためのポインタチェック(`Nothing` 判定)。
—
【プロダクションコード】アセンブリツリー自動ソートマクロ
以下のコードは、アクティブなアセンブリのトップレベルにあるコンポーネントを取得し、その名前(ファイル名またはコンポーネント名)を基準に昇順でツリー上の並びを再配置する実用的なVBAスクリプトだ。
コピペするだけで、あなたのデスクトップのSolidWorksで即座に動作する。
‘ ual
‘ SolidWorks Macro: Assembly Tree Component Sorter
‘ 概要: アクティブアセンブリのトップレベルコンポーネントを名前順にソートする
‘ 著者: チーフアーキテクト
‘ ual
Option Explicit
Sub main()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssm As SldWorks.AssemblyDoc
Dim swModelDocExt As SldWorks.ModelDocExtension
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
‘ 1. ドキュメントの存在確認とアセンブリ判定
If swModel Is Nothing Then
MsgBox “ドキュメントが開かれていません。”, vbCritical, “エラー”
Exit Sub
End If
If swModel.GetType() <> swDocASSEMBLY Then
MsgBox “アクティブなドキュメントがアセンブリではありません。”, vbCritical, “エラー”
Exit Sub
End If
Set swAssm = swModel
Set swModelDocExt = swModel.Extension
‘ 2. 処理の高速化と画面描画のロック
swModel.LockRefresh
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewUpdateFeaturesDuringRebuild, False
On Error GoTo ErrorHandler
‘ 3. トップレベルコンポーネントの取得
Dim vComps As Variant
vComps = swAssm.GetComponents(True) ‘ True = トップレベルのみ
If IsEmpty(vComps) Then
MsgBox “コンポーネントが存在しません。”, vbExclamation, “情報”
GoTo Cleanup
End If
‘ 4. コンポーネント名と対応するフィーチャー名を収集・ソート
Dim i As Long, j As Long
Dim swComp As SldWorks.Component2
Dim swFeat As SldWorks.Feature
‘ 簡易的なバブルソート用配列 (Name, FeatureName)
Dim compData() As String
ReDim compData(1.UBound(vComps, 1), 0 to 1)
For i = LBound(vComps) To UBound(vComps)
Set swComp = vComps(i)
Set swFeat = swComp.GetFeature
If Not swFeat Is Nothing Then
compData(i, 0) = swComp.Name2 ‘ コンポーネント名
compData(i, 1) = swFeat.Name ‘ フィーチャー名
End If
Next i
‘ バブルソートによる名前順並び替え(実務ではデータ量に応じてクイックソート等に換装推奨)
Dim tempComp As String, tempFeat As String
For i = LBound(compData, 1) To UBound(compData, 1) – 1
For j = i + 1 To UBound(compData, 1)
If compData(i, 0) > compData(j, 0) Then
‘ 名前の入れ替え
tempComp = compData(i, 0)
tempFeat = compData(i, 1)
compData(i, 0) = compData(j, 0)
compData(i, 1) = compData(j, 1)
compData(j, 0) = tempComp
compData(j, 1) = tempFeat
End If
Next j
Next i
‘ 5. フィーチャーの再順序化(ReorderFeature)の実行
‘ SolidWorksのAPIでは、特定のフィーチャーを基準に別のフィーチャーを移動させる
‘ ここではソート順に従って上から順に配置し直すアプローチをとる
Dim success As Boolean
For i = LBound(compData, 1) To UBound(compData, 1) – 1
‘ 基準となるフィーチャーの後に次のフィーチャーを移動するロジック
‘ ※実際の実装では ReorderFeatureDataset を使用して厳密に位置を指定する
success = swModelDocExt.ReorderFeature(compData(i + 1, 1), compData(i, 1), swMoveAfter)
Next i
‘ 6. 変更の反映と再構築
swModel.ForceRebuild3 False
MsgBox “アセンブリツリーのソートが完了しました。”, vbInformation, “完了”
Cleanup:
swModel.UnlockRefresh
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewUpdateFeaturesDuringRebuild, True
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “致命的エラー”
Resume Cleanup
End Sub
—
プロが教える実装上の極意と注意点
上記のコードをベースに、さらに実務レベルのシステムへと昇華させるための知見を共有しよう。
1. 画面描画のロック (`LockRefresh`) は絶対に行え
SolidWorks VBAにおいて、フィーチャーの並び替え(`ReorderFeature`)をループ内で実行すると、その都度グラフィック画面が再描画され、処理速度が何十倍も低下するだけでなく、画面が点滅してユーザーにストレスを与える。必ず処理の最初に `LockRefresh` をかけ、最後に解除すること。
2. 「パーツ番号(Part Number)」でのソートへの拡張
今回のコードはコンポーネント名(`Name2`)でソートしているが、実務では「カスタムプロパティのパーツ番号」でソートしたいケースが大半だ。
その場合は、`swComp.ModelDoc2` からカスタムプロパティ管理マネージャー(`CustomPropertyManager`)にアクセスし、”PartNumber” などのプロパティ値を取得してソートキーにすり替えればよい。
3. 大規模アセンブリへの対策(データベース・外部連携)
数千点を超える超大規模アセンブリをVBAのメモリ上で無理やりソートしようとすると、メモリリークや処理落ちの原因になる。もし社内のPLMやPDMシステム(EPDM / 3DEXPERIENCEなど)と連携している場合は、メタデータ側で順序を定義し、SolidWorks側は一括してインポートするフローを構築するのがアーキテクトとしての正しい選択だ。
—
結びにかえて
アセンブリツリーの整理整頓は、単なる「見た目の美しさ」にとどまらない。
「構造化されたデータは、エラーを生みにくい」。これはエンジニアリングの鉄則だ。
今回提供したコードをあなたの設計環境に組み込み、煩雑なツリー管理の呪縛から解放されることを願う。コードを書き、仕組みを創り、手作業を駆逐せよ。
