【テクニカル・上級編】【実務中級】コンフィギュレーション(構成部品の切り替え)をVBAからアセンブリ全体に適用する方法 – SolidWorks VBA解析バイブル

スポンサーリンク

SolidWorks VBAを掌握する極限の知見

【実務中級】コンフィギュレーション(構成部品の切り替え)をVBAからアセンブリ全体に適用する方法

アセンブリの設計自動化において、最も頻繁に直面し、かつ最もリソースを消耗する作業の一つが「構成部品(Component)のコンフィギュレーション切り替え」である。

「製品バリエーションごとにアセンブリを保存し直し、個別の部品コンフィギュレーションを手動でポチポチと切り替えている」
もしあなたの現場で未だにこのような前時代的なワークフローがまかり通っているならば、それはエンジニアリングの怠慢であり、システム化による解決が急務である。

今回は、SolidWorks APIのオブジェクトモデルの深層に切り込み、アセンブリ内の特定部品に対してVBAから動的にコンフィギュレーションを割り当て、バリエーション違いのモデルをミリ秒単位で生成する極限の知見を公開する。

—

1. 現場を崩壊させる「コンポーネント参照」の罠

多くのVBA初心者が陥る最初の罠が、`ModelDoc2` と `Component2` の混同だ。
アセンブリ内の部品(Component)のコンフィギュレーションを変更する場合、「アセンブリを開いた状態で、対象のコンポーネントオブジェクトに対し直接コンフィギュレーションを指定する」必要がある。

個別部品のドキュメント(.sldprt)を背後で開いてコンフィギュレーションをアクティブにし、それをアセンブリに反映させようとするアプローチは、メモリ効率の観点からも、処理速度の観点からも最悪のアンチパターンである。

SolidWorks APIにおいて、アセンブリを構成する各インスタンスは `Component2` インターフェースとして管理されている。親アセンブリのコンテキストを維持したまま、この `Component2` レベルでコンフィギュレーションの切り替えを指示するのが、プロフェッショナルなアーキテクチャの基本要件となる。

—

2. 実務仕様:アセンブリ全体を一括走査し、条件に応じてコンフィギュレーションを適用するVBAコード

以下のコードは、アクティブなアセンブリ内の全コンポーネントを再帰的に走査し、指定した部品名(あるいは特定のプレフィックスを持つ部品)に対して、ターゲットとなるコンフィギュレーション名をプログラムから強制適用する実用コードである。

メモリリークを完全に防ぐためのオブジェクト解放の作法(`Set … = Nothing` の徹底)も組み込んである。

Option Explicit

‘ ==============================================================================
‘ 担当領域: アセンブリ内の特定部品コンフィギュレーション一括置換エンジン
‘ 概要: アクティブアセンブリのコンポーネントツリーを走査し、
‘ 指定されたパーツに対して任意のコンフィギュレーションを割り当てる。
‘ ==============================================================================
Sub ExecuteConfigurationSwitch()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssocModel As SldWorks.AssemblyDoc

‘ 1. セッションの確立
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc

‘ アセンブリドキュメント以外では即座に処理を中断
If swModel Is Nothing Then
MsgBox “ドキュメントが開かれていません。”, vbCritical
Exit Sub
End If

If swModel.GetType <> swDocASSEMBLY Then
MsgBox “アクティブなドキュメントはアセンブリではありません。”, vbCritical
Exit Sub
End If

Set swAssocModel = swModel

‘ 2. 処理対象の設定(実務では外部CSVやINIファイルから読み込むことを推奨)
Const TARGET_PART_NAME As String = “Bracket-A” : Rem 変更対象の部品名(拡張子なし)
Const TARGET_CONFIG_NAME As String = “HeavyDuty_Spec” : Rem 適用したいコンフィギュレーション名

Dim successCount As Long
successCount = 0

‘ 3. 処理の開始(パフォーマンス向上のための画面描画停止)
swModel.Visible = False
swApp.GetUserPreferenceToggle(swUserPreferenceToggle_e.swViewDisplayHideAllTypes) = True

‘ 4. コンポーネントツリーの再帰的走査と適用
Dim vComps As Variant
vComps = swAssocModel.GetComponents(False) ‘ False = トップレベルおよびサブアセンブリ内の全コンポーネントを取得

If Not IsEmpty(vComps) Then
Dim i As Long
Dim swComp As SldWorks.Component2
Dim compModelName As String
Dim currentConfig As String

For i = LBound(vComps) To UBound(vComps)
Set swComp = vComps(i)

‘ 抑制されているコンポーネントはスキップ(メモリ例外回避)
If Not swComp.IsSuppressed Then
‘ 構成部品のファイル名(拡張子除く)を取得
compModelName = GetModelNameWithoutExtension(swComp.GetPathName)

‘ 対象の部品名と一致するか判定
If StrComp(compModelName, TARGET_PART_NAME, vbTextCompare) = 0 Then
‘ コンフィギュレーションの変更実行
Dim status As Boolean
status = swComp.ReferencedConfiguration = TARGET_CONFIG_NAME

If Not status Then
status = swComp.SetReferencedConfiguration(TARGET_CONFIG_NAME)
If status Then
successCount = successCount + 1
End If
End If
End If
End If

‘ ループ内でのオブジェクト解放
Set swComp = Nothing
Next i
End If

‘ 5. セッションの修復と環境復元
swModel.Visible = True
swApp.GetUserPreferenceToggle(swUserPreferenceToggle_e.swViewDisplayHideAllTypes) = False

‘ 強制再構築(Rebuild)を実行し、アセンブリの整合性を担保
swModel.ForceRebuild3 False

‘ 6. 完了報告
MsgBox “コンフィギュレーションの適用が完了しました。” & vbCrLf & _
“変更適用件数: ” & successCount & ” 件”, vbInformation, “SolidWorks VBA Automation”

CleanUp:
‘ 7. 明示的なメモリ解放(COMオブジェクトのデストラクタ的処理)
Set swAssocModel = Nothing
Set swModel = Nothing
Set swApp = Nothing
End Sub

‘ — ヘルパー関数: フルパスからファイル名(拡張子抜き)を抽出 —
Private Function GetModelNameWithoutExtension(ByVal fullPath As String) As String
If fullPath = “” Then
GetModelNameWithoutExtension = “”
Exit Function
End If

Dim fileName As String
fileName = Mid(fullPath, InStrRev(fullPath, “\”) + 1)

Dim extPos As Long
extPos = InStrRev(fileName, “.”)

If extPos > 0 Then
GetModelNameWithoutExtension = Left(fileName, extPos – 1)
Else
GetModelNameWithoutExtension = fileName
End If
End Function

—

3. チーフアーキテクトが教える「実務で絶対にハマる落とし穴」と対策

このコードをそのまま現場の巨大アセンブリ(構成部品数10,000点超クラス)に投入した場合、いくつかのクリティカルな問題に直面する。シニアエンジニアとして知っておくべき極限の知見を共有する。

A. 大規模アセンブリにおける「メモリフットプリント」の爆発

`swAssocModel.GetComponents(False)` は、メモリ上に巨大なバリアント配列を生成する。もしアセンブリの階層が極めて深い場合、VBAのヒープ領域を圧迫し、最悪の場合はSolidWorksごとクラッシュする。

  • 対策: サブアセンブリ構造ごとに分割して処理するか、APIのイベントハンドラを併用した非同期的な処理キューイングを検討すること。

B. 外部参照(External Reference)とコンテキストの矛盾

コンポーネントのコンフィギュレーションを切り替えた際、合致(Mate)の参照先エンティティ(面やエッジ)のIDがコンフィギュレーション間で異なっている場合、「合致エラー(マートエラー)」がアセンブリ全体に伝播する。

  • 対策: VBAでコンフィギュレーションを切り替えた直後に必ず `swModel.ForceRebuild3 False`(強制再構築)を挟み、幾何学的拘束の破綻をプログラム側で検知・修復できるように例外処理を記述すること。

C. レガシー環境とCOMポインタの解放

VBAのガベージコレクションは非常に曖昧である。特にループ内で `swComp` などのCOMオブジェクトを次々と生成・破棄する場合、明示的に `Set swComp = Nothing` を行わないと、SolidWorksのプロセス(SLDWORKS.exe)にメモリリークが蓄積し、数回バッチ処理を回しただけでフリーズする。上記のコードで採用している「ループごとのオブジェクト破棄」の作法は、実務システム構築において絶対の鉄則である。

—

総括

SolidWorks VBAによるアセンブリ自動化の真髄は、「APIをただ叩くこと」ではなく、「SolidWorksのドキュメントライフサイクルとメモリ管理のメカニズムを完全に従属させること」にある。

今回のコードをベースに、外部データベースやERP/PDMシステムからのJSON/CSV入力を組み合わせれば、数千種類ある製品バリエーションの3Dモデル生成を完全無人で、かつ一瞬で完了させる自動化基盤が完成する。
手作業による設計ミスを根絶し、真のエンジニアリング価値を生み出すシステムを構築してほしい。

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