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

スポンサーリンク

序文:なぜあなたの「外部参照」は牙を剥くのか

SolidWorks VBAを少し触った者なら、パーツ単体の自動生成は容易い。だが、アセンブリという巨大なエコシステムの中にそのパーツを放り込んだ瞬間、難易度は跳ね上がる。

多くのエンジニアが陥る罠がある。「パーツファイルを開いて値を書き換えれば、アセンブリ側も更新されるだろう」という安易な幻想だ。外部参照(External Reference)を持つパーツは、その魂の半分を親アセンブリに預けている。親のコンテキスト(文脈)を無視してパーツ単体で編集を強行すれば、参照は「ダングリング(迷子)」となり、再構築のたびにエラーを吐き出すゴミデータへと成り下がる。

本稿では、アセンブリの支配下にあるパーツを「インプレイス(その場)」で、かつ安全に制御するための極限の知見を授ける。これは単なるコードの書き方ではない。SolidWorksのオブジェクト・ライフサイクルを掌握し、設計意図を崩さずに自動化を完遂するための「鉄則」である。

1. 「ActiveDoc」の呪縛を解け:コンテキストの正体

SolidWorks APIにおいて、最も誤用されているのは `swApp.ActiveDoc` だ。
アセンブリ内でパーツを編集しているとき、アクティブなドキュメントは依然として「アセンブリ」である。しかし、編集のターゲットは「パーツ」だ。

この「二重性」を理解せずにパーツ側のAPIを叩いても、外部参照を持つスケッチは親のジオメトリを見つけられず、エラーを返す。

黄金のルール:

1. アセンブリをアクティブに保つ。
2. 編集対象のコンポーネントを特定する。
3. `EditPart2` メソッドで「編集モード」へ潜り込む。
4. 編集後、必ず `EditAssembly` で地上に戻る。

2. プロダクション・グレードの実装例

以下のコードは、アセンブリ内の特定のコンポーネントを特定し、そのコンテキスト内で安全にフィーチャ操作を行うためのテンプレートだ。エラーハンドリングと、編集モードからの確実な復帰(ロールバック処理)を組み込んでいる。


‘ @description アセンブリコンテキスト内でのパーツ編集テンプレート
‘ @param targetCompName 編集対象のコンポーネント名

Public Sub SecureInPlaceEdit(ByVal targetCompName As String)
Dim swApp As SldWorks.SldWorks
Dim swAssy As SldWorks.AssemblyDoc
Dim swModel As SldWorks.ModelDoc2
Dim swSelMgr As SldWorks.SelectionMgr
Dim swComp As SldWorks.Component2
Dim status As Long
Dim info As Long

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

‘ 1. ドキュメントタイプ確認
If swModel Is Nothing Or swModel.GetType <> swDocASSEMBLY Then
MsgBox “アセンブリを開いた状態で実行してください。”, vbCritical
Exit Sub
End If

Set swAssy = swModel
Set swSelMgr = swModel.SelectionManager

‘ 2. 対象コンポーネントの取得
‘ コンポーネント名での選択(例: “Part1-1″)
‘ ※ 完全に階層を指定するか、再帰探索ロジックを組むのがプロの仕事
status = swModel.Extension.SelectByID2(targetCompName, “COMPONENT”, 0, 0, 0, False, 0, Nothing, 0)

If status = False Then
Debug.Print “Error: 指定されたコンポーネントが見つかりません。”
Exit Sub
End If

Set swComp = swSelMgr.GetSelectedObjectsComponent4(1, -1)

‘ 3. インプレイス編集モードへ移行
‘ EditPart2(チェックフラグ, 外部参照の許可, エラーコード)
‘ 戻り値 0 は成功を意味する
status = swAssy.EditPart2(True, True, info)

If status <> 0 Then
Debug.Print “Error: 編集モードへの移行に失敗しました。Code: ” & info
Exit Sub
End If

‘ — ここからパーツ編集領域 —
On Error GoTo ErrorHandler

‘ 編集対象のパーツモデルを取得
Dim swEditModel As SldWorks.ModelDoc2
Set swEditModel = swComp.GetModelDoc2

‘ 例:外部参照を持つスケッチの寸法を書き換える
‘ パーツ単体で開いている場合、ここで「モデル外の参照」によりエラーになるリスクがあるが、
‘ EditPart2 を経由していれば、アセンブリのジオメトリを正しく参照できる。

‘ (具体的なジオメトリ操作をここに記述)
‘ swEditModel.Parameter(“D1@Sketch1”).SystemValue = 0.1 ‘ 100mm

‘ 強制再構築(コンテキスト内更新)
swEditModel.ForceRebuild3 False

‘ — 編集領域終了 —

Cleanup:
‘ 4. 必ずアセンブリ編集モードに戻る(これを忘れるとUIが死ぬ)
swAssy.EditAssembly
swModel.ClearSelection2 True
Debug.Print “Info: 編集が正常に終了しました。”
Exit Sub

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

3. 現場で差が出る「極限の知見」

① `EditPart2` の第二引数 `AllowExternalReferences`

この引数を `False` にしてはいけない。外部参照を持つパーツを操作する場合、ここを `True` にしなければ、API経由での更新時に参照が解決されず、意図しない形状崩壊を招く。

② モデルの「沈黙」を守る

大規模アセンブリでこれを繰り返す場合、再描画(Graphics Update)はパフォーマンスの敵だ。
`swModel.ViewLayoutUpdateLocked = True` を活用し、一連の処理が終わるまで画面更新を止めるのがチーフアーキテクトの作法だ。ただし、処理が終わった後の `False` 戻しと `ForceRebuild3` を忘れると、ユーザーはフリーズしたと勘違いする。

③ データベース・ファイルシステム連携の同期

VBAからパーツのプロパティを書き換え、それを外部DB(SQL Server等)にフィードバックする場合、「保存(Save)」のタイミングが重要だ。
インプレイス編集中の `swEditModel.Save3` は避けるべきだ。なぜなら、編集権限は親アセンブリが握っているからだ。編集を終え、`EditAssembly` で戻った後、親アセンブリを保存することで、内部のパーツ変更を一括してコミットさせるのが最も堅牢なトランザクション設計である。

4. まとめ:安定稼働するツールの条件

凡百のエンジニアは「動けばいい」と考える。だが、プロの自動化エンジニアは「ユーザーが次に何をするか」を考える。

1. 状態の保存と復元: 編集前の選択状態や表示モードを保存し、処理後に復元しているか?
2. 不測の事態への耐性: パーツが抑制(Suppressed)されていた場合や、ライトウェイト解除されていない場合の考慮は万全か?
3. 参照の健全性: `swComp.GetSelectionId` 等を用いて、名前変更に強い参照を保持しているか?

アセンブリという動的な環境において、パーツVBAは常に「借り物の力」であることを自覚せよ。コンテキストを尊重し、正しい手順で編集の扉を開き、そして確実に閉じる。この基本の徹底こそが、深夜のトラブルコールをゼロにする唯一の道である。

あなたのコードが、単なる自動化ツールを超え、設計資産を守る「守護神」となることを願っている。

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