【SolidWorks VBAを掌握する極限の知見】レガシーマクロの呪縛を断つ:廃止予定APIの特定とモダン置換術
長年運用されてきたSolidWorks VBAマクロ資産は、企業の設計効率化の歴史そのものである。しかし、幾多のバージョンアップを生き抜いてきた「レガシーコード」の内部には、時限爆弾のように非推奨(Deprecated)となった古いAPIや、いつ機能停止してもおかからないアンチパターンが眠っている。
特に、SolidWorks APIはバージョンアップに伴う構造改革が激しい。昨日まで動いていたマクロが、メジャーアップデートの瞬間に突然「Type mismatch (エラー 13)」や「Object required (エラー 424)」を吐き出して停止する。この悪夢を防ぐためには、単に動くコードを書くだけではなく、「APIオブジェクトのライフサイクル」と「モダンAPIへの正しい移行」を熟知したアーキテクチャの刷新が必要不可欠である。
本稿では、レガシーマクロに潜む廃止予定APIをあぶり出し、長期保守性を極限まで高めるためのリファクタリング手法を、シニアエンジニアの視座から徹底解説する。
—
1. なぜレガシーAPIはシステムを崩壊させるのか?
SolidWorks VBAの背後で稼働しているのは、COM(Component Object Model)ベースの複雑なインターフェース群だ。`SldWorks.Application` を頂点とし、`ModelDoc2`、`PartDoc`、`AssemblyDoc`、`Feature` と続くオブジェクトツリーは、適切な解放と型安全性が担保されて初めて安定動作する。
レガシーコードの最大の問題点は以下の3点に集約される。
1. 暗黙の型変換(Variant型への過度な依存)と遅延バインディングの弊害
2. 廃止されたメソッド(例: 古い図面操作、古い選択・フィーチャー走査)の残留
3. COM参照の解放漏れによるメモリリークとSolidWorksプロセスのゾンビ化
これらを放置したまま運用を続けることは、地雷原を全速力で駆け抜けるようなものだ。まずは、あなたのマクロに潜む「死んだコード」を特定することから始めよう。
—
2. 廃止・非推奨APIの特定とモダン置換の極意
実務で最も遭遇頻度が高く、かつシステムを破壊しやすいレガシーパターンを、具体的な置換術とともに見ていく。
置換術①:モデル走査における `GetFirstFeature` / `GetNextFeature` の限界
フィーチャーツリーを走査する際、古いコードでは `GetFirstFeature` と `GetNextFeature` を再帰的に呼び出す手法が一般的だった。しかし、この方法はフィーチャーの削除や抑制状態の変化に極めて弱く、無限ループやメモリクラッシュを引き起こす温床となる。
【モダンアプローチ】
現代のAPIでは、`Feature` オブジェクトのポインタ管理が洗練されており、さらに上位のトラバーサル(走査)設計、あるいは `IFeature` インターフェースの確実な型キャストとエラーハンドリングが必須となる。
‘ ==============================================================================
‘ 【モダン】安全なフィーチャー走査の基本パターン
‘ ==============================================================================
Public Sub TraverseFeatures(ByVal swModel As SldWorks.ModelDoc2)
If swModel Is Nothing Then Exit Sub
Dim swFeat As SldWorks.Feature
Set swFeat = swModel.FirstFeature
‘ ループの安全性を高めるため、ポインタの生存確認を行う
Do While Not swFeat Is Nothing
Debug.Print “Feature Name: ” & swFeat.Name & ” | Type: ” & swFeat.GetTypeName2()
‘ 冗長なポインタチェーンを避け、確実に次のフィーチャーへ移行
Dim swNextFeat As SldWorks.Feature
Set swNextFeat = swFeat.GetNextFeature()
‘ 明示的にオブジェクト参照を破棄 (VBAのガベージコレクションの甘さを補う)
Set swFeat = Nothing
Set swFeat = swNextFeat
Loop
End Sub
置換術②:古い図面(Drawing)操作APIの刷新
図面ビューの取得やシート操作において、古い `ModelDoc2` の直叩きや、廃止されたビュー整列メソッドを使用しているレガシーコードは、最新のDrawingパフォーマンスに対応できず、描画崩壊を起こす。
특히、ビューのスケール変更やアタッチメントの再構築には、`IView` インターフェースのモダンなプロパティを使用すべきである。
—
3. 究極のメモリ最適化:COMオブジェクトの明示的解放
VBAのランタイムはガベージコレクション(GC)の挙動が非決定的(いつ実行されるか予測不能)である。これが、SolidWorksマクロの実行後に `SLDWORKS.exe` がタスクマネージャーに幽霊のように残り続ける(ゾンビプロセス化する)根本原因である。
シニアエンジニアとして、以下の鉄則をコードに刻み込む必要がある。
1. すべてのCOMオブジェクト変数は、処理終了時に `Set obj = Nothing` で明示的に解放する。
2. ループ内でオブジェクトを変数再利用する場合も、都度 `Nothing` を代入して参照カウントをデクリメントする。
3. エラー発生時(`On Error Goto`)でも確実なメモリ解放が行われるよう、クリーンアップブロックを必ず設ける。
実装パターン:極限まで最適化された堅牢なマクロ構造
‘ ==============================================================================
‘ 堅牢性とメモリ管理を極めた実務向けテンプレート
‘ ==============================================================================
Sub ExecuteRobustAutomation()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim lErrors As Long
Dim lWarnings As Long
‘ 1. アプリケーションインスタンスの安全な取得
Set swApp = GetObject(, “SldWorks.Application”)
If swApp Is Nothing Then
MsgBox “SolidWorksが起動していません。”, vbCritical
GoTo CleanUp
End Sub
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。”, vbExclamation
GoTo CleanUp
End Sub
‘ — 実際の業務処理(例:カスタムプロパティの書き換え等) —
Call ProcessModelData(swModel)
CleanUp:
‘ 2. 逆順かつ確実なオブジェクトの解放
Set swModel = Nothing
Set swApp = Nothing
‘ メモリの断片化を防ぐための解放合図(必要に応じて)
Erase Array() ‘ 内部キャッシュのフラッシュ的意味合い
Exit Sub
ErrorHandler:
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical
Resume CleanUp
End Sub
Private Sub ProcessModelData(ByRef model As SldWorks.ModelDoc2)
‘ 処理ロジック
Dim swCustPropMgr As SldWorks.CustomPropertyManager
Set swCustPropMgr = model.Extension.CustomPropertyManager(“”)
‘ プロパティ操作…
‘ 内部オブジェクトの即座の解放
Set swCustPropMgr = Nothing
End Sub
—
4. レガシー環境とモダンシステム間連携(Windows APIの活用)
実務の現場では、SolidWorks単体の自動化にとどまらず、Excel、Access、あるいは社内PDM/ERPシステムとの連携が求められる。ここでレガシーなVBAコードは、ウィンドウハンドルの不整合や、モーダルダイアログによるフリーズ(ハングアップ)を引き起こしやすい。
例えば、マクロ実行中にSolidWorksが裏画面に隠れてしまったり、エラーメッセージボックスが背面に回ってプロセスが応答しなくなったりする現象は、Windows APIを適切に駆使することで完全に制御できる。
‘ ==============================================================================
‘ Windows APIを用いたSolidWorksウィンドウの前面強制化・ハング防止
‘ ==============================================================================
If VBA7 Then
Private Declare PtrSafe Function SetForegroundWindow Lib “user32” (ByVal hwnd As LongPtr) As Long
Private Declare PtrSafe Function IsIconic Lib “user32” (ByVal hwnd As LongPtr) As Long
Private Declare PtrSafe Function ShowWindow Lib “user32” (ByVal hwnd As LongPtr, ByVal nCmdShow As Long) As Long
Else
‘ 32bit環境互換(必要に応じて)
End If
Const SW_RESTORE As Long = 9
Public Sub BringSolidWorksToFront(ByVal swApp As SldWorks.SldWorks)
Dim hwnd As LongPtr
hwnd = swApp.FrameWindow().GetHWnd()
If hwnd <> 0 Then
‘ 最小化されている場合は復元
If IsIconic(hwnd) <> 0 Then
Call ShowWindow(hwnd, SW_RESTORE)
End If
‘ 前面へフォーカスを強制移動
Call SetForegroundWindow(hwnd)
End If
End Sub
この手法をマクロの初手、あるいは例外処理の直前に挟み込むことで、自動化バッチ処理中の「プロセス無応答トラブル」を根絶することが可能となる。
—
5. チーフアーキテクトからの提言:持続可能なマクロ資産へ
コードは「書いたら終わり」ではなく、生き物である。SolidWorksのバージョンアップサイクルの波に飲まれ、ある日突然動かなくなるレガシーマクロに怯える日々から脱却せよ。
1. 型を明示し、Variant型や遅延バインディング(`CreateObject`の多用)を排除する。
2. すべてのCOMオブジェクトは `Set x = Nothing` で例外時も含めて確実に解放する。
3. 廃止予定・非推奨のAPIを見つけ次第、最新のインターフェースへリファクタリングを敢行する。
この3点を徹底するだけで、あなたの管理するVBAマクロ資産の寿命は劇的に延び、設計現場の生産性は極限まで高まる。技術者としての誇りを持ち、今すぐレガシーコードの浄化に着手してほしい。
