【実務・中級編】【レガシーコードのリファクタリング】廃止予定となった古いSolidWorks APIメソッドの特定とモダンAPIへの置換術 – SolidWorks VBA解析バイブル

スポンサーリンク

廃止予定APIの呪縛を断て!SolidWorks VBAレガシーコード徹底リファクタリング術

開発現場のエンジニア諸君、よく聞いてほしい。
君たちが日々メンテナンスしているそのSolidWorks VBAマクロ、いつ突然「コンパイルエラー」や「実行時エラー」を吐き出すかビクビクしていないか?

「昔の先輩が書いたコードだから触りたくない」
「動いているからそのままにしている」

その技術的負債、そろそろ限界だ。SolidWorks APIはバージョンアップのたびに静かに、しかし確実に進化している。かつて主流だったメソッドは「Obsolete(非推奨)」の烙印を押され、ある日突然、完全廃止(Deprecated)の運命を辿る。

今回は、レガシーコードに潜む時限爆弾を特定し、現代のSolidWorks API仕様に則った「堅牢で、速く、10年後も耐えうるモダンVBAコード」へと生まれ変わらせるための極限の知見を伝授する。

1. なぜレガシーAPIは悪なのか?(パフォーマンスとライフサイクルの真実)

古いAPIを使い続けることは、単に「将来動かなくなるリスク」だけではない。最大の害悪は「メモリリークとCOMオブジェクトの暴走」だ。

SolidWorks VBAの背後では、巨大なC++ベースのCOM(Component Object Model)が稼働している。古いメソッドは、メモリ管理(特に`.Release`やポインタの解放)が曖昧だったり、アクティブドキュメントのコンテキスト(`SldWorks::ActiveDoc`など)に過度に依存したりするものが多い。

これらが原因で、以下のような実務上の致命傷を引き起こす。

  • バックグラウンドプロセス(SLDWORKS.exe)のゾンビ化:マクロ終了後もタスクマネージャーにプロセスが残り続け、PCのリソースを食いつぶす。
  • サイレントクラッシュ:エラーメッセージすら出さずにSolidWorksごと強制終了する。
  • 図面・アセンブリのコンテキスト迷子:複数ウィンドウを開いた状態で、意図しないモデルに対して処理が走る。

プロのエンジニアであれば、APIの背後にある「オブジェクトのライフサイクル」を完全にコントロールしなければならない。

2. 狩り場:よくある「廃止・非推奨API」のワーストパターン

まずは、君たちのコードベースに巣食う代表的なレガシー表現をあぶり出そう。

① `SldWorks.IAssemblyDoc::AddPackAndGo` などの旧式データ管理

ファイルのコピーやアーカイブ化において、古いファイル参照解決メソッドは現在のPDM環境や複雑なアセンブリ構造に対応しきれていない。

② `ModelDocExtension::SelectByID` の乱用

現在、単なる `SelectByID` は推奨されない。代わりに、厳密なエンティティ指定が可能な `SelectByID2`、さらにはモダンなセレクションマネージャを活用すべきだ。

③ 暗黙的な `ActiveDoc` への依存

これが最大にして最悪のアンチパターンである。

‘ 【悪夢のレガシーコード】
Dim swApp As SldWorks.SldWorks
Set swApp = Application.SldWorks
swApp.ActiveDoc.SaveAs2 “C:\Test.sldprt”, … ‘ 何が開いているか運任せ

現在のドキュメントを明示的に取得・保持せず、`ActiveDoc` に頼るコードは、ユーザーが別のタブをクリックした瞬間に爆散する。

3. 【実践】モダンAPIへの置換と堅牢なリファクタリング設計

では、実際にどう書き換えるべきか。
以下のプロダクションコードを見てほしい。これは、現在アクティブなモデルに対して安全に処理を行い、オブジェクトの参照を適切に管理する、実務直結のモダンVBAテンプレートだ。

Option Explicit

‘ ==============================================================================
‘ 担当者: チーフアーキテクト
‘ 概要: レガシーコードを駆逐したモダンSolidWorks VBAテンプレート
‘ 特徴: 厳格な型定義、エラーハンドリング、COMオブジェクトの適切な解放
‘ ==============================================================================
Public Sub ExecuteModernProcess()
‘ 1. アプリケーションの確実な取得
Dim swApp As SldWorks.SldWorks
Set swApp = GetObject(, “SldWorks.Application”)

If swApp Is Nothing Then
MsgBox “SolidWorksが起動していません。”, vbCritical, “致命的エラー”
Exit Sub
End If

‘ 2. グローバルなActiveDocに頼らず、モデルを明示的にキャプチャ
Dim swModel As SldWorks.ModelDoc2
Set swModel = swApp.IActiveDoc2

If swModel Is Nothing Then
MsgBox “処理対象となるドキュメントが開かれていません。”, vbExclamation, “警告”
Exit Sub
End If

‘ 3. ドキュメントタイプの判定(定数はtype安全に処理)
Dim docType As Long
docType = swModel.GetType

Select Case docType
Case swDocPART
Call ProcessPart(swModel)
Case swDocASSEMBLY
Call ProcessAssembly(swModel)
Case swDocDRAWING
Call ProcessDrawing(swModel)
Case Else
MsgBox “未対応のドキュメントタイプです。”, vbCritical
Exit Sub
End Select

‘ 4. クリーンアップ(VBAでは自動解放されるが、大規模マクロでは参照破棄が定石)
Set swModel = Nothing
Set swApp = Nothing

MsgBox “すべての処理が正常に完了しました。”, vbInformation, “完了”
End Sub

Private Sub ProcessPart(ByVal swModel As SldWorks.ModelDoc2)
‘ 現代的かつ安全なパーツ処理ロジック
Dim swPart As SldWorks.PartDoc
Set swPart = swModel

‘ 例: ユーザー定義プロパティの安全な取得・設定など
Dim swCustPropExt As SldWorks.CustomPropertyManager
Set swCustPropExt = swModel.Extension.CustomPropertyManager(“”)

Dim valOut As String
Dim resolvedOut As String
Dim wasResolved As Boolean

‘ 古いGet函数の代わりにモダンな拡張プロパティマネージャを使用
swCustPropExt.Get5 “Material”, False, valOut, resolvedOut, wasResolved

Debug.Print “Current Material: ” & resolvedOut

Set swCustPropExt = Nothing
Set swPart = Nothing
End Sub

Private Sub ProcessAssembly(ByVal swModel As SldWorks.ModelDoc2)
‘ アセンブリ固有のモダン処理
Dim swAssy As SldWorks.AssemblyDoc
Set swAssy = swModel

‘ 構成部品の走査などはここで安全に行う

Set swAssy = Nothing
End Sub

Private Sub ProcessDrawing(ByVal swModel As SldWorks.ModelDoc2)
‘ 図面固有のモダン処理
Dim swDraw As SldWorks.DrawingDoc
Set swDraw = swModel

Set swDraw = Nothing
End Sub

4. チーフアーキテクトからの提言:ファイル・データベース連携の注意点

業務自動化を進めると、SolidWorksマクロからExcel、Access、あるいは社内PLM/PDMデータベースへ直接データを書き込む設計にしがちだ。

ここでレガシーな手法(例:古いADO接続や、ファイルパスのハードコーディング)を使っていると、ネットワークの瞬断やファイルロックでマクロが沈黙する。

1. ファイルパスの動的解決とバリデーション
ハードコーディングされた `C:\Work\…` は即座に廃止せよ。必ず `ModelDoc2::GetPathName` からディレクトリを取得し、FileSystemObject (FSO) を用いて動的にパスを構築すること。
2. トランザクション的な思考を持つ
ファイル保存(`Save3` や `SaveAs3`)を行う際は、必ずエラー監視を挟み、途中で失敗した場合は変更を破棄(`ReloadOrReloadWithOptions` 等の活用)する堅牢性を担保しろ。

5. まとめ:明日から始めるリファクタリングのファーストステップ

レガシーコードの刷新は、一気にやろうとすると挫折する。以下のステップで段階的に進めるのがプロの流儀だ。

1. 「Option Explicit」の強制:変数の宣言漏れによる暗黙のバリアント型を撲滅する。
2. `ActiveDoc` の排除:すべてのプロシージャで `ModelDoc2` を引数として渡す設計(Dependency Injection的アプローチ)に変更する。
3. APIヘルプ(API Help)の常時確認:新しいコードを書くときは必ず最新のSolidWorks APIヘルプを開き、該当メソッドに「Obsolete」の文字がないか確認する癖をつける。

君たちの書くコードが洗練されれば、それだけ会社の設計プロセスは加速し、無駄なトラブルは消え去る。
さあ、今すぐ古いエディタを開き、負債の刈り取りを始めよう。

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