廃止予定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」の文字がないか確認する癖をつける。
君たちの書くコードが洗練されれば、それだけ会社の設計プロセスは加速し、無駄なトラブルは消え去る。
さあ、今すぐ古いエディタを開き、負債の刈り取りを始めよう。
