【テクニカル・上級編】【堅牢なエラーハンドリング】On Error Resume NextとGetObjectを用いた安全な例外処理 – SolidWorks VBA解析バイブル

スポンサーリンク

SolidWorks APIの深淵:堅牢なエラーハンドリングとプロセス生存戦略

SolidWorksの自動化において、コードの「正常系」を記述するのは初心者でもできる。しかし、我々のようなシステムアーキテクトが真に時間を割くべきは、「SolidWorksが死ぬ瞬間」をいかに検知し、安全に軟着陸させるかという一点に尽きる。

本稿では、`On Error Resume Next`の乱用を卒業し、Windows APIとプロセス間通信を制御することで、エンタープライズ環境に耐えうる堅牢なVBA実装の極意を解説する。

1. GetObjectの真の目的:インスタンスの「生存確認」

多くの開発者が `GetObject(, “SldWorks.Application”)` を単なる起動判定として用いているが、これは片手落ちだ。SolidWorksがバックグラウンドで「応答なし」の状態に陥っている場合、このメソッドは無意味な待ち時間を発生させるか、あるいはハングアップを誘発する。

真のプロは、「プロセスが生存しているか」と「COMが応答可能か」を分離して考える。

実装例:安全なインスタンス取得

Public Function GetSWApp() As SldWorks.SldWorks
Dim swApp As Object

‘ 既に稼働しているインスタンスをアタッチ
On Error Resume Next
Set swApp = GetObject(, “SldWorks.Application”)
On Error GoTo 0

‘ プロセスが発見できない、またはCOMが反応しない場合のハンドリング
If swApp Is Nothing Then
Err.Raise vbObjectError + 1001, “GetSWApp”, “SolidWorksプロセスが見つかりません。”
End If

‘ オブジェクトの有効性を検証する(重要な一手)
‘ バージョン情報を取得し、応答があれば生存とみなす
Dim version As String
On Error Resume Next
version = swApp.RevisionNumber()
If Err.Number <> 0 Then
Set swApp = Nothing ‘ 応答なしの場合は解放する
End If
On Error GoTo 0

Set GetSWApp = swApp
End Function

2. On Error Resume Nextを「局所的」に封じ込める

`On Error Resume Next`は諸刃の剣だ。広範囲に適用すれば、予期せぬバグを隠蔽し、デバッグ不可能なモンスターコードを生み出す。

鉄則:エラーが発生しうる「最小単位のスコープ」のみに適用し、直後にエラーコードを検証せよ。

‘ 悪い例: サブルーチン全体に適用
‘ 良い例: 特定のAPIコールのみを囲い込む

Dim swModel As SldWorks.ModelDoc2
Set swModel = swApp.ActiveDoc

‘ ファイル操作はOSレベルの遅延が発生するため、ここだけを厳格に管理する
On Error Resume Next
swModel.SaveAs2 “C:\Path\To\File.SLDPRT”, 0, False, False
Dim errCode As Long: errCode = Err.Number
On Error GoTo 0

If errCode <> 0 Then
‘ ここでログ出力し、必要であればプロセスを強制終了(TaskKill)する判断を行う
Logger.Log “保存失敗: ” & errCode
Exit Sub
End If

3. メモリ解放の極致:明示的なNothing化とCOM参照

VBAのガーベジコレクションを過信してはならない。特に`ModelDoc2`や`Feature`オブジェクトをループ処理で大量に生成する場合、メモリリークは確実にシステムをクラッシュさせる。

メモリ最適化のチェックリスト

1. 参照の明示的解放: ループ内でのオブジェクト生成は必ず `Set obj = Nothing` で即座に解放する。
2. 型指定の徹底: `Variant`型を避け、必ず`SldWorks.ModelDoc2`等の具象型を指定せよ(バインディングのオーバーヘッドを削減する)。
3. 大容量モデルの取り扱い: `swApp.CloseDoc` の後に、不要なCOM参照がスタックに残っていないか確認する。

4. 最終防衛線:Windows APIによる強制介入

SolidWorksが完全にフリーズし、COM経由の操作が一切受け付けられない場合、VBA単体では何もできない。その時は、`kernel32.dll` を介して、プロセスID(PID)から強制終了を行うのが最善の策だ。

If VBA7 Then
Private Declare PtrSafe Function TerminateProcess Lib “kernel32” (ByVal hProcess As LongPtr, ByVal uExitCode As Long) As Long
Else
Private Declare Function TerminateProcess Lib “kernel32” (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
End If

‘ 運用保守の現場では、タスクマネージャーを開かせるのではなく、
‘ スクリプト側で「応答なしプロセス」を特定し、再起動する仕組みを組み込んでおくべきだ。

総括:伝説的アーキテクトからの助言

SolidWorks VBAの安定性は、コードの美しさよりも「いかに異常系を予測し、設計に組み込んでいるか」で決まる。

  • ユーザーにエラーメッセージを出させるな。 システムが自動で検知し、再起動または安全な離脱を行うのがプロの仕事だ。
  • APIは「生き物」だと思え。 メモリの断片化、Windows OSの割り込み、ネットワークドライブの切断。これら全てがAPIのレスポンスに影響を与える。

この知見を胸に、今日から君のコードを「動くもの」から「止まらないもの」へと進化させてほしい。それが、レガシーを掌握するエンジニアの唯一の道だ。

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