SolidWorks VBAを掌握する極限の知見
【コンフィギュレーション連携】Configuration.SetIsModelStateを活用した大規模パーツにおける軽量状態(Lightweight)のVBA制御
開発プロジェクトの現場において、数百点に及ぶコンフィギュレーションを持つ巨大なマスターパーツ(Master Part)のバッチ処理や、世代管理の自動化を任されたことはないだろうか。
「すべてのコンフィギュレーションをループさせながらプロパティを書き換え、ジオメトリを検証し、図面やSTEPを吐き出す」
――この要件を愚直に実装した瞬間、SolidWorksは重い息をつき、やがてメモリリーク(OutOfMemoryException)やフリーズの海原へ沈んでいく。
なぜか?
デフォルトのVBA実装では、コンフィギュレーションを切り替えるたびに、背後で全コンフィギュレーションの全フィーチャーツリー、全ジオメトリデータがRAMへ強制ロードされるからだ。コンフィギュレーションが50個あれば、1つのファイルを開くだけで50個分のリソースがメモリを食い潰す。
この地獄を回避し、大規模パーツの自動化を秒速で終わらせるための唯一の解が、`Configuration.SetIsModelState` による「軽量状態(Lightweight)」のプログラム制御である。今回は、その極限の知見を授けよう。
—
1. なぜ「全ロード」は悪なのか? ――SolidWorksメモリ管理の真実
SolidWorksのAPIにおいて、コンフィギュレーションの切り替え(`Part.ShowConfiguration2`)は、単なる「表示の切り替え」ではない。裏側では、そのコンフィギュレーション固有のサプレッション状態や寸法の解決が行われ、グラフィックデータと数学的モデル(B-Rep)がメモリ上に展開される。
大規模アセンブリや複雑なテーブル駆動パーツにおいて、これを全コンフィギュレーションに対して順次行えば、RAMの容量など一瞬で枯渇する。
救世主:軽量状態(Lightweight State)
アセンブリのパフォーマンス向上機能として知られる「軽量」だが、実はパーツファイルの各コンフィギュレーションに対しても適用可能である。
コンフィギュレーションを「軽量」に落とし込むと、ジオメトリの完全な数学的定義ではなく、大まかな近似データのみがメモリに保持される。これにより、メモリ消費量を極限まで抑えつつ、プロパティの書き換えや特定のメタデータ操作といった「重いジオメトリ再計算を伴わない処理」を高速に実行できるのだ。
—
2. 堅牢な設計:バグを生む罠とアーキテクチャ
実務でこの制御を実装する際、以下の3つの鉄則を守らなければならない。
1. アクティブコンフィギュレーションの保護
現在アクティブなコンフィギュレーションを直接「軽量」にすることはできない。処理対象外のコンフィギュレーションを順次軽量化し、操作対象のみ一時的に解決状態(Resolved)にするというステートマシン的な思考が必要である。
2. 自動再構築の抑制
コンフィギュレーション切替時の無駄な `EditRebuild3` は厳禁。バッチ処理の最後、あるいは本当に必要なタイミングでのみ一括してリビルドをかける。
3. エラーハンドリングとCOMオブジェクトの解放
VBAにおけるSolidWorks API連携では、変数の解放漏れがメモリリークに直結する。特にコンフィギュレーションの列挙時は細心の注意を払う。
—
3. プロダクションコード例:爆速コンフィギュレーション・バッチ処理
以下のコードは、大規模パーツ内の全コンフィギュレーションを走査し、メモリを爆発させずに安全かつ高速にカスタムプロパティを更新、または軽量状態を制御する実戦投入可能なVBAモジュールである。
Option Explicit
‘ =================================================================================
‘ módulo名: modConfigurationManager
‘ 概要 : 大規模パーツのコンフィギュレーションを軽量状態を活用して高速制御する
‘ 著者 : Chief Automation Architect
‘ =================================================================================
Public Sub ExecuteHighSpeedConfigurationBatch()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swPart As SldWorks.PartDoc
Dim configNames As Variant
Dim i As Long
Dim currentConfigName As String
‘ 1. アプリケーションおよびドキュメントの取得
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。”, vbCritical, “致命的エラー”
Exit Sub
End If
‘ パーツドキュメントかどうかの型チェック
If swModel.GetType <> swDocPART Then
MsgBox “このマクロはパーツファイルでのみ実行可能です。”, vbExclamation, “型不一致”
Exit Sub
End If
Set swPart = swModel
‘ 2. 処理前の画面描画をロックしてパフォーマンスを最大化
swApp.Visible = False
swModel.ActiveView.EnableGraphics = False
On Error GoTo ErrorHandler
‘ 3. 全コンフィギュレーション名の取得
configNames = swModel.GetConfigurationNames()
currentConfigName = swModel.ConfigurationManager.ActiveConfiguration.Name
Dim swConfig As SldWorks.Configuration
‘ 4. メモリ効率化ループ:ターゲット以外のコンフィギュレーションを軽量化
For i = LBound(configNames) To UBound(configNames)
Set swConfig = swModel.GetConfigurationByName(configNames(i))
If Not swConfig Is Nothing Then
If configNames(i) <> currentConfigName Then
‘ 【極限の知見】アクティブ以外を明示的に軽量状態(Lightweight)に設定
‘ 引数: True = 軽量化, False = 完全解決
Dim success As Boolean
success = swConfig.SetIsModelState(swModelState_LightWeight)
If Not success) Then
Debug.Print “Warning: コンフィギュレーション [” & configNames(i) & “] の軽量化に失敗しました。”
End If
End If
End If
Set swConfig = Nothing
Next i
‘ 5. 各コンフィギュレーションに対する実務処理(例:プロパティの付与・検証)
For i = LBound(configNames) To UBound(configNames)
‘ 処理対象のコンフィギュレーションへ切り替え
swModel.ShowConfiguration2 (configNames(i))
‘ ここに各コンフィギュレーションで行いたい重い処理を記述
‘ 例: CustomPropertyManagerを通じたデータ書き換え
Call ProcessConfigurationData(swModel, configNames(i))
Next i
‘ 元のコンフィギュレーションに戻す
swModel.ShowConfiguration2 (currentConfigName)
‘ 6. 終了処理
swModel.ActiveView.EnableGraphics = True
swApp.Visible = True
MsgBox “すべてのコンフィギュレーションのバッチ処理が完了しました。”, vbInformation, “完了”
Exit Sub
ErrorHandler:
‘ 異常終了時の安全保障(画面描画の復元)
swModel.ActiveView.EnableGraphics = True
swApp.Visible = True
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “ランタイムエラー”
End Sub
Private Sub ProcessConfigurationData(ByRef swModel As SldWorks.ModelDoc2, ByVal configName As String)
Dim swCustPropMgr As SldWorks.CustomPropertyManager
Set swCustPropMgr = swModel.Extension.CustomPropertyManager(configName)
‘ 例としてステータスプロパティを書き込む
Dim res As Long
res = swCustPropMgr.Add3(“AutoProcessed”, swCustomInfoText, “Checked”, swCustomPropReplaceValue)
Set swCustPropMgr = Nothing
End Sub
—
4. 現場で活きる! データベース連携時の設計指針
このコードを実際の社内データベース(PLMやPDM、あるいはExcel/Access等)と連携させる場合、以下のアーキテクチャを推奨する。
- トランザクション的思考の導入
外部DBから取得した仕様データをパーツへ反映させる際、「全コンフィギュレーションのループ」の中でDBクエリを何回も発行してはならない。あらかじめVBA側のメモリ(Dictionary等)にDBデータを一括ロードし、メモリ上でマッピングした上で、上記の `ProcessConfigurationData` 内で一気に流し込む。
- サイレント保存(Silent Save)
バッチ処理の最後にファイルを保存する際は、ユーザーインタラクションを排除し、かつ軽量状態を保持したままクローズすることで、次回オープン時のパフォーマンスを担保する。
—
5. 結びに代えて
自動化の神は「細部のメモリ管理」に宿る。
動けばいいだけのコードを書く時代は終わった。数百・数千のコンフィギュレーションを従えた重厚長大なパーツファイルを、まるで羽毛のように軽々と操るシステムを構築してこそ、真のプロフェッショナル・オート메이션エンジニアと言える。
`Configuration.SetIsModelState`。この武器をあなたのVBAツールキットに加え、現場のエンジニアたちを「待ち時間」という名の呪縛から解放してほしい。
