SolidWorks APIの深淵:ミリ秒を支配する「高精度プロファイリング基盤」の構築
SolidWorksの自動化において、多くのエンジニアは「動けば良い」というコードを書く。しかし、数千のフィーチャを生成する大規模なパーツ自動生成において、そのアプローチは破滅を招く。処理がフリーズしたかのように停滞し、タスクマネージャーを眺めるだけの無為な時間は、我々には許されない。
真の自動化エンジニアは、「コードがどこで呼吸を止め、どこでCPUを浪費しているか」を可視化しなければならない。今回は、`FileSystemObject(FSO)`と`Windows API`を統合し、ミリ秒単位の解像度でボトルネックを暴くための、プロフェッショナル向け計測基盤を伝授する。
—
1. なぜ「Time関数」では不十分なのか
VBAの`Timer`関数は精度が低く、高負荷なフィーチャ演算の合間を計測するには粗すぎる。我々が求めるのは、Windowsカーネルレベルの計測だ。`QueryPerformanceCounter`(QPC)を用いることで、マイクロ秒単位の計測が可能となる。
高精度計測のためのAPI定義
‘ Windows APIによる高精度タイマーの実装
If VBA7 Then
Private Declare PtrSafe Function QueryPerformanceCounter Lib “kernel32” (lpPerformanceCount As Currency) As Long
Private Declare PtrSafe Function QueryPerformanceFrequency Lib “kernel32” (lpFrequency As Currency) As Long
Else
Private Declare Function QueryPerformanceCounter Lib “kernel32” (lpPerformanceCount As Currency) As Long
Private Declare Function QueryPerformanceFrequency Lib “kernel32” (lpFrequency As Currency) As Long
End If
Private m_Frequency As Currency
Private m_StartCount As Currency
‘ インスタンス初期化時に一度だけ実行
Public Sub InitializeTimer()
QueryPerformanceFrequency m_Frequency
End Sub
—
2. FSOを駆使した非同期ロギングの極意
大規模なパーツ生成では、ログ出力自体がディスクI/Oのボトルネックになる可能性がある。しかし、適切に`TextStream`を管理すれば、メモリを食いつぶすことなく、安定したトレースが可能だ。
プロファイリング・ロガーの実装
Public Sub WriteLog(ByVal ProcessName As String)
Dim FSO As Object
Dim ts As Object
Dim EndCount As Currency
Dim ElapsedTime As Double
QueryPerformanceCounter EndCount
‘ 経過時間をミリ秒で算出
ElapsedTime = (EndCount – m_StartCount) / m_Frequency 1000
‘ FSOによるログ書き込み(追記モード)
Set FSO = CreateObject(“Scripting.FileSystemObject”)
Set ts = FSO.OpenTextFile(“C:\Temp\SolidWorks_Perf.log”, 8, True)
ts.WriteLine Now & ” | ” & ProcessName & ” | ” & Format(ElapsedTime, “0.000”) & ” ms”
ts.Close
‘ オブジェクトの明示的解放:メモリリークは許さない
Set ts = Nothing
Set FSO = Nothing
‘ 次の計測のためにリセット
QueryPerformanceCounter m_StartCount
End Sub
—
3. 実践:フィーチャ生成のボトルネックを暴く
SolidWorksのAPI、特に`IFeatureManager`を多用する際、どのメソッドが重いのか。以下の構造でコードをラップせよ。
Public Sub RebuildPartBody()
InitializeTimer
QueryPerformanceCounter m_StartCount
‘ フェーズ1: スケッチ作成
Dim swSketch As Object
‘ … スケッチ生成処理 …
WriteLog “Sketch Creation”
‘ フェーズ2: 複雑な押し出しフィーチャ生成
Dim swFeature As Object
‘ … FeatureManager.FeatureExtrusion2 などの重い処理 …
WriteLog “Extrusion Feature”
‘ フェーズ3: フィレット・面取り演算
‘ …
WriteLog “Fillet Operation”
End Sub
—
4. チーフアーキテクトからの忠告
この手法を導入する上で、以下の「鉄則」を忘れてはならない。
1. オブジェクトの明示的解放: `Set swApp = Nothing`だけでは不十分だ。複雑なアセンブリ操作を行う際、`swModelDoc2`や`swFeature`の参照が残っていると、SolidWorksはメモリをキャッシュし続ける。スコープを厳密に区切り、ローカル変数を適切に破棄せよ。
2. イミディエイトウィンドウの過信を捨てよ: 実行中に`Debug.Print`を乱打するのは、UIスレッドをブロックする愚行だ。今回のコードのように外部ファイルへログを逃がすことで、SolidWorksのイベントループを阻害せずに計測を行うのが「正しい」設計である。
3. 再計算(Rebuild)のタイミング制御: 多くのエンジニアが陥る罠が、ループ内での過剰な`ForceRebuild3`だ。ログを解析し、`AutoSolve`や`FreezeFeature`を適切に活用して、無駄な再計算を削ることに注力せよ。
結び
コードは単なる命令の羅列ではない。それはCPUとメモリ、そしてSolidWorksの幾何エンジンとの対話である。計測なき最適化は、ただの勘に頼る当てずっぽうだ。この基盤を基に、君の書くマクロが「0.1秒の高速化」という研ぎ澄まされた刃物へと進化することを期待する。
次回の講義では、`COMインターフェース`を直接叩くことで、VBAの抽象化層を突き抜ける「真の高速化テクニック」について触れることとしよう。
