【テクニカル・上級編】【数式・グローバル変数】EquationMgr.GetEquationCountとValue2プロパティを用いたパーツ内寸法の動的数式書き換えバッチ – SolidWorks VBA解析バイブル

スポンサーリンク

SolidWorks VBAを掌握する極限の知見

【数式・グローバル変数】EquationMgr.GetEquationCountとValue2プロパティを用いたパーツ内寸法の動的数式書き換えバッチ

設計変更の嵐、そして幾重にも複雑怪奇に絡み合ったコンフィギュレーションと数式の依存関係。
レガシーなパーツファイルを開き、手動でグローバル変数を書き換え、リビルドエラーの爆弾処理に追われる日々を送っていないだろうか。

シニアエンジニアや社内システム管理者であれば、一度は「外部システム(ERPやCSV)からのパラメータ入力に連動して、数式マネージャーの値を一括で、かつ安全にドライブしたい」という欲求に駆られるはずだ。
今回は、SolidWorks APIの根幹である `EquationMgr` を極限までチューニングし、数式の解析から安全な書き換え、そして一括リビルドに至るまでの全プロセスを解説する。

1. 架构の核心:`EquationMgr` のライフサイクルとメモリ管理の罠

SolidWorksの数式管理は、見た目のシンプルさとは裏腹に、背後で厳密な依存関係グラフ(Dependency Graph)を構築している。
VBAから `PartDoc.GetEquationMgr` を呼び出す際、以下の鉄則を忘れると、メモリリークやCOMオブジェクトの解放漏れによるSolidWorks本体のフリーズを引き起こす。

  • COM参照の局所化: `EquationMgr` インスタンスはキャッシュせず、必要なスコープでのみ取得・即座に解放する。
  • インデックスの変動リスク: 数式を削除・追加すると、インデックス番号が動的にシフトする。一括処理時は必ず「末尾からの逆順処理」または「名前ベースの特定」を原則とする。
  • 暗黙のリビルド抑止: ループ内で数式を書き換えるたびにリビルド走査が発生すると、パフォーマンスが劇的に低下する。`AutoRebuild` プロパティを制御下に置くべし。

2. 実装コード:動的数式書き換えエンジン

以下のコードは、指定したパーツファイル内のグローバル変数を外部データ(ここではハードコーディングされた辞書的配列を想定)に基づいて安全に書き換え、依存関係を破綻させずに一括リビルドをかける実用プロシージャである。

Option Explicit

‘ =================================================================================
‘ 専門家向け:パーツ内グローバル変数・数式一括置換バッチエンジン
‘ =================================================================================
Sub ExecuteEquationBatchDriver()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swEqMgr As SldWorks.EquationMgr

‘ 1. セーフティなアプリケーションインスタンスの取得
Set swApp = Application.SldWorks
If swApp is Nothing Then Exit Sub

Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなパーツドキュメントが存在しません。”, vbCritical
Exit Sub
End If

‘ パーツドキュメントかどうかの型チェック (swDocPART = 1)
If swModel.GetType <> swDocPART Then
MsgBox “このマクロはパーツファイルでのみ実行可能です。”, vbExclamation
Exit Sub
End If

‘ 2. EquationMgr の取得
Set swEqMgr = swModel.GetEquationMgr
If swEqMgr Is Nothing Then
MsgBox “数式マネージャーの取得に失敗しました。”, vbCritical
Exit Sub
End If

‘ 3. トランザクション的処理の開始(パフォーマンス最適化)
‘ ※SolidWorks APIでは直接的なBeginTransactionがないため、画面描画と自動リビルドを抑制
swApp.GetUserPreferenceToggle(swUserPreferenceToggle_e.swViewDisplayUpdate)

On Error GoTo ErrorHandler

Dim i As Long
Dim eqCount As Long
Dim eqString As String
Dim varName As String
Dim targetValue As Double

eqCount = swEqMgr.GetEquationCount
Debug.Print “— 既存数式スキャン開始 (総数: ” & eqCount & “) —”

‘ 4. 外部データ駆動型の値書き換えループ
‘ (実運用ではここでCSVやDB、Dictionaryオブジェクトから値を取得する)
targetValue = 150.5 ‘ 例としての新しい値

For i = 0 To eqCount – 1
eqString = swEqMgr.Equation(i)
Debug.Print “[” & i & “] ” & eqString

‘ 例:「”Overall_Length” = 100」のようなグローバル変数定義を想定
If InStr(eqString, “””Overall_Length”””) > 0 Then
‘ Value2プロパティを用いて数式の評価値を安全に書き換える
‘ 引数(インデックス, 新しい数式または値の文字列)
‘ 注意: 数式全体を再定義するか、Value2で評価値を直接叩くか要件で使い分ける

Dim newEquationStr As String
newEquationStr = “””Overall_Length”” = ” & CStr(targetValue)

Dim setResult As Long
setResult = swEqMgr.SetEquation(i, newEquationStr)

If setResult = 0 then
Debug.Print ” -> 成功: Overall_Length を ” & targetValue & ” に更新しました。”
Else
Debug.Print ” -> 警告: 該当数式の更新に失敗しました (エラーコード: ” & setResult & “)”
End If
End If
Next i

‘ 5. 整合性を担保するための一括強制リビルド
Dim rebuildSuccess As Boolean
rebuildSuccess = swModel.ForceRebuild3(False)

If rebuildSuccess Then
MsgBox “数式の書き換えおよびパーツの再構築が正常に完了しました。”, vbInformation
Else
MsgBox “再構築(Rebuild)フェーズで警告またはエラーが発生しました。フィーチャーツリーを確認してください。”, vbExclamation
End If

CleanUp:
‘ 6. 確実なオブジェクト解放(メモリリーク防止の絶対命題)
Set swEqMgr = Nothing
Set swModel = Nothing
Set swApp = Nothing
Exit Sub

ErrorHandler:
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical
Resume CleanUp
End Sub

3. チーフアーキテクトが教える現場の知見とトラブルシューティング

構文エラー(Syntax Error)のハンドリング

`SetEquation` メソッドは、入力された文字列がSolidWorksの数式パーサの文法に違反している場合(例:クォーテーションの不一致、存在しないディメンション名とのリンク)、非零のエラーコードを返す。
この戻り値を無視して処理を進めると、後続の `ForceRebuild3` でモデルが破損(あるいはゼロ除算エラー等でアボート)するため、必ず戻り値の評価を実装の義務としなければならない。

大規模アセンブリ・コンフィギュレーション環境への拡張

今回のコードは単体パーツを対象としているが、これを上位のアセンブリやマルチコンフィギュレーション環境へ展開する場合、`ConfigurationManager` を通じたコンフィギュレーションごとのアクティブ化制御(`ShowConfiguration2`)を挟む必要がある。
コンフィギュレーション固有の数式(This Configuration)と全コンフィギュレーション共通の数式(All Configurations)のスコープ違いを見誤ると、意図しない全社標準パーツの破壊を招くため細心の注意を払うこと。

メモリ最適化の極み

VBAのガベージコレクションは頼りにならない。特にCOMコンポーネントを大量に扱うCADマクロにおいては、プロシージャの脱出時に `Set object = Nothing` を明示的に記述し、COM参照カウンタを確実にデクリメントすることが、長時間のバッチ処理におけるメモリクラッシュを防ぐ唯一の防壁となる。

プロフェッショナルであれば、コードは常に美しく、かつ冗長なエラーハンドリングを備えているべきだ。
現場の自動化を極限まで押し上げるための武器として、この知見を役立ててほしい。

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