巨大な負債を資産に変える:SolidWorks再帰マイグレーションの極意
SolidWorksのバージョンアップは、設計現場において常に「地雷原」を歩くような作業だ。数千、数万のファイルを抱える社内サーバで、手動のマイグレーションなど正気の沙汰ではない。
私はこれまで、数多のレガシー環境を救済してきた。そこで共通して見られるのは、不適切な再帰処理によるスタックオーバーフローと、メモリリークによるSolidWorksの「突然死」だ。今回は、FileSystemObject(FSO)を使い倒し、堅牢かつ高速に全ファイルを網羅・更新するアーキテクチャを伝授する。
—
1. なぜ「再帰」が地獄への入り口となるのか
多くのエンジニアが陥る罠は、再帰関数の中で安易に`Set swApp = Application.SldWorks`を呼び出すことだ。SolidWorksのCOMオブジェクトは重量級であり、ループのたびにインスタンスを生成・破棄しようとすれば、プロセスのメモリ空間は瞬く間に断片化する。
極限の知見:
- インスタンスはシングルトンで保持せよ: `SldWorks`オブジェクトは、再帰処理の外で一度だけ接続し、使い回す。
- ドキュメントの完全解放: `swApp.CloseDoc`を呼ぶだけでは不十分だ。`Set swDoc = Nothing`を明示し、ガベージコレクションを促すための`DoEvents`を適切な間隔で挿入しなければならない。
—
2. 実装の要:再帰的探索とマイグレーションのエンジン
以下は、社内サーバの巨大なディレクトリツリーを走査し、最新バージョンへマイグレーションするための核となるコードだ。
Option Explicit
‘ 伝説的な安定性を担保するための定数
Private Const SW_TIMEOUT As Long = 1000
‘ グローバルなSWインスタンス(メモリ最適化のため保持)
Private swApp As SldWorks.SldWorks
Private fso As Object
Public Sub RunMigration()
Dim rootPath As String
rootPath = “Z:\EngineeringData\Projects” ‘ 対象ルート
Set swApp = CreateObject(“SldWorks.Application”)
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ プロセスをバックグラウンドで走らせるための設定
swApp.Visible = False
TraverseFolder fso.GetFolder(rootPath)
‘ 終了処理
swApp.ExitApp
Set swApp = Nothing
Set fso = Nothing
End Sub
Private Sub TraverseFolder(fldr As Object)
Dim subFldr As Object
Dim file As Object
Dim swDoc As SldWorks.ModelDoc2
‘ サブフォルダの再帰
For Each subFldr In fldr.SubFolders
TraverseFolder subFldr
Next
‘ ファイルの処理
For Each file In fldr.Files
If IsSWFile(file.Name) Then
MigrateFile file.Path
End If
Next
End Sub
Private Sub MigrateFile(filePath As String)
Dim swErrors As Long, swWarnings As Long
‘ 読み取り専用で開き、強制的に保存してマイグレーション
Set swDoc = swApp.OpenDoc6(filePath, swDocType_e.swDocASSEMBLY, swOpenDocOptions_Silent, “”, swErrors, swWarnings)
If Not swDoc Is Nothing Then
‘ バージョン更新のためのSaveAs(上書き)
swDoc.SaveAs3 filePath, 0, 0
swApp.CloseDoc swDoc.GetTitle
‘ オブジェクトの明示的解放
Set swDoc = Nothing
DoEvents ‘ メモリ解放の猶予を与える
End If
End Sub
Private Function IsSWFile(fileName As String) As Boolean
Dim ext As String
ext = LCase(fso.GetExtensionName(fileName))
IsSWFile = (ext = “sldprt” Or ext = “sldasm” Or ext = “slddrw”)
End Function
—
3. チーフアーキテクトからの「極限の忠告」
このコードを実戦投入する際、以下の3点だけは死守してほしい。
1. 書き込み権限の管理:
社内サーバのファイルには、設計者が編集中で「ロック」されているものが混ざる。`OpenDoc6`の戻り値とエラーコード(`swErrors`)を詳細に解析し、ロックされているファイルは即座にログへ書き出し、スキップするロジックを組むこと。これを怠ると、マイグレーション中に全システムが停止する。
2. Windows APIによる監視:
数千ファイルに及ぶ場合、SolidWorksが「応答なし」になることは珍しくない。`FindWindow`や`PostMessage`といったWindows APIを併用し、監視プロセスからハングアップしたSolidWorksプロセスを強制終了・再起動する「ウォッチドッグ」を別スレッド(あるいは別VBAプロセス)で実装するのが、真のプロの流儀だ。
3. ジャーナルログの活用:
マイグレーションの進捗は、必ず外部のテキストファイル(またはSQLite)に出力せよ。どこで失敗し、どのファイルで止まったのか。このログこそが、翌朝の君の精神的な安定を保証する唯一の材料となる。
結びに代えて
自動化とは、単にコードを書くことではない。「失敗した時のリカバリ」までを設計に組み込むことだ。このツールが、君の工数を劇的に削減し、本来の設計業務へと時間をシフトさせる助けになることを確信している。
さあ、レガシーなサーバの埃を払い、一気に最新環境へ引き上げよう。幸運を祈る。
