【実務・中級編】【上級プロ】レガシーマクロのモダンリファクタリング:グローバル変数依存のコードをクラスモジュール化して保守性を極限まで高める – SolidWorks VBA解析バイブル

スポンサーリンク

伝説のコードへ昇華せよ:SolidWorks VBAを「クラス」で制御する極限の作法

現場でよく見る「動けばいい」という考えで書かれたスパゲッティコードは、数ヶ月後の自分にとってのテロリストだ。特にアセンブリの自動構築において、グローバル変数に頼った設計は、エラーハンドリングを絶望的にし、メモリリークの温床となる。

今日は、SolidWorks APIを使いこなすプロとして、「脱・手続き型」のクラスモジュール設計によるアセンブリ自動化の極意を伝授する。

—

なぜ「手続き型」は沈没するのか

多くのエンジニアが犯す最大の過ちは、`swApp` や `swModel` を標準モジュールでグローバルに宣言し、関数間で使い回すことだ。これには以下の致命的な欠陥がある。

1. 状態の汚染: 複数のアセンブリ処理が並行または連鎖した際、変数の参照が意図せず書き換わる。
2. スコープの無法地帯: どこで誰がファイルを閉じたのか、どの関数がポインタを無効化したのか追跡不能になる。
3. 再利用性の欠如: 特定のプロジェクトに依存しすぎて、部品配置のロジックを別プロジェクトに移植できない。

これらを解決する唯一の正解が、「アセンブリ操作のオブジェクト化」である。

—

実践:アセンブリ構築をクラスにカプセル化する

今回は、部品をアセンブリに投入し、特定の合致を定義するクラス `AssemblyAutomator` を構築する。

1. クラスモジュール:`AssemblyAutomator.cls`

まずは、アセンブリの状態を管理する核となるクラスを定義する。

‘ AssemblyAutomator.cls
Option Explicit

Private swApp As SldWorks.SldWorks
Private swAssy As SldWorks.AssemblyDoc

‘ コンストラクタ代わりの初期化メソッド
Public Sub Initialize(app As SldWorks.SldWorks, assy As SldWorks.ModelDoc2)
Set swApp = app
If Not assy Is Nothing Then
Set swAssy = assy
Else
Err.Raise vbObjectError + 1, “AssemblyAutomator”, “アセンブリが正しく指定されていません。”
End If
End Sub

‘ パーツを配置し、合致を作成するロジック
Public Function AddComponentWithMate(compPath As String, targetEntityName As String) As Boolean
Dim swComp As SldWorks.Component2
Dim swModel As SldWorks.ModelDoc2

‘ 1. コンポーネントの挿入
Set swComp = swAssy.AddComponent(compPath, 0, 0, 0)
If swComp Is Nothing Then Exit Function

‘ 2. 合致作成のロジック(簡略化)
‘ ここでグローバル変数を使わず、渡されたインスタンス内で完結させる
Debug.Print “Component added: ” & swComp.Name2

AddComponentWithMate = True
End Function

2. 呼び出し側のコード:`Main.bas`

メイン処理は極めてクリーンになる。これが「保守性が高い」ということだ。

Sub RunAutomation()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim automator As New AssemblyAutomator

Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc

‘ クラスに依存関係を注入する
automator.Initialize swApp, swModel

‘ 業務ロジックの実行
If automator.AddComponentWithMate(“C:\Parts\Bolt.sldprt”, “Plane1”) Then
MsgBox “構築完了”
End If
End Sub

—

プロが教える「陥りがちな罠」と回避策

1. ファイルハンドルの保持と解放

`AddComponent` を繰り返すと、SolidWorks側のキャッシュが溜まり、メモリ使用量が急増する。長時間稼働するツールであれば、定期的に `swModel.ForceRebuild3 True` を呼び出し、不要になったオブジェクトは `Set obj = Nothing` で明示的にメモリを解放せよ。

2. インターフェースの厳格化

アセンブリの合致作成(`AddMate`)は非常に繊細だ。エンティティ(面や軸)の取得に失敗するとSolidWorksがクラッシュする。

  • 対策: `SelectByRay` などの選択メソッドに頼らず、名前指定(`SelectByID2`)を優先する。また、`Select` 系のメソッドの戻り値を必ずチェックし、`False` ならば即座に例外を投げる設計にすること。

3. データベース連携(外部ファイル読込)

CSVやJSONから構成情報を読み込む際、標準モジュールでファイル処理を完結させてはいけない。`FileParser` のような専用クラスを作成し、`AssemblyAutomator` に「データ」として渡す設計にする。これにより、将来的にデータソースがExcelからSQL Serverに変わっても、アセンブリ構築ロジックには一行も手を入れなくて済む。

—

最後に:自動化は「設計」が全て

VBAは古臭い言語だと言われる。しかし、それは言語のせいではなく、書く側の設計思想が古いからだ。
クラスモジュールを使いこなし、SolidWorksのAPIを「オブジェクトの連鎖」として捉えることができれば、あなたの書くツールは、単なるスクリプトから「強固な自動化エンジン」へと進化する。

次にマクロを書くときは、こう自問してほしい。
「このコードを、半年後の自分が深夜に修正しても、一切の迷いなく動くか?」

その答えが「Yes」と言い切れるコードこそが、真のプロダクションコードだ。

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