【実務・中級編】【レガシー保守】Onionレイヤー構造を持つ古いVBAマクロのクラスモジュール化と現代的なエラー処理へのリファクタリング – SolidWorks VBA解析バイブル

スポンサーリンク

SolidWorks VBAの「負の遺産」を殲滅せよ:Onionレイヤー構造による堅牢なクラス設計術

SolidWorks VBAの現場で、未だに `On Error Resume Next` が幅を利かせていないだろうか。

「とりあえず動けばいい」という考えで作られたスパゲッティコードは、数年後の自分やチームを確実に殺す。フィーチャ操作の失敗を握りつぶし、不正なオブジェクト状態でメモリを浪費し続けるマクロは、エンジニアリングツールではなく「爆弾」だ。

今日は、レガシーなマクロを、メンテナンス可能な「エンタープライズ級」の構造へ昇華させるための、Onion(オニオン)レイヤー設計現代的なエラーハンドリングの極意を授ける。

1. なぜ「On Error Resume Next」が罪深いのか

多くのVBAマクロが陥る罠は、エラーを無視することで「予期せぬ状態」を放置することだ。SolidWorks APIは、COMオブジェクトの寿命(LifeCycle)管理が非常にシビアだ。

フィーチャ生成に失敗した際、適当なリトライや無視を行うと、SolidWorksの内部メモリに「ゾンビ化した未定義フィーチャ」が残り、後の処理で`Access Violation`を引き起こす。エラーは隠蔽するのではなく、制御可能な形に変換し、適切に破棄(Dispose)しなければならない。

2. Onionレイヤー構造への転換

堅牢なマクロを作るには、責務を分離する。これがOnion構造の基本だ。

1. Core Layer (Domain): SolidWorks APIとの直接的な対話のみを行う。
2. Service Layer (Business Logic): 生成・編集の順序や条件を制御する。
3. UI/Entry Layer (Presentation): ユーザーインターフェースとエラー表示を行う。

これにより、ビジネスロジックを修正したいときに、APIの呼び出し手順まで書き換えるという「悲劇」を回避できる。

3. 実践:保守性の高いフィーチャ生成クラス

まずは、APIの複雑さを隠蔽するクラスモジュール `PartManager` の設計例を見てほしい。

‘ クラス名: PartManager
Option Explicit

Private swApp As SldWorks.SldWorks
Private swModel As SldWorks.ModelDoc2

‘ 初期化時にアプリケーションオブジェクトを注入(Dependency Injection)
Public Sub Initialize(ByRef app As SldWorks.SldWorks)
Set swApp = app
End Sub

‘ 堅牢なフィーチャ作成メソッド
Public Sub CreateExtrude(depth As Double)
‘ 構造化エラーハンドリング
On Error GoTo ErrorHandler

Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then Err.Raise 1001, “PartManager”, “ドキュメントが開かれていません”

‘ API操作の実行
Dim swFeature As SldWorks.Feature
Set swFeature = swModel.FeatureManager.FeatureExtrusion2(…)

If swFeature Is Nothing Then Err.Raise 1002, “PartManager”, “フィーチャ生成に失敗しました”

Exit Sub

ErrorHandler:
‘ ここでログ出力やクリーンアップを行う
Debug.Print “Error ” & Err.Number & “: ” & Err.Description
Err.Raise Err.Number, “PartManager”, Err.Description
End Sub

この設計のポイント:

  • エラーの伝播: `On Error Resume Next` で逃げず、`Err.Raise` で呼び出し元に問題を通知する。
  • ガード節: `If swModel Is Nothing` のように、処理の前提条件を冒頭でチェックする。
  • 単一責任: このクラスは「生成する」ことだけに集中する。

4. 現代的なエラーハンドリングとリソース解放

SolidWorks APIを使用する際、最も注意すべきは「オブジェクトの破棄」だ。VBAには明示的な `Dispose` はないが、`Set = Nothing` を確実に行うことで、COM参照カウントを適切に管理できる。

Public Sub SafeExecute()
Dim mgr As New PartManager

On Error GoTo Finalize
mgr.Initialize Application.SldWorks
mgr.CreateExtrude 0.05

Finalize:
‘ 異常終了時でも確実にリソースをクリーンアップ
Set mgr = Nothing

If Err.Number <> 0 Then
MsgBox “致命的なエラーが発生しました: ” & Err.Description, vbCritical
End If
End Sub

5. データベース連携時の黄金律

設計担当者がやりがちなのは、フィーチャ生成ループの中でDB接続を維持することだ。これは論外である。

1. データ取得: DBから必要なパラメータをすべてメモリ(配列やコレクション)に読み込む。
2. クローズ: DB接続を即座に切断する。
3. 生成: SolidWorksの操作を行う。
4. 結果保存: 最後に一度だけ接続して結果を書き込む。

SolidWorksが重い処理を行っている最中にDB接続がタイムアウトするリスクを排除せよ。

最後に:伝説のエンジニアとしてのアドバイス

「動くコード」を作るのは新米の仕事だ。「壊れないコード」を作り、「壊れたときに原因が即座にわかるコード」を書くのが、我々アーキテクトの仕事である。

今回紹介したクラス化と構造化エラーハンドリングは、最初の構築には手間がかかる。だが、その手間は、将来の数千時間に及ぶ「原因不明のバグ調査」を未然に防ぐための強力な投資だ。

明日からの開発では、`On Error Resume Next` をタイプする指を止め、まずはクラス図を書くことから始めてほしい。あなたのコードが、現場の資産となることを期待している。

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