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

スポンサーリンク

墓場からの脱却:SolidWorks VBAにおける「Onionアーキテクチャ」の再構築と生存戦略

SolidWorksの自動化において、我々が直面する最大の敵は「過去の自分」が書いた、あの罪深いコードだ。`On Error Resume Next`を盾に、エラーを握りつぶして突き進む「ゾンビのようなマクロ」。これに苦しめられている現場は少なくない。

今日は、その泥沼のレガシーを、堅牢なクラス設計へと昇華させるための「解剖学」を伝授する。

1. 「On Error Resume Next」という名の自殺行為

まず大前提として、VBAにおけるエラーハンドリングを「避ける」ことは、「ブレーキの効かない車で時速200kmを出す」のと同じだ。SolidWorks APIは、COMインターフェースを介した不安定な通信の連続である。

  • 何が起きるのか?:メモリリーク、ゾンビプロセスとしての`SLDWORKS.exe`の残留、そして何より「どこで落ちたか分からない」というデバッグの泥沼化。
  • あるべき姿:エラーは「発生させるもの」ではなく「予測し、封じ込めるもの」である。

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

SolidWorksの自動化を、以下の3階層(Onion)に分離する。これが、保守性を極限まで高めるための黄金律だ。

1. Core Layer (API Wrapper): `SldWorks`や`ModelDoc2`の生APIをラップし、低レイヤーのCOM操作をカプセル化する。
2. Domain Layer (Feature Factory): スケッチや押し出しなど、ビジネスロジック(設計意図)を定義する。
3. Application Layer (Controller): UIやファイル操作、外部システム連携を司る。

3. 実装:堅牢なクラスモジュールの雛形

単なるモジュールではなく、「IDisposable」の精神を持ったクラス設計を行う。`Terminate`イベントを活用し、明示的なオブジェクト解放を徹底する。

‘ クラスモジュール: SolidWorksWrapper
Option Explicit

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

‘ 初期化処理:外部から注入(DIの概念)
Public Sub Initialize(ByRef app As SldWorks.SldWorks)
Set swApp = app
End Sub

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

If swApp Is Nothing Then Err.Raise 1001, , “SolidWorksが起動していません。”

‘ ここにフィーチャ操作ロジック
‘ …

CreateExtrude = True
Exit Function

ErrorHandler:
‘ ログ出力および適切なクリーンアップ
Debug.Print “Error ” & Err.Number & “: ” & Err.Description
CreateExtrude = False
End Function

‘ 終了処理:メモリの解放を強制する
Private Sub Class_Terminate()
Set swModel = Nothing
Set swApp = Nothing
‘ 必要に応じて、未解放のCOMオブジェクトを監視・破棄するロジックをここに
End Sub

4. シニアエンジニアが知るべき「メモリ管理の極意」

VBAのガーベジコレクションは、我々が想像するほど優秀ではない。特にループ処理内でフィーチャを大量生成する場合、以下の鉄則を守れ。

  • Set Nothing の徹底: ループ内で`Set swFeat = swModel.FeatureManager.FeatureExtrusion2(…)`としたら、処理の最後に必ず`Set swFeat = Nothing`を呼べ。これを怠ると、数千回のループでメモリは枯渇する。
  • APIの呼び出し回数を最小化: `swModel.Extension.SelectByID2`などをループの中で呼ぶのは罪だ。可能な限り、`FeatureManager`の直接操作や、`SelectionManager`のキャッシュを利用せよ。
  • Windows APIによるプロセス監視: 処理が長時間に及ぶ場合、`EnumProcesses`を使用して、SolidWorksのメモリ消費量を監視し、閾値を超えたらログを吐いて安全に終了させるガードレールを実装すべきだ。

5. レガシー保守の極致:システム間連携

ERPやPDMと連携する場合、Excel VBAを「ただの仲介役」にするな。JSONライブラリを導入し、データ構造を疎結合にせよ。

現代的なアーキテクチャでは、「VBAは単なるインターフェース」と割り切るのが賢明だ。重い計算や複雑なデータ処理は、別途DLL(C#/.NETで作ったもの)に逃がし、VBAはCOM呼び出しだけを行うようにすれば、SolidWorksの安定性は劇的に向上する。

結論:技術は「消去法」で洗練される

レガシーコードの改善とは、新しい機能を足すことではない。「動かない原因を徹底的に排除し、動く理由を明確にすること」だ。

`On Error Resume Next`を削除し、クラスのライフサイクルを管理し、メモリの最後の一滴まで制御下に置く。これこそが、SolidWorks VBAという古の技術を、現代のエンジニアリングの最前線で戦わせるための唯一の道である。

さあ、墓場からコードを掘り起こし、その息の根を止めて、新たな生命を吹き込め。健闘を祈る。

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