SolidWorks VBAを掌握する極限の知見:コンフィギュレーション判定と堅牢な分岐処理の全貌
SolidWorks APIを用いた自動化において、モデルの「現在のアクティブなコンフィギュレーション名」を正確に取得し、それに応じた条件分岐を行うことは、実務的なマクロ開発の最も基本であり、かつ最も見落としがちな地雷原である。
多くの初心者は `ModelDoc2.GetCurrentConfiguration` の返り値を安易に変数へ格納し、そのまま文字列比較を行って満足する。しかし、大規模なアセンブリのコンテキスト下や、外部プロセス(COMオートメーション)からの遠隔操作、さらにはレガシーなSolidWorks 2010代の環境の保守まで視野に入れた時、その場しのぎのコードは確実にメモリリークや未定義動作を引き起こす。
本稿では、`SldWorks.ModelDoc2` から `GetCurrentConfiguration` を用いて現在のコンフィギュレーション名を取得し、安全かつ高速に分岐処理を実装するための極限の知見を、チーフアーキテクトの視点から授与する。
—
1. APIの解剖学:`GetCurrentConfiguration` の本質とライフサイクル
`ModelDoc2` インターフェースが提供する `GetCurrentConfiguration` メソッドは、一見するとただの文字列(String / BSTR)を返すだけのシンプルな関数に見える。
Dim swModel As SldWorks.ModelDoc2
Dim configName As String
configName = swModel.GetCurrentConfiguration()
しかし、COM(Component Object Model)のアーキテクチャおよびSolidWorksのドキュメントライフサイクルの観点から、この挙動には厳格なルールが存在する。
- BSTRのメモリ管理: 返される文字列はSolidWorksのプロセス空間内でアロケートされたBSTRである。VBAのランタイムはこの受け渡しを自動でラップ・解放してくれるが、多重ループ内やイベントハンドラ内で無駄に呼び出すと、微小なメモリフラグメンテーションの蓄積を招く。
- 図面(Drawing)ドキュメントにおける罠: パーツやアセンブリであれば「アクティブなコンフィギュレーション」は一意に定まるが、図面ドキュメント(DrawingDoc)の場合、アクティブなシート上のビューに紐づくモデルのコンフィギュレーションと、ドキュメント自体のコンフィギュレーションが乖離しているケースがある。対象が `PartDoc` なのか `AssemblyDoc` なのか、あるいは図面なのかを意識したコンテキストの把握が不可欠である。
—
2. 実装パターン:堅牢なコンフィギュレーション分岐プロシージャ
実務の現場でそのまま再利用できる、エラーハンドリングとオブジェクト管理を徹底したVBAコードを提示する。
Option Explicit
‘ =================================================================================
‘ 処理名: 活性コンフィギュレーションに基づく条件分岐処理
‘ 概要: 現在アクティブなコンフィギュレーション名を取得し、名称に応じた処理を安全に実行する
‘ =================================================================================
Sub ExecuteConfigurationDependentTask()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim currentConfig As String
‘ 1. SldWorks アプリケーションの取得 (Early Bindingを推奨)
Set swApp = Application.SldWorks
If swApp Is Nothing Then
MsgBox “SolidWorksが起動していません。”, vbCritical, “致命的エラー”
Exit Sub
End If
‘ 2. アクティブドキュメントの取得
Set swModel = swApp.ActiveDoc
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。”, vbExclamation, “警告”
Exit Sub
End If
‘ 3. ドキュメントタイプの検証 (パーツまたはアセンブリのみを対象とする)
Dim docType As Long
docType = swModel.GetType
If docType <> swDocPART And docType <> swDocASSEMBLY Then
MsgBox “このマクロはパーツまたはアセンブリでのみ実行可能です。”, vbExclamation, “対象外ドキュメント”
GoTo CleanUp
End If
‘ 4. 現在のコンフィギュレーション名の取得
‘ ※ 内部でモデルが再構築中の場合、予期せぬ挙動を防ぐためにエラー監視を行う
On Error GoTo ErrorHandler
currentConfig = swModel.GetCurrentConfiguration()
On Error GoTo 0
‘ 5. コンフィギュレーション名に基づく厳密な分岐処理
‘ 大文字・小文字の揺れを吸収するため、必要に応じて UCase() を使用する
Select Case Trim(currentConfig)
Case “Default”
Call ProcessDefaultConfiguration(swModel)
Case “Machined”, “加工済”
Call ProcessMachinedConfiguration(swModel)
Case Else
‘ 未知のコンフィギュレーションに対するフォールバック処理
MsgBox “未定義のコンフィギュレーション [” & currentConfig & “] が検知されました。”, vbInformation, “情報”
Call ProcessFallbackConfiguration(swModel)
End Select
CleanUp:
‘ 6. 参照の明示的な解放 (メモリ最適化の極意)
Set swModel = Nothing
Set swApp = Nothing
Exit Sub
ErrorHandler:
MsgBox “コンフィギュレーション名の取得中に予期せぬエラーが発生しました。” & vbCrLf & _
“エラー番号: ” & Err.Number & vbCrLf & _
“説明: ” & Err.Description, vbCritical, “API例外”
Resume CleanUp
End Sub
‘ — サブプロシージャ群(実際の業務ロジックのプレースホルダー) —
Private Sub ProcessDefaultConfiguration(ByRef model As SldWorks.ModelDoc2)
‘ デフォルトコンフィギュレーション時の処理
Debug.Print “Default 処理実行: ” & model.GetPathName
End Sub
Private Sub ProcessMachinedConfiguration(ByRef model As SldWorks.ModelDoc2)
‘ 加工コンフィギュレーション時の処理(例:属性の付与や特定のフィーチャ抑制制御など)
Debug.Print “Machined 処理実行: ” & model.GetPathName
End Sub
Private Sub ProcessFallbackConfiguration(ByRef model As SldWorks.ModelDoc2)
‘ フォールバック処理
Debug.Print “Fallback 処理実行”
End Sub
—
3. チーフアーキテクトが説く「現場の知見」とアンチパターン
長年のレガシーシステム保守や、他システム(PDM/PLM、ERP)との連携開発において、以下のアンチパターンを踏み抜く開発者が後を絶たない。
アンチパターン 1: 遅延バインディング(CreateObject / GetObject)の乱用
社内システム連携などで外部VBScriptや別プロセスからSolidWorksを操作する場合、`CreateObject(“SldWorks.Application”)` を多用しがちである。しかし、既に立ち上がっているセッションとのコンテキスト共有や、イベントハンドラの非同期処理において `GetCurrentConfiguration` の返り値が同期ズレを起こす現象が確認されている。SolidWorks VBA内での完結であっても、極力アリーバインディング(参照設定の活用)を維持し、型安全性を確保すべきである。
アンチパターン 2: 文字列比較におけるロケールと大文字小文字の罠
SolidWorksのコンフィギュレーション名はユーザーが任意に命名できるため、全角・半角の混在や、”Default” と “default” のようなケーススタディが発生する。
システム連携や自動バッチ処理の信頼性を担保するためには、分岐の直前で `UCase()` や `LCase()` による正規化、あるいは `StrComp(…, vbTextCompare)` を用いた比較ロジックを必ず挟むべきである。
アンチパターン 3: オブジェクト変数の解放漏れ
VBAはガベージコレクション言語ではなく、参照カウンタ方式のCOMラッパーである。プロシージャ内で取得した `SldWorks` や `ModelDoc2` などのオブジェクトは、処理の終端(`CleanUp` ラベル等)で確実に `Set 〇〇 = Nothing` を実行し、SolidWorksプロセスのメモリ空間へ確実な解放シグナルを送らなければならない。これを怠ると、マクロを数十回連続実行した際にSolidWorksがサイレントクラッシュ(メモリ違反)を引き起こす原因となる。
—
総括
`GetCurrentConfiguration` を用いたコンフィギュレーション判定は、SolidWorks APIの入り口に過ぎない。しかし、この極めてプリミティブな操作の中にこそ、COMプログラミングの鉄則、メモリ管理の哲学、そして予期せぬ例外に耐えうる堅牢なアーキテクチャのすべてが凝縮されている。
本稿で示したコードと思想をあなたの開発環境に導入し、一切の妥協を排した「プロフェッショナルな自動化基盤」を構築してほしい。
