【SolidWorks VBAを掌握する極限の知見】コンフィギュレーション名の正規表現マッチング:VBScript.RegExpと連携したマルチ構成部品の柔軟なフィルタリング
こんにちは。チーフアーキテクトの私だ。
日々、何千、何万というアセンブリの迷宮に挑み、重厚長大化するSolidWorksのパフォーマンスと格闘しているエンジニアなら、一度は痛感しているはずだ。
「標準の `GetConfigurationNames` や `String` 型の単純なワイルドカード比較では、現場の複雑怪奇な型番ルールに対応しきれない」と。
「“ や `?` だけのLIKE演算子では、プレフィックスやサフィックスの組み合わせ、特定桁のオプションコードの除外といった高度な条件分岐を記述した瞬間に、コードがスパゲッティ化する」と。
今回は、VBAの標準機能の限界を軽々と突破し、外部の強力なエンジンである `VBScript.RegExp` をシームレスに統合することで、マルチ構成(コンフィギュレーション)を持つ部品・アセンブリを圧倒的にスマートかつ堅牢にフィルタリングする極限のテクニックを伝授しよう。
生半可なコードは現場のメモリリークやSolidWorks自体のフリーズを招く。プロフェッショナルが書くべき「プロダクションコードの作法」をここで体得してほしい。
—
1. なぜ「単なる文字列比較」では実務で破綻するのか?
実務における型番規則は、往々にしてカオスである。
例えば、以下のようなコンフィギュレーション名が混在するアセンブリを想像してほしい。
- `ASSY-2023-REV01-A_STD`
- `ASSY-2023-REV01-A_OPT-X`
- `ASSY-2023-REV02-B_STD`
- `ASSY-2024-PRO-EX_OPT-Y`
「REV01またはREV02かつ、末尾が `_STD` のものだけを処理し、オプション品は除外したい」という要件があった場合、VBAの `InStr` や `Like` 演算子でこれを書こうとするとどうなるか? 枝分かれする `If` 文の嵐になり、半年後には誰もメンテナンスできないレガシーコードが誕生する。
ここで投入すべきなのが 正規表現(Regular Expressions) だ。
`VBScript.RegExp` オブジェクトをVBAからラップし、SolidWorksのAPIモデルと完璧に同期させることで、複雑なパターンマッチングをたった1行の表現力に凝縮できる。
—
2. 設計上の要諦:オブジェクトのライフサイクルとエラーハンドリング
VBAで外部COMオブジェクト(今回は `VBScript.RegExp`)を扱う際、初心者が陥りがちな罠が 「ループ内でのインスタンス生成・破棄によるパフォーマンス低下」 と 「不正な正規表現パターンの入力によるランタイムエラー」 だ。
プロダクションコードとしての要件は以下の通り:
1. インスタンスの単一化(または適切なスコープ管理):ループのたびに `New RegExp` を呼ばず、初期化コストを最小化する。
2. 完全修飾または適切な参照設定:今回はあえて遅延バインディング(Late Binding)を採用し、参照設定のバージョン競合リスクを排除する。
3. APIオブジェクトの安全な解放:`ModelDoc2` や `Configuration` オブジェクトの取り扱いに伴うメモリ管理を徹底する。
—
3. 実装コード:プロダクションレベル・コンフィギュレーションフィルター
以下のコードは、アクティブなドキュメントから指定した正規表現パターンに一致するコンフィギュレーション名のみを抽出し、それぞれのコンフィギュレーションに切り替えて何らかのバッチ処理(ここでは例としてプロパティ確認やログ出力)を実行する完全なモジュールだ。
Option Explicit
‘ =========================================================================
‘ 模範的プロダクションコード:正規表現によるコンフィギュレーションフィルタリング
‘ =========================================================================
Sub RunConfigurationRegexFiltering()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
‘ 1. SolidWorks アプリケーションの取得
Set swApp = Application.SldWorks
If swApp Is Nothing Then
MsgBox “SolidWorksが起動していません。”, vbCritical
Exit Sub
End If
Set swModel = swApp.ActiveDoc
If swModel is Nothing Then
MsgBox “アクティブなドキュメントが存在しません。”, vbCritical
Exit Sub
End If
‘ 2. アセンブリまたは部品かどうかのバリデーション
Dim docType As Long
docType = swModel.GetType
If docType <> swDocPART And docType <> swDocASSEMBLY Then
MsgBox “部品(Part)またはアセンブリ(Assembly)ドキュメントを開いて実行してください。”, vbExclamation
Exit Sub
End If
‘ 3. 検索パターン(正規表現)の定義
‘ 例: “REV0[12]” を含み、かつ末尾が “_STD” で終わるパターン
Dim regexPattern As String
regexPattern = “^.REV0[12]._STD$”
‘ 4. 正規表現エンジンの初期化(遅延バインディングによる堅牢な設計)
Dim regEx As Object
On Error GoTo ErrorHandler
Set regEx = CreateObject(“VBScript.RegExp”)
With regEx
.Pattern = regexPattern
.IgnoreCase = True ‘ 大文字小文字を区別しない
.Global = True ‘ 文字列全体からマッチを探す
End With
‘ 5. コンフィギュレーション名の配列を取得
Dim vConfigNames As Variant
vConfigNames = swModel.GetConfigurationNames
If IsEmpty(vConfigNames) Then
MsgBox “コンフィギュレーションが存在しません。”, vbExclamation
GoTo CleanUp
End If
‘ 6. フィルタリングとバッチ処理の実行
Dim i As Long
Dim currentConfig As String
Dim matchCount As Long
matchCount = 0
‘ 現在のコンフィギュレーションを退避(処理後に復元するため)
currentConfig = swModel.ConfigurationManager.ActiveConfiguration.Name
‘ パフォーマンス最適化:画面描画の凍結
swModel.Extension.EnableUserUpdate = False
For i = LBound(vConfigNames) To UBound(vConfigNames)
Dim targetConfig As String
targetConfig = vConfigNames(i)
‘ 正規表現マッチングの実行
If regEx.Test(targetConfig) Then
matchCount = matchCount + 1
Debug.Print “【一致】処理対象コンフィギュレーション: ” & targetConfig
‘ コンフィギュレーションの切り替え
‘ ※大規模アセンブリではこの切り替えコストが重いため、本当に必要な処理のみをここに記述する
Dim boolstatus As Boolean
boolstatus = swModel.ShowConfiguration2(targetConfig)
If boolstatus Then
‘ — ── ここに各コンフィギュレーションに対する実務処理を記述 ── —
Call ExecuteBatchTask(swModel, targetConfig)
‘ ————————————————————-
Else
Debug.Print ” -> 警告: コンフィギュレーションの切り替えに失敗しました: ” & targetConfig
End If
Else
Debug.Print “【除外】スルー: ” & targetConfig
End If
Next i
‘ 処理完了後の復元とUI更新の有効化
swModel.ShowConfiguration2 currentConfig
swModel.Extension.EnableUserUpdate = True
MsgBox “処理が完了しました。” & vbCrLf & _
“総数: ” & (UBound(vConfigNames) – LBound(vConfigNames) + 1) & “件” & vbCrLf & _
“一致・処理件数: ” & matchCount & “件”, vbInformation, “完了”
CleanUp:
‘ オブジェクトの明示的な解放
Set regEx = Nothing
Set swModel = Nothing
Set swApp = Nothing
Exit Sub
ErrorHandler:
‘ 異常系ハンドリング:正規表現の構文エラーなどを捕捉
If Not swModel Is Nothing Then
swModel.Extension.EnableUserUpdate = True
swModel.ShowConfiguration2 currentConfig
End If
MsgBox “予期せぬエラーが発生しました。” & vbCrLf & _
“Error: ” & Err.Description, vbCritical, “システムエラー”
Resume CleanUp
End Sub
‘ =========================================================================
‘ サンプル:各コンフィギュレーションに対して実行する実務タスク
‘ =========================================================================
Private Sub ExecuteBatchTask(ByVal swModel As SldWorks.ModelDoc2, ByVal configName As String)
‘ 例:カスタムプロパティの書き込みや、質量計算の強制など
‘ 実際にはここにロジックを組み込む
‘ ドキュメントの強制再構築(必要に応じて)
‘ swModel.ForceRebuild3 False
Debug.Print ” -> タスク実行中: ” & configName
End Sub
—
4. コードのアーキテクチャ解説:プロが押さえるべきポイント
1. `swModel.Extension.EnableUserUpdate = False` の重要性
マルチコンフィギュレーションをループで切り替える際、裏でSolidWorksがグラフィックス領域を再描画していると、処理時間が何倍にも膨れ上がる。描画を凍結(Freeze)し、処理が終わってから元のコンフィギュレーションに戻して描画を再有効化する手法は、大規模アセンブリを扱うマクロの鉄則である。
2. 元のコンフィギュレーションへの復元
マクロが途中で中断した際や完了時に、ユーザーが作業していたコンフィギュレーション状態を復元する配慮がないツールは、現場から「使い物にならない」と烙印を押される。エラーハンドラー内も含めた厳密なステート管理を実装している。
3. `VBScript.RegExp` のメタキャラクターの活用
今回の例 (`^.REV0[12]._STD$`) では、アンカー (`^`, `$`) を用いることで部分一致の誤爆を防ぎ、厳密に型番構造を規定している。この表現力を手に入れたことで、仕様変更に伴うマクロの改修コストは劇的に低下する。
—
結びにかえて
自動化エンジニアの価値は、「動くコードを書くこと」ではなく、「現場の混沌とした仕様変更やイレギュラーに耐えうる、保守性の高い堅牢なシステムを構築すること」にある。
今回紹介した `VBScript.RegExp` との連携テクニックは、コンフィギュレーションのフィルタリングだけでなく、ファイル名のバッチリネーム、図面番号の自動採番検証、カスタムプロパティの一括パースなど、あらゆる文字列処理の基盤として応用できる。
あなたの手元にあるその非効率なマクロを、今すぐこのアーキテクチャでアップグレードしてほしい。現場のエンジニアリングスピードは、君のコードのクオリティと共にある。
