SolidWorks APIの深淵:数千パーツの連続生成を「完遂」させるためのメモリ管理術
SolidWorksで数千規模のパーツを連続生成・保存するバッチ処理を組んだことがある諸君なら、一度は経験があるはずだ。
処理が数百個を超えたあたりでSolidWorksが重くなり、挙動が怪しくなり、最終的にはメモリを食いつぶしてプロセスがクラッシュする。
「コードは間違っていないはずなのに、なぜ落ちるのか?」
答えは単純だ。SolidWorks APIが裏で保持し続ける「選択バッファ」と「オブジェクトの寿命」を制御できていないからだ。
今日は、おもちゃのスクリプトから脱却し、プロダクションレベルの「止まらない自動化」を実装するための極意を伝授する。
—
1. なぜ「選択バッファ」がメモリを蝕むのか
SolidWorks APIにおいて、`Select2` や `SelectByID2` を実行するたびに、その選択情報は内部の「選択セット(Selection Manager)」に蓄積される。
恐ろしいことに、`ModelDoc2` を閉じても、この選択バッファが即座に解放されるとは限らない。特にループ処理の中でこれらを繰り返すと、メモリ上に無数の「幽霊のようなオブジェクト参照」が残り、ガベージコレクション(GC)が機能不全に陥る。
さらに、`UserControl`(SolidWorksのGUIプロセス制御)のフラグが適切でない場合、バックグラウンドでの描画更新やイベント監視が止まらず、CPU負荷が指数関数的に増大する。
—
2. 完遂を約束する黄金ルール
長時間バッチを成功させるには、以下の3つの鉄則を守れ。
1. 選択バッファを強制クリアせよ:各フィーチャ操作の前後で `ClearSelection2` を叩くのは当然だが、処理の節目で `IModelDocExtension::SelectAll` → `ClearSelection2` を組み合わせ、徹底的にバッファをパージする。
2. オブジェクトを明示的に解放せよ:VBAであっても、使い終わった `Feature` や `Sketch` 等のオブジェクトは `Set obj = Nothing` で即座に参照を断ち切る。
3. UserControlの抑制:不要な描画更新を止めるために `SldWorks::UserControl = False` を活用する。これにより、SolidWorksは「人間が見るためのGUI」から「計算のためのエンジン」へと変貌する。
—
3. 実装:メモリリークを抑え込む堅牢なコード
これが、数千回のパーツ生成にも耐えうる、私の設計したテンプレートだ。
‘ SolidWorksバッチ処理用・堅牢なメモリ管理テンプレート
Option Explicit
Public Sub GenerateBatchParts()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim i As Long
Set swApp = Application.SldWorks
‘ 重要: GUIの更新を停止し、処理速度とメモリ効率を最大化する
swApp.UserControl = False
swApp.Visible = True ‘ 完全非表示は不安定になる場合があるためVisibleは維持
On Error GoTo Cleanup
For i = 1 To 5000
‘ 新規パーツ作成
Set swModel = swApp.NewDocument(“Part”, 0, 0, 0)
‘ 処理実行
ProcessFeatureLogic swModel
‘ ファイル保存と解放
swModel.SaveAs2 “C:\Temp\Part_” & i & “.sldprt”, 0, False, False
swApp.CloseDoc swModel.GetTitle
‘ 強制的なメモリ解放
Set swModel = Nothing
‘ 100回に一度、強制的にGCを意識したインターバルを置くのも有効
If i Mod 100 = 0 Then DoEvents
Next i
Cleanup:
‘ 最後に制御を戻す
swApp.UserControl = True
MsgBox “全処理完了”
End Sub
Private Sub ProcessFeatureLogic(ByVal swModel As SldWorks.ModelDoc2)
‘ 選択バッファを常にクリーンに保つ
swModel.ClearSelection2 True
‘ フィーチャ生成等の操作
‘ … (ここにロジック) …
‘ 最後に再度クリア(次の処理への汚染を防ぐ)
swModel.ClearSelection2 True
End Sub
—
4. プロの視点:データベース連携の注意点
もしこのバッチがSQL Server等のデータベースと連携している場合、接続(Connectionオブジェクト)をループの中で開閉するな。
数千回も接続の確立と切断を繰り返せば、ネットワークのオーバーヘッド以上に、DB側のセッション管理が追いつかなくなる。
- バッチ開始時にDB接続を開く
- トランザクション単位でコミットする
- 終了時に必ず接続を閉じる
この基本を怠ると、SolidWorks側の安定性がどれほど高くても、DB側からエラーを吐いてバッチが停止する羽目になる。
—
結論:コードは「美しく」ではなく「粘り強く」書け
業務自動化エンジニアにとって、コードの美学とは「いかに少ない行数で書くか」ではない。「いかに過酷な条件下でもエラーを吐かずに完走するか」である。
SolidWorksは巨大なソフトウェアだ。そのリソースを制御下におくためには、APIの「お作法」を逆手に取ったメモリ管理が不可欠となる。今回紹介した`UserControl`の抑制と、徹底した`ClearSelection2`の運用を徹底すれば、あなたの夜間バッチは、翌朝には必ず成功しているはずだ。
さあ、恐れずにコードを書け。ただし、メモリの足跡には常に気を配ることだ。
