【テクニカル・上級編】【エラーハンドリング】On Error Resume NextとErr.Clearの適切なスコープ設計による泥臭いリトライ処理の実装 – SolidWorks VBA解析バイブル

スポンサーリンク

SolidWorks APIの「不条理」を飼い慣らす:エラーハンドリングの極致

SolidWorks API開発の現場で、`On Error Resume Next`を「とりあえずのエラー回避策」として乱用しているなら、今すぐその手を止めてほしい。

SolidWorksという巨大なモンスターは、単なるCOMオブジェクトの集まりではない。バックグラウンドで走る複雑なジオメトリエンジン、不安定な選択状態、メモリリークのリスク。これらと対峙する時、我々に求められるのは「綺麗事のコーディング」ではなく、泥臭いまでの「生存戦略」である。

今日は、APIが投げてくる不可解なCOM例外を制御し、システムを止めることなくリトライへと昇華させるための「プロフェッショナルな例外設計」を伝授する。

1. 原則:エラーハンドリングのスコープは「最小」に

多くの開発者が陥る罠は、モジュール全体を`On Error Resume Next`で覆い隠すことだ。これでは何が起きたのかすら分からず、デバッグは不可能になる。

エラーハンドリングは、「失敗が予見される操作」の直前で有効化し、直後に即座に解除(On Error GoTo 0)する。これが鉄則だ。

泥臭いリトライロジックの設計パターン

フィーチャの挿入や面選択は、SolidWorksの内部状態(Rebuild状態)に依存するため、失敗する前提で設計すべきだ。

‘ 伝説的なチーフアーキテクトが推奨するリトライ設計
Public Function SafeCreateFeature(swModel As SldWorks.ModelDoc2, featureData As Object) As Boolean
Dim retryCount As Integer
Dim success As Boolean

For retryCount = 1 To 3
‘ エラー監視の開始
On Error Resume Next

‘ 失敗の可能性が高い操作(フィーチャ挿入など)
swModel.FeatureManager.InsertFeatureDefinition featureData

‘ エラー状態を判定
If Err.Number = 0 Then
success = True
‘ 成功したら即座にハンドラを解除
On Error GoTo 0
Exit For
Else
‘ ログ出力と状態のリセット
Debug.Print “Attempt ” & retryCount & ” failed: ” & Err.Description
Err.Clear

‘ 重要なポイント:少しだけ時間を置く(OSのメッセージループに委ねる)
Sleep 500

‘ 必要であればモデルを強制再構築してクリーンな状態へ
swModel.ForceRebuild3 False
End If

On Error GoTo 0
Next retryCount

SafeCreateFeature = success
End Function

2. Windows APIによる「強制的な待機」の重要性

SolidWorksのGUIが処理を終えたように見えても、バックグラウンドのプロセスがジオメトリ計算を継続していることがある。VBAの`DoEvents`だけでは不十分なケースが多い。

Windows APIの`Sleep`を併用し、プロセスが落ち着くのを待つ「間」を作ることが、リトライ成功率を劇的に引き上げる。

If VBA7 Then
Private Declare PtrSafe Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
Else
Private Declare Sub Sleep Lib “kernel32” (ByVal dwMilliseconds As Long)
End If

3. メモリ解放の哲学:Set Nothingは「誠意」である

SolidWorksのCOMオブジェクトは、参照カウントが残っている限りメモリを占有し続ける。特にループ処理内でフィーチャや面を操作する場合、明示的な解放を怠れば、数千のフィーチャを生成するコードは必ずクラッシュする。

鉄壁のオブジェクト解放テンプレート

Sub RobustProcess(swModel As SldWorks.ModelDoc2)
Dim swFeat As SldWorks.Feature
Dim swSubFeat As SldWorks.Feature

‘ … 処理 …

‘ 最後に参照を徹底的に切断する
Set swSubFeat = Nothing
Set swFeat = Nothing

‘ ガベージコレクションを促すため、必要に応じてDoEventsを挟む
DoEvents
End Sub

4. 伝説のアーキテクトからの助言:なぜ「泥臭さ」が必要か

大規模なアセンブリや複雑な曲面を含むパーツにおいて、SolidWorksは時として「APIの要求」と「ジオメトリの整合性」の間で矛盾を起こす。

  • 選択失敗: 面を選択しようとしても、直前のフィーチャが未再構築で面が一時的に消失している。
  • APIタイムアウト: 大規模モデルでAPIが応答を待たずに切断される。

これらを解決するのは、最新のモダン言語によるスマートな例外処理ではなく、「失敗したなら待て。待ってもダメなら再構築せよ。それでもダメなら、モデルを閉じて開き直す勇気を持て」という、泥臭いまでの執念だ。

最後に

システムは、書いた通りの挙動をするのではない。「エラーが起きた後の挙動」を定義した通りに動くのだ。

あなたが書くコードが、明日の朝、誰かのPCで「エラーで止まりました」とアラートを出すか、それとも「黙々と仕事を完了させる」か。それは、`Err.Clear`の使い所に、あなたの技術者としての魂が宿っているかどうかにかかっている。

健闘を祈る。

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