【テクニカル・上級編】【パフォーマンス改善】ModelDoc2.EnableRebuild枚数制御とFeatureManager.EnableFeatureUpdateによる大規模パーツの爆速化 – SolidWorks VBA解析バイブル

スポンサーリンク

SolidWorks APIの深淵:大規模モデル生成を「一瞬」で終わらせるための極限チューニング

SolidWorks APIを扱うエンジニアにとって、フィーチャを数百、数千と積み重ねる作業は、時に「終わりのない待機時間」との戦いを意味する。多くの初心者は、マクロ実行中に画面がチカチカと再描画され、プログレスバーがゆっくりと進む様子を眺めることに甘んじている。

だが、我々の目的は「動作するコード」ではない。「極限まで研ぎ澄まされたシステム」だ。今回は、大規模パーツ生成におけるパフォーマンスのボトルネックを物理的に排除し、実行時間を劇的に短縮するためのアーキテクチャを解説する。

1. 再構築(Rebuild)という最大の足枷

SolidWorks APIにおいて、最も高コストな操作は「フィーチャごとの再構築」だ。デフォルトでは、`FeatureManager`に新しいフィーチャを追加するたびに、モデルはジオメトリの整合性を確認し、表示を更新しようとする。

これを放置すれば、複雑な履歴を持つモデルでは、フィーチャが100個を超えたあたりから指数関数的に処理時間が悪化する。この「無駄な計算」を止めるのが、エンジニアの第一歩だ。

核心を突く実装パターン

`ModelDoc2.EnableRebuild` を `False` に設定し、`FeatureManager.EnableFeatureUpdate` を `False` にすることで、SolidWorksの「思考プロセス」を強制的に一時停止させる。

‘ 伝説的なパフォーマンス改善のための定型テンプレート
Public Sub OptimizeFeatureCreation(swApp As SldWorks.SldWorks, swModel As SldWorks.ModelDoc2)
‘ 1. 再構築イベントを抑止(これが最大のキモ)
swModel.EnableRebuild = False

‘ 2. FeatureManagerの更新を停止(UIと内部計算を分離)
swModel.FeatureManager.EnableFeatureUpdate = False

On Error GoTo Cleanup

‘ — ここに大規模なフィーチャ生成処理を記述 —

Cleanup:
‘ 3. 処理終了後に必ず状態を戻す(忘れるとSolidWorksが半死状態になる)
swModel.EnableRebuild = True
swModel.FeatureManager.EnableFeatureUpdate = True

‘ 4. 最後に一度だけ再構築を実行し、モデルの整合性を確定させる
swModel.ForceRebuild3 True
End Sub

2. メモリ最適化とオブジェクトのライフサイクル

VBAのガーベッジコレクションは非常に「怠惰」だ。大規模なパーツ操作において、`Feature`や`Entity`オブジェクトをループ内で生成し続け、解放しないコードは、メモリリークの温床となる。

シニアエンジニアであれば、「明示的な破棄(Nothing代入)」と「スコープの局所化」を徹底せよ。

  • ループ内でのオブジェクト生成を避ける:

フィーチャ定義のたびに巨大なオブジェクトを保持し続けるのではなく、必要な情報を取得したら即座に解放する。

  • API呼び出しのキャッシュ:

`swModel.Extension.SelectByID2`などをループ内で無意味に呼び出さない。あらかじめ必要な`Feature`オブジェクトをコレクションに格納し、参照を再利用する手法が、IPC(プロセス間通信)のオーバーヘッドを劇的に抑える。

3. Windows APIで「描画」を完全に沈黙させる

`EnableRebuild` や `EnableFeatureUpdate` を使っても、バックグラウンドでの描画更新が完全に止まらないケースがある。特に、複雑なアセンブリや大規模パーツが親モデルとして存在する場合だ。

ここで、Windows APIの `LockWindowUpdate` を併用する。これは、SolidWorksのプロセスウィンドウに対して「描画を許可しない」という強力な命令を下す。

‘ User32.dll を活用した描画ロック
Private Declare PtrSafe Function LockWindowUpdate Lib “user32” (ByVal hwndLock As LongPtr) As LongPtr

Sub HardLockPerformance()
Dim swFrame As Object
Set swFrame = swApp.Frame

‘ 描画を強制停止
LockWindowUpdate swFrame.GetHWnd

‘ — 処理実行 —

‘ 描画を解放
LockWindowUpdate 0
End Sub

※注意: `LockWindowUpdate`は強力だが、デバッグ中にエラーが発生して解放を忘れると、SolidWorksの画面が真っ白のままフリーズする。必ずエラーハンドリング内で確実に `LockWindowUpdate 0` を呼び出すこと。

4. レガシーシステムへの極限の知見

もしあなたが現在、古いSolidWorks環境や、さらに古いVB6/VBAから移行できないシステムを維持しているなら、以下のルールを金律とせよ。

1. DoEventsは「悪」: ループ内で `DoEvents` を呼ぶと、OSのメッセージキューがクリアされ、パフォーマンスが劇的に低下するだけでなく、SolidWorksの再構築順序を狂わせる可能性がある。プログレスバーを更新したいなら、100回に1回など、頻度を極限まで下げろ。
2. 型変換のコスト: `Variant`型を不用意に使うな。特にAPI引数で `Object` や `Dispatch` を渡す際、明示的な型指定(`SldWorks.Feature`等)を怠ると、ランタイム時のバインドコストが累積する。

結びに代えて

大規模パーツの生成速度は、SolidWorksというエンジンの「機嫌」をどれだけコントロールできるかにかかっている。再構築を制御し、メモリを管理し、OSレベルで描画をロックする。これらは単なるテクニックではなく、SolidWorksという巨大なソフトウェアの「内部挙動を支配する」ためのプロトコルだ。

今日からあなたのコードにこの「抑制の哲学」を取り入れろ。待機時間が消滅した時、あなたは初めて、SolidWorks APIを完全に掌握したと言えるだろう。

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