【実務・中級編】【実務中級】アセンブリ内のすべての非表示部品の状態を一時保存し、特定の検査工程後に元の表示状態へ復元するマクロ – SolidWorks VBA解析バイブル

スポンサーリンク

【SolidWorks VBA】アセンブリの表示状態を「完全復元」するプロフェッショナルな設計術

SolidWorks APIを扱うエンジニアにとって、アセンブリの状態管理は避けて通れない関門だ。特に、特定の検査工程で非表示部品を一時的に強制表示させ、その後「元の状態に完全に戻す」という処理は、一見単純だが、甘く見ると必ずバグを招く。

なぜなら、アセンブリの表示状態はコンポーネント単体のフラグだけでなく、表示状態(Display States)やコンフィギュレーションとの相関で決定されるからだ。今回は、現場で「動けばいい」レベルを卒業し、堅牢かつ保守性の高い「状態復元アーキテクチャ」を伝授する。

—

1. なぜ「力技」での復元は失敗するのか?

多くの初学者が陥るミスは、コンポーネントをループして `Component.Visible` プロパティを直接操作し、それを配列に保存しようとすることだ。

  • 問題点1: コンポーネントが非表示の際、その「親」が非表示である場合、子コンポーネントを強制表示させてもアセンブリ上で反映されないケースがある。
  • 問題点2: 実行中にコンフィギュレーションが切り替わると、復元先を見失う。
  • 問題点3: 処理中のエラーでマクロが中断されると、表示状態が「変更されたまま」で放置され、ユーザーが手動で復元しなければならなくなる。

我々プロフェッショナルは、「状態の保存(Snapshot)」と「例外処理(Error Handling)」を分離し、トランザクションとして設計する必要がある。

—

2. 実装コード:堅牢な表示状態の管理クラス

以下は、`Dictionary` オブジェクトを用いて、コンポーネントのパスをキーに、表示状態を安全にバックアップ・復元するプロダクションコードだ。

Option Explicit

‘ — 状態復元のためのメインプロシージャ —
Public Sub ExecuteTaskWithRestoration()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssy As SldWorks.AssemblyDoc

Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc

If swModel.GetType <> swDocASSEMBLY Then Exit Sub
Set swAssy = swModel

‘ 状態保存用辞書
Dim compStates As Object
Set compStates = CreateObject(“Scripting.Dictionary”)

On Error GoTo ErrorHandler

‘ 1. 現在の状態を保存
Call SaveVisibilityState(swAssy, compStates)

‘ 2. 検査・解析工程(例:全部品を強制表示)
swAssy.ShowAllComponents
Debug.Print “解析中:すべての部品を表示しました。”

‘ — ここに本来の業務ロジックを記述 —

‘ 3. 状態を復元
Call RestoreVisibilityState(swAssy, compStates)

Exit Sub

ErrorHandler:
MsgBox “予期せぬエラー発生。表示状態を強制復元します。”, vbCritical
RestoreVisibilityState swAssy, compStates
End Sub

‘ — 非表示コンポーネントの状態保存 —
Private Sub SaveVisibilityState(assy As SldWorks.AssemblyDoc, dict As Object)
Dim comps As Variant
comps = assy.GetComponents(False)

Dim i As Long
Dim comp As SldWorks.Component2

For i = 0 To UBound(comps)
Set comp = comps(i)
‘ コンポーネントの表示状態を取得 (1: 表示, 0: 非表示)
If comp.Visible = 0 Then
dict.Add comp.GetPathName, comp.Visible
End If
Next i
End Sub

‘ — 状態復元 —
Private Sub RestoreVisibilityState(assy As SldWorks.AssemblyDoc, dict As Object)
Dim comps As Variant
comps = assy.GetComponents(False)

Dim i As Long
Dim comp As SldWorks.Component2

For i = 0 To UBound(comps)
Set comp = comps(i)
‘ 辞書に存在すれば(非表示対象であれば)、復元
If dict.Exists(comp.GetPathName) Then
comp.Visible = dict(comp.GetPathName)
End If
Next i

assy.ForceRebuild3 False
End Sub

—

3. 設計のポイントと技術的知見

A. `Scripting.Dictionary` の採用

配列ではなく `Dictionary` を使用することで、検索時間を O(1) に抑えている。大規模アセンブリにおいて、数千個の部品に対してインデックスでループを回すのは愚策だ。パス名をキーにすることで、コンポーネントの順序が入れ替わっても正確に復元できる。

B. `On Error GoTo` によるトランザクションの保護

業務自動化ツールの最大の罪は「中途半端な状態でマクロが止まること」だ。必ず `ErrorHandler` を経由させ、エラーが発生しても `RestoreVisibilityState` が確実に呼ばれる設計にしている。これは、製造現場のエンジニアに対する最低限の礼儀である。

C. パフォーマンスへの配慮

`ForceRebuild3` は重い処理だ。状態復元のループ内で何度も呼び出すのではなく、最後に一回だけ実行するように設計している。APIの呼び出し回数は、そのままツールが「重い」か「速い」かを決定する要因となる。

—

結びに代えて

自動化とは、単にコードを書くことではない。「作業者が本来行うべき『元の状態に戻す』という管理コストを、マクロに肩代わりさせること」である。

今回紹介したコードは、単なるスニペットではなく、「例外時にもシステムを整合性の取れた状態へ戻す」という設計思想の具現化だ。この構造をベースにすれば、表示状態だけでなく、色、コンフィギュレーション、抑制状態など、あらゆる属性のバックアップ・復元に応用が可能になるだろう。

君の作るツールが、現場のストレスを一つでも減らすことを期待している。次回の設計も、妥協のないものを期待してほしい。

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