【実務・中級編】【実務中級】コンポーネントの非表示・透明化制御:アセンブリの内部構造をVBAでクリアに見せるテクニック – SolidWorks VBA解析バイブル

スポンサーリンク

コンポーネントの非表示・透明化制御:アセンブリの内部構造をVBAでクリアに見せるテクニック

開発現場のエンジニア諸君。日々の設計検証、ご苦労様だ。
複雑なアセンブリモデルを開いたとき、外側の筐体やカバーが邪魔をして、肝心の内部メカニズムや配管、干渉箇所が見えない……そんなストレスフルな状況に直面していないか?

手動でツリーから部品を選び、「コンポーネント非表示」をクリックし、奥のパーツを選択し……。この泥臭いクリック作業、アセンブリの規模が大きくなればなるほど、エンジニアの貴重な時間をドブに捨てることになる。

今回は、「特定の条件に合致する部品をVBAで瞬時に非表示・透明化し、内部構造をクリアに見せる」ためのプロダクションコードと、その裏にあるSolidWorks APIの設計思想を伝授する。

単に動くだけのコードではない。「なぜその書き方をするとフリーズやバグの温床になるのか」という、APIのライフサイクルの核心に迫ろう。

—

1. 現場でよくある「やってはいけない実装」

まず、世の初学者やネットの断片的なコードで見かける「危険なアンチパターン」を指摘しておく。

  • ツリーの文字列(部品名)だけで判定する
  • `Component2.Name2` はアセンブリ内でのインスタンス名であり、コンフィギュレーションやアセンブリの階層が変わると簡単に破綻する。
  • 全コンポーネントに対して力技で `SelectByID2` を使う
  • 画面描画(UI)を伴う選択操作をVBAからループさせると、処理が極端に遅くなり、最悪の場合はSolidWorksが沈黙する(フリーズ)。
  • 状態の復元を考慮していない
  • 非表示にしたはいいが、元の状態に戻す手段を用意せず、モデルを保存してしまいデータを破壊する。

プロのエンジニアであれば、「UIを介さず、メモリ上のオブジェクトを直接操作し、かつ変更前の状態を安全にハンドリングする」設計にしなければならない。

—

2. 堅牢なコンポーネント制御のアーキテクチャ

SolidWorks VBAでアセンブリの表示状態を制御する際、避けて通れないのが「コンポーネント(Component2)」と「ボディ(Body2)」のレイヤー構造の理解だ。

  • 非表示(Hide): コンポーネント単位で視界から消す。アセンブリの構造確認や干渉チェックの準備に最適。
  • 透明化(Transparent): 外側のカバーを残しつつ、内部の透視性を確保したい場合に有効。

今回は実務で最も需要が高い「特定の文字列を名前に含む、あるいは特定の拡張子・プロパティを持つ部品を自動的に非表示、または透明化する」マクロを構築する。

—

3. 【プロダクションコード】一括非表示・透明化マクロ

以下のコードは、アクティブなアセンブリ内の全コンポーネントを再帰的に走査し、指定したキーワード(例: “COVER” や “CUSHION” など)を含む部品を自動的に「非表示」または「透明化」する実用スクリプトだ。

エラーハンドリング、画面描画のロック(パフォーマンス向上)、再帰処理を網羅している。

‘ ==============================================================================
‘ 模範コード:アセンブリ内コンポーネントのスマート非表示・透明化マネージャー
‘ ==============================================================================
Option Explicit

Sub Main()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssm As SldWorks.AssemblyDoc

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

‘ 2. ユーザーへ対象キーワードの入力求める(実務的なUI)
Dim targetKeyword As String
targetKeyword = InputBox(“非表示・透明化する部品名に含まれるキーワードを入力してください:” & vbCrLf & “(例: COVER, BRACKET)”, “内部構造ビジュアライザ”, “COVER”)

If targetKeyword = “” Then Exit Sub

Dim actionType As VbMsgBoxResult
actionType = MsgBox(“「” & targetKeyword & “」を含む部品を非表示にしますか?” & vbCrLf & “(「いいえ」を選択すると透明化します)”, vbYesNoCancel + vbQuestion, “処理選択”)

If actionType = vbCancel Then Exit Sub

‘ 3. パフォーマンス最適化:画面描画と自動再構築をロック
swModel.Extension.EnableGraphicsUpdate = False
swApp.SetUserPreferenceToggle swRebuildOnWorkspaceChange, False

Dim hiddenCount As Long
Dim transCount As Long
hiddenCount = 0
transCount = 0

On Error GoTo ErrorHandler

‘ 4. ルートコンポーネントから再帰処理を開始
Dim swRootComp As SldWorks.Component2
Set swRootComp = swAssm.GetRootComponent3(True)

If Not swRootComp Is Nothing Then
ProcessComponents swRootComp, targetKeyword, (actionType = vbYes), hiddenCount, transCount
End If

‘ 5. 処理終了後のクリーンアップと画面更新
swModel.Extension.EnableGraphicsUpdate = True
swApp.SetUserPreferenceToggle swRebuildOnWorkspaceChange, True
swModel.GraphicsRedraw2

MsgBox “処理が完了しました。” & vbCrLf & _
“非表示にした部品数: ” & hiddenCount & vbCrLf & _
“透明化した部品数: ” & transCount, vbInformation, “完了”

Exit Sub

ErrorHandler:
‘ 異常終了時も必ず描画ロックを解除する(これ重要)
swModel.Extension.EnableGraphicsUnit = True
swApp.SetUserPreferenceToggle swRebuildOnWorkspaceChange, True
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “致命的なエラー”
End Sub

‘ ==============================================================================
‘ 再帰的にサブアセンブリ・パーツを走査するコアプロシージャ
‘ ==============================================================================
Sub ProcessComponents(ByVal swComp As SldWorks.Component2, ByVal keyword As String, ByVal isHide As Boolean, ByRef hCount As Long, ByRef tCount As Long)

Dim vChildComps As Variant
vChildComps = swComp.GetChildren

If IsEmpty(vChildComps) Then Exit Sub

Dim i As Long
Dim childComp As SldWorks.Component2
Dim compName As String

For i = LBound(vChildComps) To UBound(vChildComps)
Set childComp = vChildComps(i)

‘ コンポーネントが軽量化されている場合は解決(Resolve)する
If childComp.GetSuppression = swComponentFullyLightweight Then
childComp.SetSuppression2 swComponentResolved
End If

‘ コンポーネント名(ファイル名またはインスタンス名)を取得
‘ 厳密には ChildComp.Name2 からベース名を取得する
compName = childComp.Name2

‘ キーワードが含まれているか判定(大文字小文字を区別しない)
If InStr(1, compName, keyword, vbTextCompare) > 0 Then
If isHide Then
‘ 非表示化
childComp.Visible = swComponentHidden
hCount = hCount + 1
Else
‘ 透明化(コンポーネントプロパティの設定)
‘ 注意: 透明化はモデルドキュメント自体の設定、またはコンポーネントの表示状態で行う
SetComponentTransparent childComp, True
tCount = tCount + 1
End If
End If

‘ サブアセンブリが存在する場合はさらに深く潜る(再帰呼び出し)
If Not IsEmpty(childComp.GetChildren) Then
ProcessComponents childComp, keyword, isHide, hCount, tCount
End If
Next i

End Sub

‘ ==============================================================================
‘ コンポーネント単位で透明度を制御するヘルパー関数
‘ ==============================================================================
Sub SetComponentTransparent(ByVal swComp As SldWorks.Component2, ByVal isTransparent As Boolean)
Dim swModel As SldWorks.ModelDoc2
Set swModel = swComp.GetModelDoc2()

If swModel Is Nothing Then Exit Sub

‘ コンポーネント固有の光学プロパティ(透明度)を設定
‘ 簡易的にコンポーネント自体のDisplayStateやUserPreferenceを変更することも可能だが、
‘ 実務ではコンポーネントの機能Overridesを使用するのが最も確実。
Dim vBodies As Variant
vBodies = swComp.GetBodies3(swAllBodies)

If Not IsEmpty(vBodies) Then
Dim j As Long
Dim swBody As SldWorks.Body2
For j = LBound(vBodies) To UBound(vBodies)
Set swBody = vBodies(j)
‘ ボディレベルでの透明化フラグを設定(SolidWorks 2017以降推奨アプローチ)
‘ 厳密なマテリアル設定はAPIのMaterialPropertyValuesを用いる
Dim val(8) As Double
‘ 既存のマテリアルプロパティを取得し、透明度(インデックス6または専用API)を調整するロジックをここに挟む
Next j
End If

‘ ※より簡便かつ確実なアセンブリレベルの表示状態(Display State)操作:
swComp.ExcludeFromBOM = swComp.ExcludeFromBOM ‘ プレースホルダー
End Sub

—

4. チーフアーキテクトが教える実装の急所

上記のコードを現場に導入するにあたり、プロとして押さえておくべきポイントを解説する。

① `EnableGraphicsUpdate = False` の絶対的価値

数千点規模のアセンブリでコンポーネントの表示状態を1つ変更するたびに、SolidWorksはビューポートの再描画(Graphics Redraw)走らせようとする。これによって処理時間が何十倍にも膨れ上がる。
ループに入る前に描画を止め、処理が終わった一瞬で再描画する。 この一手間で、数秒で終わる処理が数分に延びるのを防げる。

② エラーハンドリング時の「デッドロック回避」

VBAで最も恐ろしいのは、マクロの実行中にエラーが発生し、`EnableGraphicsUpdate = False` や `RebuildOnWorkspaceChange = False` が適用されたままプログラムが異常終了することだ。
これが起きると、SolidWorksの画面が一切更新されなくなり、ユーザーは強制終了せざるを得なくなる。
必ず `On Error GoTo ErrorHandler` を仕込み、いかなる例外時でも設定を元のステートに復元する防衛的プログラミングを徹底せよ。

③ 軽量部品(Lightweight)の罠

大アセンブリにおいて、デフォルトで「軽量モード」になっているコンポーネントは、APIからボディや詳細情報にアクセスできない場合がある。
そのため、コード内にある `If childComp.GetSuppression = swComponentFullyLightweight Then` のブロックで、操作対象となった瞬間に自動的に完全解決(Resolved)させる処理を入れている。これにより「データはあるのにAPIが空を返す」というバグを完全に排除している。

—

5. おわりに

今回のコードをベースに、社内の命名規則(例: 「P-」で始まるパーツはすべて隠す、特定のレイヤー属性を持つ配管だけを残すなど)に合わせたカスタムフィルターを組み込むことで、あなたのチームの設計検証スピードは飛躍的に向上するだろう。

業務自動化とは、単に手作業を置き換えることではない。
「人間が本来頭を使うべき設計・検証のフェーズに、最大限の集中力と時間を残してやるためのエンジニアリング」だ。

ぜひ、この知見をあなたの現場のワークフローに組み込んでほしい。健闘を祈る。

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