【SolidWorks VBA極限活用】親アセンブリ文脈を支配する!インプレイスパーツ自動更新の極意
開発現場のリーダーとして、ハッキリと言わせていただく。
「パーツ単体を開いて寸法をいじり、アセンブリに戻って再構築する」という、昭和のような非効率なトップダウン設計をまだ続けているのか?
真に自動化された設計プロセスの世界では、パーツは常に親アセンブリの文脈(Context)の中で生きている。アセンブリ内の他のコンポーネントの位置関係、干渉状態、あるいは合致条件を逆引きし、パーツ側のジオメトリをインプレイスで自律的にアジャストさせる――これこそが、大規模アセンブリを数分で料理するプロのVBAエンジニアの技量だ。
今回は、`PartDoc.EnumConfigurations2` と `Component2` オブジェクトを極限まで使い倒し、「親アセンブリの文脈を考慮したインプレイスパーツ自動更新」を実現する堅牢なプロダクションコードを授けよう。
—
1. なぜ「パーツ単体マクロ」は実務で破綻するのか?
多くの初学者が陥る罠がある。それは、アクティブなパーツドキュメントに対して直接 `ISldWorks.ActivateDoc3` や単体の寸法変更を適用しようとするアプローチだ。
- 外部参照(External References)の破綻: アセンブリコンテキスト(In-Context)を持つパーツを、単体(PartDoc)として誤ったコンテキストのまま操作すると、参照切れ(Dangling)を起こす。
- 構成部品(Configuration)の迷子: 親アセンブリ側で特定のコンフィギュレーションが選択されているにもかかわらず、パーツ側のデフォルト構成をいじってしまい、アセンブリ側で意図しない形状崩壊を引き起こす。
- メモリとパフォーマンスの無駄: アセンブリを開いたまま背後で何重にもドキュメントを開閉し、SolidWorksのCOMオブジェクトをリークさせる。
これらを防ぐには、「アセンブリを主導権(マスタ)とし、コンポーネント経由でパーツのドキュメントへ安全にアクセスする」というオブジェクト指向的なライフサイクル管理が絶対条件となる。
—
2. アーキテクチャ設計:文脈把握のキーマンたち
今回の自動化ロジックの要となるSolidWorks APIの階層構造を理解してほしい。
1. `SldWorks.ModelDoc2` (アセンブリ): 最上位のマスタ。
2. `AssemblyDoc` -> `IComponent2`: アセンブリに配置された各部品のインスタンス。ここで座標系や親・子関係、そして「どのコンフィギュレーションで組み込まれているか」を把握する。
3. `IComponent2.GetModelDoc2`: コンポーネントの背後にある実体(PartDoc / AssemblyDoc)への安全な参照を取得する。
4. `PartDoc.EnumConfigurations2`: パーツ側の全コンフィギュレーションを列挙し、文脈に応じた適切なターゲットを特定する。
このフローを完璧にコードに落とし込む必要がある。
—
3. 【プロダクションコード】親アセンブリ文脈を考慮したインプレイス更新
以下のVBAコードは、現在アクティブなアセンブリから選択されたコンポーネント(パーツ)を特定し、親アセンブリ内での位置情報や構成部品名を取得した上で、パーツ側の特定の寸法・構成をインプレイスで安全に書き換える実用コードである。
エラーハンドリング、COMオブジェクトの適切な解放(Nothing代入)、そして型安全性を極限まで高めたプロ仕様だ。
Option Explicit
‘ =========================================================================
‘ 処理名: 親アセンブリ文脈を考慮したインプレイスパーツ自動更新
‘ 概要 : アセンブリ内の選択コンポーネントを起点に、パーツ側のジオメトリを制御する
‘ =========================================================================
Sub UpdatePartInAssemblyContext()
Dim swApp As SldWorks.SldWorks
Dim swAssyDoc As SldWorks.ModelDoc2
Dim swAssy As SldWorks.AssemblyDoc
Dim swSelMgr As SldWorks.SelectionMgr
Dim swComp As SldWorks.Component2
Dim swPartDoc As SldWorks.ModelDoc2
Dim swPart As SldWorks.PartDoc
Set swApp = Application.SldWorks
Set swAssyDoc = swApp.ActiveDoc
‘ 1. 事前条件チェック (アセンブリが開かれているか)
If swAssyDoc Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。”, vbCritical, “エラー”
Exit Sub
End If
If swAssyDoc.GetType() <> swDocASSEMBLY Then
MsgBox “このマクロはアセンブリ文書でのみ実行可能です。”, vbCritical, “エラー”
Exit Sub
End If
Set swAssy = swAssyDoc
Set swSelMgr = swAssyDoc.SelectionManager
‘ 2. アセンブリ内で対象のコンポーネントが選択されているか確認
Dim selType As Long
selType = swSelMgr.GetSelectedObjectType3(1)
If selType <> swSelectComponent Then
MsgBox “対象となるパーツのコンポーネントをアセンブリツリーまたはグラフィックス領域で選択してください。”, vbExclamation, “操作確認”
Exit Sub
End If
‘ 3. 選択されたコンポーネントの取得
Set swComp = swSelMgr.GetSelectedObject6(1, -1)
If swComp Is Nothing Then
MsgBox “コンポーネントの取得に失敗しました。”, vbCritical, “エラー”
Exit Sub
End If
‘ デバッグ出力:コンポーネント情報
Debug.Print “=== ターゲットコンポーネント情報 ===”
Debug.Print “名称: ” & swComp.Name2
Debug.Print “構成部品名: ” & swComp.ReferencedConfiguration
‘ 4. コンポーネントの背後にあるパーツドキュメント(ModelDoc2)を取得
‘ ※ 注意: GetModelDoc2はメモリにロードされている必要があるため、必要に応じてPathNameから開く制御も実務では検討する
Set swPartDoc = swComp.GetModelDoc2
If swPartDoc Is Nothing Then
‘ メモリにない場合はファイルパスからサイレントオープンする安全策
Dim docPath As String
docPath = swComp.GetPathName()
Set swPartDoc = swApp.OpenDoc6(docPath, swDocPART, swOpenDocOptions_Silent, “”, 0, 0)
End If
If swPartDoc.GetType() <> swDocPART Then
MsgBox “選択されたコンポーネントはパーツではありません。”, vbCritical, “エラー”
Exit Sub
End If
Set swPart = swPartDoc
‘ 5. PartDoc.EnumConfigurations2 を活用した構成部品の走査と文脈同期
Dim configNames As Variant
configNames = swPart.GetConfigurationNames()
Dim i As Long
Dim targetConfig As String
targetConfig = swComp.ReferencedConfiguration ‘ 親アセンブリが要求している構成名
Dim configFound As Boolean
configFound = False
For i = LBound(configNames) To UBound(configNames)
If configNames(i) = targetConfig Then
configFound = True
Exit For
End If
Next i
If Not configFound Then
MsgBox “パーツ内に親アセンブリが要求する構成 [” & targetConfig & “] が存在しません。”, vbCritical, “エラー”
GoTo CleanUp
End If
‘ パーツ側の構成を親アセンブリの文脈に強制一致させる
Dim boolstatus As Boolean
boolstatus = swPartDoc.ShowConfiguration2(targetConfig)
‘ =========================================================================
‘ 6. インプレイスジオメトリの自動アジャストロジック
‘ ※ ここでは例として特定の値(例: “Length@Sketch1″)を書き換える処理を記述
‘ =========================================================================
‘ 親アセンブリの文脈(他のコンポーネントの位置など)から動的に値を計算する場合はここにロジックを挿入
Dim targetDimensionName As String
targetDimensionName = “D1@押し出し1” ‘ 実際のモデルに合わせて変更してください
Dim swParam As SldWorks.Parameter
Set swParam = swPartDoc.Parameter(targetDimensionName)
If Not swParam Is Nothing Then
‘ 例として値を 150.0 mm (メート法換算で 0.15m) に変更
Dim newDimValue As Double
newDimValue = 0.15 ‘ 単位はメートル(m)
Dim setRes As Long
setRes = swParam.SetSystemValue3(newDimValue, swSetValue_InThisConfiguration, Nothing)
If setRes = 0 Then
Debug.Print “寸法 ” & targetDimensionName & ” の更新に成功しました。”
Else
MsgBox “寸法の更新に失敗しました。コードを確認してください。”, vbExclamation, “警告”
End If
Else
Debug.Print “指定された寸法が見つかりませんでした: ” & targetDimensionName
End If
‘ 7. 変更の保存とリビルド
‘ アセンブリ文脈を保持したままパーツ側を強制リビルド
swPartDoc.Extension.Rebuild swRebuildAll
swAssyDoc.Extension.Rebuild swRebuildTopLevel
MsgBox “親アセンブリ文脈に基づくパーツのインプレイス更新が完了しました。”, vbInformation, “完了”
CleanUp:
‘ 8. オブジェクトの明示的な解放(メモリリーク防止の鉄則)
Set swParam = Nothing
Set swPart = Nothing
Set swPartDoc = Nothing
Set swComp = Nothing
Set swSelMgr = Nothing
Set swAssy = Nothing
Set swAssyDoc = Nothing
Set swApp = Nothing
End Sub
—
4. チーフアーキテクトが教える実装上の極意と注意点
このコードを現場に導入するにあたり、プログラマが押さえておくべき「生き残りの知見」を共有する。
① `GetModelDoc2` の落とし穴とサイレントオープン
アセンブリが大規模な場合、非表示(Lightweight)状態のコンポーネントや、まだメモリにロードされていないパーツに対して `swComp.GetModelDoc2` を実行すると `Nothing` が返ってくる。
実務では、上記のコード例のように `swComp.GetPathName()` を取得し、`swApp.OpenDoc6` を `swOpenDocOptions_Silent` オプションで裏側(非表示)で安全にロードするフェイルセーフを必ず組み込むこと。
② 単位系の呪縛(マスタは常にメートル)
SolidWorks APIの内部値(SystemValue)は、ユーザインターフェース上の単位(mmやinch)に関わらず、常に「メートル法(m / kg / sec)」で処理される。
コード内で `0.15` と指定しているのは `150mm` を意味する。ここをミリメートル単位で直に渡すと、パーツが宇宙の彼方へ吹き飛ぶような巨大な形状になるので細心の注意を払うこと。
③ 構成部品名(Configuration)の不一致を防ぐ
`swComp.ReferencedConfiguration` は、親アセンブリがそのパーツの「どのコンフィギュレーションを参照しているか」を正確に返す。
パーツ単体側の構成名とアセンブリ側の参照構成名が完全一致していない状態でパラメータを叩くと、意図しない構成の寸法が書き換わり、他のアセンブリへの悪影響(スノーボール現象)を引き起こす。`EnumConfigurations2`(または `GetConfigurationNames`)による存在確認のステップは絶対に省略してはならない。
—
5. おわりに:自動化の次のステージへ
今回解説したロジックをマスターすれば、単なる「お絵描きマクロ」から脱却し、「アセンブリの設計変更に追従して自律的に最適化されるパーツ群」という、真の意味でのエンジニアリング・オートメーション(EA)の領域に到達できる。
設計者の手作業を減らし、計算と検証の本質的な時間に集中させる。それこそが、我々エンジニアに課された使命だ。現場の仕組みを、今すぐ書き換えろ。
