【実務・中級編】【サブアセンブリの動的制御】IComponent2.SetSuppression2とIsFixedによるコンポーネントの高度な状態管理 – SolidWorks VBA解析バイブル

スポンサーリンク

【SolidWorks VBAを掌握する極限の知見】サブアセンブリの動的制御:IComponent2.SetSuppression2とIsFixedによる極限の軽量化と状態管理

開発現場のリーダーである私に、よくこんな悲鳴が聞こえてくる。
「数万点規模の大規模アセンブリを開こうとすると、PCがフリーズする」
「コンフィギュレーションを切り替えて軽量化しているつもりだが、特定の検証時だけに要る部品の制御がVBAで安定しない」

もし君が、アセンブリを開くたびにメモリを食いつぶされ、画面の前でコーヒーをすする時間すら無駄にしているなら、今日のこの記事は君のエンジニア人生を変えることになるだろう。

世に溢れる退屈な入門書は、「マクロの記録」をそのまま貼り付けただけの、実務では使い物にならないゴミコードを量産する。オブジェクトのライフサイクルや、APIの「重み」を理解していないコードは、大規模アセンブリの海原では一瞬で沈没する運命にあるのだ。

今回は、SolidWorks APIの核心の一つである `IComponent2.SetSuppression2``IsFixed` を駆使し、大規模アセンブリを意のままに操る「動的制御」の極意を伝授しよう。

1. なぜ「力技のコンフィギュレーション切り替え」では失敗するのか?

大規模アセンブリの検証において、不要なサブアセンブリを「抑制(Suppression)」してメモリを解放し、計算コストを削るのは定石だ。しかし、これをすべてのパターンに対して手動のコンフィギュレーションで用意しようとすると、PDM上のファイル管理が破綻する。爆発的に増える派生ファイルを想像してほしい。悪夢でしかない。

だからこそ、VBAによる動的制御(オンザフライでの抑制・非抑制・固定制御)が必要となる。
だが、ここで多くの初心者がハマる罠がある。

  • ドキュメントの再構築(Rebuild)のタイミングを無視して、APIが沈黙する
  • コンポーネントの参照切れ(Pathの不一致やインスタンスIDの変化)を考慮していない
  • 固定(Fix)と抑制(Suppression)の依存関係を無視して、アセンブリが暴発する

これらを完全に克服するための設計思想を、コードとともに叩き込む。

2. APIの核心:IComponent2が持つ「重み」と正しい操作

コンポーネントを操作する際、私たちが触れるべきは `ModelDoc2` ではなく、アセンブリのツリー構造を構成する `IComponent2` インターフェースだ。

特に以下の2つのメソッド・プロパティの挙動を正確に把握する必要がある。

1. `SetSuppression2`: コンポーネントの状態(抑制、軽量、完全解決など)を制御する。

  • 引数の定数(`swComponentSuppression_e`)を誤ると、メモリ上にデータが残ったままになり、軽量化の恩恵を受けられない。

2. `IsFixed`: 空間に対する拘束(固定)状態を真偽値で制御する。

  • 抑制されているコンポーネントに対して位置関係を操作しようとすると、APIは容赦なくエラーを吐く。「抑制の解除 -> 配置・固定の制御 -> 必要に応じた再構築」 というライフサイクルの順序が絶対の鉄則だ。

3. 【プロダクションコード】堅牢なサブアセンブリ動的制御モジュール

実務でそのまま使える、極めて堅牢なVBAコードを公開する。
このコードは、指定した名前のサブアセンブリ(またはパーツ)を動的に「非抑制(完全解決)」にし、特定の位置に「固定(Fix)」した上で、全体の再構築を安全に行うプロシージャだ。

Option Explicit

‘ =================================================================================
‘ módulo:
‘ 概要: 指定したコンポーネントの抑制状態と固定状態を動的に制御するプロダクションコード
‘ 著者: チーフアーキテクト
‘ =================================================================================

Public Sub ControlTargetComponentState()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssocDoc As SldWorks.AssemblyDoc
Dim targetCompName As String

‘ 1. アプリケーションおよびアクティブドキュメントの取得
Set swApp = Application.SldWorks
If swApp Is Nothing Then Exit Sub

Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントがありません。”, vbCritical, “エラー”
Exit Sub
End If

‘ アセンブリドキュメントかどうかの型チェック(境界防衛)
If swModel.GetType <> swDocASSEMBLY Then
MsgBox “このマクロはアセンブリドキュメントでのみ実行可能です。”, vbExclamation, “警告”
Exit Sub
End If

Set swAssocDoc = swModel

‘ 制御対象のコンポーネント名(フィーチャマネージャーに表示される名前から拡張子を除いたもの)
‘ 例: “SubAssembly_A-1”
targetCompName = “SubAssembly_A-1”

‘ 2. コンポーネントの取得と動的制御の実行
Dim swComp As SldWorks.Component2
Set swComp = swAssocDoc.GetComponentByName(targetCompName)

If swComp Is Nothing Then
MsgBox “指定されたコンポーネントが見つかりません: ” & targetCompName, vbCritical, “エラー”
Exit Sub
End If

‘ エラーハンドリング開始
On Error GoTo ErrorHandler

‘ 処理高速化のための画面描画停止
swApp.Visible = False
swModel.Extension.SetDatabaseSave False

‘ — ステップ A: 非抑制(完全解決)にする —
‘ swComponentFullyResolved (星マーク状態) または swComponentLight (羽マーク)
‘ 大規模検証のためには完全解決(swComponentFullyResolved=29)が安全
Dim status As Long
status = swComp.SetSuppression2(swComponentFullyResolved)

If status <> 0 Then
Err.Raise vbObjectError + 1000, “ControlComponent”, “コンポーネントの非抑制化に失敗しました。ステータスコード: ” & status
End If

‘ — ステップ B: 固定状態(IsFixed)の制御 —
‘ 一旦固定を解除してから必要に応じて再設定する、あるいは状態をトグルする
If swComp.IsFixed = False Then
swComp.IsFixed = True
End If

‘ — ステップ C: アセンブリの確実な再構築(Rebuild) —
‘ 形状変更や状態変更の後は、強制再構築 (ForceRebuild3) を叩くのがプロの作法
swModel.ForceRebuild3 False

‘ 後処理
swApp.Visible = True
swModel.Extension.SetDatabaseSave True

MsgBox “コンポーネント ‘” & targetCompName & “‘ の動的制御に成功しました。”, vbInformation, “完了”
Exit Sub

ErrorHandler:
‘ 異常系でも必ずUIとデータベースの整合性を復元する
swApp.Visible = True
swModel.Extension.SetDatabaseSave True
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “致命的エラー”
End Sub

4. コードの解説と「現場の知見」

このコードがなぜ優れているのか、エンジニアの視点で解説しよう。

① 境界防衛(Guard Clauses)の徹底

冒頭で `swModel.GetType <> swDocASSEMBLY` をチェックし、パーツドキュメントで誤作動を起こすのを未然に防いでいる。実務の現場では、ユーザーは平気で関係ない画面でマクロを実行する。ここに備えないコードは「未完成のオモチャ」に過ぎない。

② UIとデータベースの凍結(パフォーマンス最適化)

大規模アセンブリを操作する際、グラフィックの再描画(`swApp.Visible = False` や `SetDatabaseSave`)を挟むか挟まないかで、処理時間が数倍〜数十倍変わる。無駄なレンダリングコストを極限まで削ぎ落とすのがプロのエンジニアだ。

③ トランザクション的なエラーハンドリング

`On Error GoTo ErrorHandler` を用いて、万が一の失敗時にも `swApp.Visible = True` やデータベース保存フラグの復元を確実に行うようにしている。これを怠ると、マクロ異常終了後にSolidWorksがフリーズしたままになり、ユーザーに多大なストレスを与えることになる。

5. データベースや外部ファイル連携への発展性

この動的制御を極めれば、エクセル(Excel)や外部データベース(Access / SQL Server / PDMのメタデータ)と連携した「完全自動・検証レスキューシステム」の構築が可能になる。

たとえば、
1. Excelから「どの検証パターンでどのサブアセンブリが必要か」のリスト(CSV/JSON)を読み込む。
2. マクロが動的に必要な部品だけを `SetSuppression2(swComponentFullyResolved)` で呼び出し、不要なパーツを `swComponentSuppression_e.swComponentSuppressed` で消し去る。
3. そのまま干渉チェック(Collision Detection)や質量特性の算出をAPI経由で自動実行し、結果をデータベースに吐き出す。

ここまで作り込むことができれば、設計検証工数を従来の 1/10以下 に圧縮することも夢ではない。

最後に:エンジニアとしての誇りを持て

VBAは「おもちゃの言語」などと揶揄されることがある。しかし、SolidWorks APIを正しく理解し、メモリ管理とオブジェクトのライフサイクルをコントロールしたVBAコードは、C#やVB.NETで書かれたアドインと同等、あるいはそれ以上に現場の課題を瞬時に解決する「最強の武器」となる。

今回の記事で紹介した `SetSuppression2` と `IsFixed` の制御構造をマスターし、君の職場の非効率な手作業を根絶やしにしてほしい。

さらなる高みを目指すエンジニアからの挑戦状や質問は、いつでも歓迎する。限界を超えていこう。

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