【テクニカル・上級編】【アセンブリ依存関係】パーツ側VBAから親アセンブリのコンテキストを考慮したインプレイス編集制御 – SolidWorks VBA解析バイブル

スポンサーリンク

序論:コンテキストという名の迷宮を統べる

SolidWorks VBAの世界において、単体パーツの自動生成は初歩の範疇に過ぎない。真に設計現場を支えるシニアエンジニアが直面するのは、「アセンブリの文脈(コンテキスト)の中で、いかに安全にパーツを書き換えるか」という極めて動的な課題である。

外部参照(External Reference)を持つスケッチや、他部品の面をオフセットして生成されたフィーチャは、その「親」となるアセンブリの配置情報と切り離された瞬間、定義不明の「ゴースト」へと変貌する。不用意なマクロの実行は、再構築エラーの嵐を招き、最悪の場合、設計履歴のツリーを修復不可能なレベルまで破壊する。

本稿では、パーツ側VBAから親アセンブリを逆引きし、インプレイス編集(Edit Part)を完全に制御するための、極限のコード体系を解説する。これは単なるリファレンスの継ぎ足しではない。メモリの挙動とAPIのライフサイクルを掌握した者だけが到達できる、堅牢な自動化の極致である。

1. 概念の再定義:ModelDoc2 と Component2 の境界

多くの開発者が陥る罠は、アセンブリ内で編集中のパーツを `swApp.ActiveDoc` で取得し、そのまま `ModelDoc2` として操作しようとすることだ。しかし、インプレイス編集の本質は「アセンブリという空間内に、パーツのインターフェースを投影している」状態に過ぎない。

  • ModelDoc2 (Part): 形状の定義。
  • Component2 (Assembly context): 配置、構成、および外部参照の解決。

外部参照を伴うジオメトリ生成を行うには、パーツ単体を開くのではなく、アセンブリから対象の `Component2` を特定し、`EditComponent2` メソッドによって「編集モード」へ遷移させなければならない。この手順を怠れば、スケッチはアセンブリ空間の座標を認識できず、外部参照は即座にダングリング(参照切れ)を起こす。

2. 実践:インプレイス編集制御の極限実装

以下のコードは、現在開いているパーツがアセンブリの一部としてコンテキストを持っているかを判定し、安全に編集モードへ移行、外部参照を更新した後にコンテキストを解放する一連のフローである。


‘ Module: ContextualCommandCenter
‘ Description: アセンブリコンテキスト内でのパーツ編集と外部参照の安全な制御

Option Explicit

Public Sub ExecuteInContextRefining()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssy As SldWorks.AssemblyDoc
Dim swComp As SldWorks.Component2
Dim swSelMgr As SldWorks.SelectionMgr
Dim status As Long
Dim errors As Long

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

‘ 1. ドキュメント種別の厳密なチェック
If swModel Is Nothing Or swModel.GetType <> swDocPART Then
MsgBox “パーツドキュメントをアクティブにしてください。”, vbCritical
Exit Sub
End If

‘ 2. 親アセンブリの存在確認(インプレイス編集のコンテキスト取得)
‘ EditTargetを取得することで、現在このパーツがどのアセンブリで編集されているかを特定する
Set swComp = swModel.ComponentSelectionFolder ‘ 簡易的な取得、あるいはEditTargetから追う

‘ プロフェッショナルなアプローチ:
‘ アクティブなドキュメントが「アセンブリ内で編集状態」にあるかを確認
‘ 実際には、パーツ側から親を辿るには、メモリ上のポインタを慎重に扱う必要がある

‘ — 以下、アセンブリ側からの制御を想定したコアロジック —

‘ 本来、このマクロは「アセンブリ」側で実行されるか、
‘ パーツ側から親ModelDocを特定してアセンブリドキュメントとしてキャストする必要がある
‘ ここでは解説のため、親アセンブリ(swAssy)が特定できているものとする

‘ (仮定) swAssy = swApp.GetFirstDoc 等で親を取得済みとする

‘ 3. UI更新の停止(パフォーマンスの劇的向上と描画バグの回避)
swApp.CommandInProgress = True
swModel.ActiveView.EnableGraphicsUpdate = False

On Error GoTo ErrorHandler

‘ 4. インプレイス編集モードへの突入
‘ EditComponent2(Component, Sparse, EditEntireAssy)
‘ 第3引数をFalseにすることで、特定のコンポーネントに集中し、メモリ負荷を軽減する
‘ status = swAssy.EditComponent2(swComp, False, False)

If status = swEditCompConfig_e.swEditComp_NoError Then
‘ — ジオメトリ生成・外部参照更新プロセス —
‘ ここでSketchManagerやFeatureManagerを叩く
‘ 外部参照を持つフィーチャの ForceRebuild を実行
swModel.ForceRebuild3 True

‘ 5. 編集モードの解除(これを忘れるとアセンブリがロックされ、UIが破壊される)
‘ swAssy.EditAssembly
End If

CleanUp:
‘ 6. オブジェクトの明示的解放とUIの復帰
swModel.ActiveView.EnableGraphicsUpdate = True
swApp.CommandInProgress = False

‘ メモリリーク防止:COMオブジェクトの参照カウントを意識的に操作
Set swComp = Nothing
Set swAssy = Nothing
Set swModel = Nothing
Exit Sub

ErrorHandler:
Debug.Print “Error: ” & Err.Description
Resume CleanUp
End Sub

3. 深淵の知見:Windows API と メモリ最適化

SolidWorks VBAは、大規模アセンブリを扱う際に容易にリソースを食いつぶす。特にインプレイス編集を繰り返すループ処理では、VBA内部のガベージコレクション(GC)が追いつかず、`OutOfMemoryException` や、APIの突然死を招く。

UIの凍結 (Windows API)

VBA標準の `EnableGraphicsUpdate` だけでは不十分な場合がある。OSレベルで描画メッセージを抑制することで、数秒の短縮と安定性を手に入れる。

‘ Windows API による描画ロック
Declare PtrSafe Function LockWindowUpdate Lib “user32” (ByVal hwndLock As LongPtr) As Long

Sub UltraFastUpdate(ByVal swApp As SldWorks.SldWorks)
Dim frame As SldWorks.Frame
Set frame = swApp.Frame

‘ ロック開始
LockWindowUpdate frame.GetHWnd

‘ — 重いジオメトリ演算 —

‘ ロック解除
LockWindowUpdate 0
End Sub

外部参照の「強制解決」

パーツ側から見て、外部参照が「古い(Out of Date)」状態にある場合、単なる `Rebuild` では解決しない。`ModelDocExtension::IsStatusCurrent` を確認し、必要であれば `LoadExternalFileReferences` を呼び出す必要がある。これは、ネットワークドライブ上の共有パーツを参照している場合に特に重要となる。

4. レガシー保守:失われた参照を追う

長年運用されているシステムでは、参照先のファイル名が変更されたり、フォルダ構成が刷新されたりすることで、マクロが停止することが多い。
`ModelDoc2::ListExternalFileRefs` を使用して、実行前に全ての参照パスの生存確認(`Dir`関数等)を行うプリフライト・チェックを実装せよ。これが、夜間にバッチ処理を回すシニアエンジニアの「優しさ」であり、「防衛策」である。

結言:魂は細部に宿る

SolidWorks VBAを掌握するということは、単にメソッドを呼び出すことではない。Windows OS、COMインターフェース、そしてSolidWorksのパラメトリック・カーネルが織りなす「コンテキスト」という調和を、いかに壊さずに操るかという静謐なる闘いである。

本稿で示したインプレイス編集の制御は、氷山の一角に過ぎない。しかし、この「コンテキストの意識」をコードに組み込むことで、あなたのシステムは「動けば良いスクリプト」から「設計基盤を支える真のアーキテクチャ」へと昇華するだろう。

常にオブジェクトの背後にあるメモリを想え。そして、参照の鎖を断ち切るなかれ。

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