【SolidWorks VBA極限optimization】マクロの処理時間を10倍にする画面描画停止・再計算抑制の全技術
開発現場でこんな絶望感を味わったことはないか?
「数十個のコンフィギュレーションを持つ複雑なパーツで、パラメータを一括変更するマクロを書いた。しかし、実行ボタンを押した瞬間から画面が狂ったように点滅し、1回のフィーチャ更新ごとに数秒待たされ、終わる頃にはコーヒーが冷めきっている……」
もしあなたのマクロが「画面を見せながら動いている」なら、あなたはSolidWorksのAPIに対して「最も重い罰ゲーム」を課していることになる。
SolidWorksは、VBAからAPI経由でジオメトリやフィーチャを操作するたびに、デフォルトでは忠実に「グラフィックビューポートの再描画(Redraw)」と「フィーチャツリーの再評価(Rebuild)」を行っている。これがパフォーマンス低下の元凶だ。
今回は、`SwApp.SetUserPreferenceToggle`をはじめとするAPI群を駆使し、マクロ実行中の描画と再計算を完全にコントロール下におき、処理速度を最大10倍以上に跳ね上げるための極限の知見を伝授する。
—
1. なぜ描画と自動再計算の抑制が必須なのか?
プログラミング初心者や独学のエンジニアは、マクロのコード量やアルゴリズムの効率ばかりを気にする。だが、SolidWorks VBAにおける真のボトルネックは「COM境界を跨いだGUIの更新コスト」と「ジオメトリカーネル(Parasolid)の無駄な再評価」にある。
描画(Screen Update)のコスト
VBAからAPIを1回叩くたびに、SolidWorksはその結果を画面に反映させようとする。人間の目で認識できない数ミリ秒単位の描画であっても、OSとグラフィックボードにとっては膨大な負荷だ。画面描画を止めるだけで、I/O待ちの時間は劇的に消滅する。
自動再計算(Auto-Rebuild)の罠
フィーチャを一つ追加・変更するたびに、モデル全体が汚染(Dirty)状態とみなされ、意図しないタイミングで親子関係の解決や干渉チェックが走る。
「最後にまとめて再計算すればいい」という状態を作り出すことが、高速化の絶対条件なのだ。
—
2. 抑制を司る主要APIと「戻し忘れ」の恐怖
ここで、今回主役となるAPIを確認する。これらは単なるメソッドではなく、SolidWorksのアプリケーションスコープ(グローバル)の状態を書き換える強力なスイッチだ。
1. `SldWorks.Application.SetUserPreferenceToggle`
- 画面の自動再計算や表示設定などのシステムオプションをトグル制御する。
2. `ModelDoc2.EditRebuild3` / `ForceRebuild3`
- 抑制期間中に溜まった変更を一括して適用(リビルド)する。
3. `ModelDoc2.GraphicsRedraw`
- 処理完了後に、一度だけ画面を強制描画リフレッシュする。
⚠️ チーフアーキテクトからの警告:エラーハンドリングの鉄則
描画停止系APIを使う際最大の恐怖は、「マクロが途中でエラー落ちした結果、画面描画や自動再計算が停止したままSolidWorksがフリーズしたような状態になること」である。ユーザーは絶望し、タスクマネージャーから強制終了する羽目になる。
したがって、例外処理(`On Error Goto`構造)を必ず実装し、異常終了時であっても確実に設定を元の状態に復元する設計にしなければならない。
—
3. 【プロダクションコード】極限まで最適化されたパーツ生成テンプレート
実務でそのまま使える、堅牢性とパフォーマンスを極めたコードを示す。
このテンプレートは、エラーハンドリング、描画停止、再計算抑制、そして確実な復元を完璧なライフサイクル管理のもとで実行する。
Option Explicit
‘ ==============================================================================
‘ 担当者: シニアAutomationアーキテクト
‘ 概要 : 画面描画と再計算を完全抑制し、大量のフィーチャ操作を爆速化するテンプレート
‘ ==============================================================================
Sub ExecuteHighSpeedFeatureOperation()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim longstatus As Long
‘ 状態退避用の変数
Dim originalScreenUpdate As Boolean
Dim originalAutoRebuild As Boolean
‘ 1. アプリケーションとドキュメントの取得
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。”, vbCritical, “エラー”
Exit Sub
End If
‘ 2. エラーハンドリングの有効化(環境復元の担保)
On Error GoTo ErrorHandler
‘ 3. 現在の設定を退避(システム設定の読取)
originalScreenUpdate = swApp.GetUserPreferenceToggle(swUserPreferenceToggle_e.swViewDisplayUpdate)
originalAutoRebuild = swApp.GetUserPreferenceToggle(swUserPreferenceToggle_e.swDocumentPropertiesAutoRebuild)
‘ ==========================================================================
‘ 【核心】 描画の停止と、自動リビルドの無効化
‘ ==========================================================================
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayUpdate, False
swModel.FeatureManager.EnableUpdate = False ‘ フィーチャマネージャの更新も停止
‘ 4. メイン処理(ここに重いパーツ生成・編集処理を記述)
Dim i As Long
For i = 1 to 50
‘ サンプルとして何か重い処理をしていると仮定
Call DoHeavyOperation(swModel, i)
Next i
‘ ==========================================================================
‘ 【収束】 一括リビルドと環境の復元
‘ ==========================================================================
‘ フィーチャツリーの更新を再開
swModel.FeatureManager.EnableUpdate = True
‘ 最後に1度だけモデル全体を強制リビルド(ここで全変更が一度に計算される)
swModel.ForceRebuild3 False
‘ 描画設定を元に戻す
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayUpdate, True
‘ 画面を最新の状態に強制リフレッシュ
swModel.GraphicsRedraw
MsgBox “処理が正常に完了しました。”, vbInformation, “高速化完了”
Exit Sub
ErrorHandler:
‘ 【緊急脱出コード】 例外発生時も必ずSolidWorksの描画状態を復元する
On Error Resume Next
swModel.FeatureManager.EnableUpdate = True
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swViewDisplayUpdate, originalScreenUpdate
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swDocumentPropertiesAutoRebuild, originalAutoRebuild
swModel.GraphicsRedraw
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“詳細: ” & Err.Description, vbCritical, “致命的エラー”
End Sub
‘ ダミーの重い処理用プロシージャ
Private Sub DoHeavyOperation(ByRef swModel As SldWorks.ModelDoc2, ByVal index As Long)
‘ 実際にはここでボス押し出し、カット、パターンなどのAPIを叩く
‘ 例: swModel.Extension.SelectByID2 …
‘ この間、画面は一切再描画されず、裏で計算も走らないため極めて高速。
End Sub
—
4. チーフアーキテクトが教える、現場でハマる「3つの罠」
この手法を導入するにあたり、現場の開発者が陥りがちなしわ寄せポイントを先回りして共有しておく。
① `FeatureManager.EnableUpdate = False` との併用がカギ
`SetUserPreferenceToggle` だけでは、FeatureManagerのデザインツリー(左側のツリービュー)のアイコン更新やスクロール描画が走ってしまうことがある。`swModel.FeatureManager.EnableUpdate = False` を必ずセットで使うことで、ツリー側の描画・イベント発火も完全に沈黙させることができる。
② 処理途中のジオメトリ参照(セレクション)の罠
描画を止め、リビルドを止めると、「今生成したフィーチャの面やエッジを、次のコードで選択(SelectByID2等)して次のフィーチャを作る」という処理が失敗することがある。なぜなら、ジオメトリがまだカーネル上で確定(評価)されていないからだ。
一連の処理の中で「直前の生成結果に依存する幾何拘束」を行う場合は、適所で `swModel.EditRebuild3` を挟むか、APIオブジェクトのポインタ(参照)を直接保持して処理する設計に昇華させる必要がある。
③ データベースや外部ファイル連携時の注意点
もしこのマクロが、Excelや外部DBから数千件のパラメータを読み込んでパーツを次々と生成・上書き保存するバッチ処理である場合、メモリリーク(COMオブジェクトの解放漏れ)がパフォーマンス低下のもう一つの主犯になる。
ループ内で生成したオブジェクト(`SelectionMgr` や一時的な `MathPoint` など)は、不要になった時点で必ず `Set var = Nothing` で解放し、定期的にガベージコレクションを意識したコーディングを心がけよう。
—
総括
SolidWorks VBAにおけるパフォーマンスチューニングは、単なる「コードの小手先のテクニック」ではない。それは、CADという巨大な3Dエンジンのライフサイクルをエンジニアが手綱を握ってコントロールする「アーキテクチャ設計」そのものだ。
今回紹介した描画停止と再計算抑制のパターンをあなたのマクロに組み込むだけで、数分かかっていた処理が数秒で終わる「圧倒的な感動」を現場にもたらすことができる。
プロの仕事とは、ただ動くだけのコードを書くことではない。「ストレスのない、美しく速いシステム」を構築することだ。明日からの開発に、ぜひこの知見をフル活用してほしい。
