SolidWorks VBAを掌握する極限の知見
【レガシー保守】SolidWorks 2012以前の古いAPIメソッドを最新のSolidWorks 2024対応コードへリファクタリングする手順
არは、過去の遺産であるVBAマクロが突然沈黙した瞬間の冷や汗を覚えているだろうか。
「SolidWorks 2012までは完璧に動いていた自動化スクリプトが、最新のSolidWorks 2024環境ではコンパイルエラーすら吐かずにフリーズする、あるいは不可解なクラッシュを起こす」――これは、製造業の現場でシニアエンジニアやシステム管理者が最も直面したくない、しかし避けて通れない悪夢である。
APIの変遷、COMの参照切れ、そして裏で肥大化し続けるメモリリーク。
本稿では、レガシーなSolidWorks VBAコードを最新の2024基準へと安全に、かつ完璧に蘇らせるための「極限の知見」を体系化する。妥協なきエンジニアリングの神髄をここに開示する。
—
1. なぜレガシーAPIは最新環境で破綻するのか?
SolidWorks APIは、過去20年以上にわたってCOM(Component Object Model)アーキテクチャをベースに進化を続けてきた。しかし、2012年から2024年の間に、以下のような根本的なパラダイムシフトが起きている。
- 型安全性の厳格化とVariant型の排除: 古いコードでは曖昧に処理されていた引数が、厳密なデータ型(特に`Long`から`LongLong`への移行、`Double`の精度保証)を要求されるようになった。
- 非推奨(Deprecated)メソッドの完全削除: 長年「警告付きで生かされていた」古いフィーチャ生成メソッドや選択メソッドが、2020年以降のバージョンでバイナリレベルから削除されている。
- 非同期処理とグラフィック更新の競合: `SldWorks.Application`のイベントループや画面再描画の仕様変更により、古い`Extension.SelectByID2`などの強引な選択処理が例外を引き起こす。
これらを放置したまま動かそうとすることは、すり減ったブレーキパッドでF1マシンを運転するようなものだ。
—
2. レガシーコードの「3大死活問題」と改修アプローチ
① `SelectByID2` の過剰依存と座標・名前依存の破綻
古いコードの9割は、画面上の名前や座標に依存した `SelectByID2` で埋め尽くされている。モデルの形状が変わったり、コンフィギュレーションで名前が揺らいだりした瞬間に破綻する。
【対策】: 生の文字列選択から、フィーチャや面を直接指すポインタ(オブジェクト参照)の直接取得へ移行する。
② メモリリークとCOMオブジェクトのゾンビ化
VBAのガベージコレクションは極めて脆弱である。特にループ内で `Feature` や `Body2` オブジェクトを取得し、明示的に解放(`Set obj = Nothing`)していないコードは、SolidWorksのプロセス内にメモリリークの残骸を残し、や日々のクラッシュを引き起こす。
③ 64bit環境(`LongLong` / `PtrSafe`)への対応漏れ
32bit時代の古いWindows API(`FindWindow`や`SendMessage`など)をVBA内で直接叩いている場合、64bitのSolidWorks 2024環境では一発でExcel/SolidWorksごと強制終了する。
—
3. 実践:2012年スタイルから2024年標準へのリファクタリング
ここでは、古いパーツファイル生成・フィーチャ追加のレガシーコードを、最新のAPI仕様と堅牢性(Robustness)を備えたコードへリファクタリングする実例を示す。
【レガシーコード(2012年以前の悪夢)】
‘ ── 【危険なレガシーコードの例】 ──
Sub CreateOldBox()
Dim swApp As SldWorks.SldWorks
Dim swPart As SldWorks.ModelDoc2
Set swApp = CreateObject(“SldWorks.Application”)
Set swPart = swApp.NewDocument(“C:\Templates\Part.prtdot”, 0, 0, 0)
‘ 古いメソッドによるスケッチと押し出し
swPart.SketchManager.InsertSketch True
swPart.CreateCircleByRadius 0, 0, 0, 0.05
‘ 強引な文字列選択(2024年では名前が変わると失敗する)
swPart.Extension.SelectByID2 “スケッチ1”, “SKETCH”, 0, 0, 0, False, 0, Nothing, 0
swPart.FeatureManager.FeatureExtrusion2 True, False, False, 0, 0, 0.1, 0.01, False, False, False, False, 1.745, 1.745, False, False, False, False, True, True, True
‘ オブジェクトの解放をサボっている典型例
End Sub
【モダンリファクタリングコード(SolidWorks 2024 完全対応版)】
以下のコードは、厳密な型定義、Windows APIの64bit安全宣言、確実なCOMオブジェクトの解放、そして最新の `FeatureManager` インターフェースを使用している。
Option Explicit
‘ ── 64bit/32bit完全対応のWindows API宣言 ──
If Vba7 Then
Private Declare PtrSafe Function SetForegroundWindow Lib “user32” (ByVal hwnd As LongPtr) As Long
Private Declare PtrSafe Function FindWindow Lib “user32” Alias “FindWindowA” (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Else
Private Declare Function SetForegroundWindow Lib “user32” (ByVal hwnd As Long) As Long
Private Declare Function FindWindow Lib “user32” Alias “FindWindowA” (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
End If
”’
”’
Sub CreateModernBox_2024()
‘ 1. アプリケーションの安全な取得(多重起動・ゾンビプロセス防止)
Dim swApp As SldWorks.SldWorks
On Error Resume Next
Set swApp = GetObject(, “SldWorks.Application”)
If swApp Is Nothing Then
Set swApp = New SldWorks.SldWorks
End If
On Error GoTo 0
If swApp Is Nothing Then
MsgBox “SolidWorksの起動に失敗しました。”, vbCritical
Exit Sub
End If
swApp.Visible = True
‘ 2. 新規ドキュントの安全な作成(ユーザー定義テンプレートの取得)
Dim swModel As SldWorks.ModelDoc2
Dim defaultPartTemplate As String
defaultPartTemplate = swApp.GetUserPreferenceStringValue(swUserPreferenceStringValue_e.swDefaultTemplatePart)
Set swModel = swApp.NewDocument(defaultPartTemplate, 0, 0, 0)
If swModel Is Nothing Then
MsgBox “パーツドキュメントの作成が拒否されました。”, vbCritical
Exit Sub
End If
‘ 3. 画面描画のロック(パフォーマンス劇的向上とちらつき防止)
swModel.Extension.EnableGraphicsUpdate = False
Dim boolstatus As Boolean
Dim swFeatMgr As SldWorks.FeatureManager
Set swFeatMgr = swModel.FeatureManager
‘ 4. 現代的なスケッチ&フィーチャ生成アプローチ
Dim swSketchMgr As SldWorks.SketchManager
Set swSketchMgr = swModel.SketchManager
swSketchMgr.InsertSketch True
‘ 2D中心円の作成(戻り値としてスケッチセグメントを取得可能)
Dim swSkCircle As SldWorks.SketchSegment
Set swSkCircle = swSketchMgr.CreateCircleByRadius(0#, 0#, 0#, 0.05)
swSketchMgr.InsertSketch True ‘ スケッチ終了
‘ 5. 最新のフィーチャ押し出し (FeatureExtrusion3 または FeatureManagerのメソッド群)
‘ ※古い FeatureExtrusion2 は引数が多すぎて破綻するため、モダンなボス押し出しAPIを使用
Dim swFeat As SldWorks.Feature
‘ 選択に依存せず、直前のスケッチをアクティブにした状態で安全に押し出す
boolstatus = swModel.Extension.SelectByID2(“”, “SKETCH”, 0, 0, 0, False, 0, Nothing, 0)
If boolstatus Then
‘ 2024推奨:フィーチャマネージャー経由の堅牢な押し出し定義
‘ 引数: 逆方向, 両方向, サーフェスまで等, 終端条件1, 終端条件2, 奥行き1, 奥行き2, ドラフト…
Set swFeat = swFeatMgr.FeatureExtrusion3( _
True, False, False, _
swEndCondTypes_e.swEndCondBlind, swEndCondTypes_e.swEndCondBlind, _
0.1, 0.0, _
False, False, False, False, _
0.017453292519943, 0.017453292519943, _
False, False, False, False, _
True, True, True, _
swStartConditions_e.swStartSketchPlane, 0#, False)
End If
‘ 6. 描画の復帰と強制リビルド
swModel.Extension.EnableGraphicsUpdate = True
swModel.ForceRebuild3 False
‘ ── 【極限の知見】メモリの明示的解放 (Memory Garbage Collection) ──
‘ VBAのCOM参照カウンタを確実にデクリメントし、メモリリークとCOM例外を防ぐ
Set swFeat = Nothing
Set swSkCircle = Nothing
Set swSketchMgr = Nothing
Set swFeatMgr = Nothing
Set swModel = Nothing
Set swApp = Nothing
MsgBox “SolidWorks 2024 環境でのジオメトリ生成が正常に完了しました。”, vbInformation
End Sub
—
4. チーフアーキテクトが教える「保守の鉄則」
レガシーマクロをただ動かすだけなら素人でもできる。真のプロフェッショナルなシステム管理者は、以下の運用ポリシーをコードに組み込む。
1. `On Error Resume Next` の乱用を直ちに禁止せよ
エラーを握り潰すコードは、バグの温床であり、SolidWorksプロセスのゾンビ化を招く。例外が発生した場合は、必ずトランザクション(処理のロールバックや画面復帰)を挟んで安全に離脱させろ。
2. `EnableGraphicsUpdate = False` による高速化とフリーズ防止
大規模なアセンブリやパーツの自動生成において、グラフィック描画を有効にしたままAPIを叩くのは罪悪である。処理の冒頭で描画を止め、最後に一括して再描画(または強制リビルド)を行え。
3. 変数のスコープを極限まで狭め、確実に `Nothing` を代入せよ
VBAのオブジェクト変数は、プロシージャが終了するまでメモリ上に残るケースがある。特に大規模なループ処理内では、オブジェクトの参照を使い回さず、都度生成・解放のサイクルを回すこと。これが何千回とループする自動化スクリプトを安定稼働させる唯一の絶対条件である。
過去の遺物を恐れるな。APIの仕様を掌握し、メモリの息吹までをコントロールできた者だけが、真の「SolidWorks自動化の支配者」となるのだ。
