【SolidWorks VBA】FSOで制圧するバッチ処理基盤:数千のファイル群を「安全・確実」に回す極意
エンジニア諸君。SolidWorksのルーチンワークに追われ、深夜まで「名前を付けて保存」を繰り返していないか?
もし君が、ただ「動くコード」を書いて満足しているなら、今すぐその考えを捨てろ。SolidWorksのAPIは強力だが、メモリ管理とファイルロックの概念を無視したコードは、数千個のファイルを処理する過程で必ずメモリリークやプロセス暴走を引き起こす。
今日は、現場で真に使える「FileSystemObject (FSO) を核としたバッチ処理基盤」の設計思想を伝授する。これは単なるスクリプトではない。堅牢性を担保し、エラーを握りつぶさず、再開可能なアーキテクチャだ。
—
1. なぜ「力任せのループ」が地獄を見るのか
初心者が書くコードは、往々にしてこうだ。
- `Dir()`関数を使い、エラーハンドリングを怠る。
- 処理したドキュメントを`CloseDoc`せずに放置し、メモリを食いつぶす。
- 途中でクラッシュすると、どこまで進んだか分からなくなる。
プロの設計は違う。
FSOを用いてディレクトリ構造を再帰的にトラバース(探索)し、個別の処理を「サブプロシージャ」として完全に独立させる。これにより、単体テストが可能になり、保守性が劇的に向上する。
—
2. 実装:堅牢なバッチ処理フレームワーク
このコードは、指定フォルダ以下のすべての部品(.sldprt)を対象に、特定の処理を施すための「骨格」だ。
Option Explicit
‘ 必要なライブラリ:Microsoft Scripting Runtime (FSO)
‘ 事前にツール > 参照設定から追加しておくこと
Public Sub BatchProcessMain()
Dim fso As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)
Dim targetFolder As String
targetFolder = “C:\Projects\TargetModels” ‘ 対象フォルダ
‘ 再帰的にディレクトリを走査し、処理を実行する
ProcessFolder fso.GetFolder(targetFolder), fso
MsgBox “全処理完了。”, vbInformation
End Sub
Private Sub ProcessFolder(folder As Object, fso As Object)
Dim file As Object
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Set swApp = Application.SldWorks
‘ ファイル走査
For Each file In folder.Files
If LCase(fso.GetExtensionName(file.Path)) = “sldprt” Then
‘ 1. 開く(読み取り専用で開くのが鉄則)
Set swModel = swApp.OpenDoc6(file.Path, swDocPART, swOpenDocOptions_ReadOnly, “”, 0, 0)
If Not swModel Is Nothing Then
‘ 2. 実処理(別プロシージャに追い出すことで保守性を確保)
ExecuteTask swModel
‘ 3. 確実に閉じる(メモリリークを防ぐ唯一の手段)
swApp.CloseDoc swModel.GetTitle
End If
End If
Next
‘ サブフォルダも走査したい場合は再帰呼び出しを行う
‘ Dim subFolder As Object
‘ For Each subFolder In folder.SubFolders
‘ ProcessFolder subFolder, fso
‘ Next
End Sub
Private Sub ExecuteTask(swModel As SldWorks.ModelDoc2)
‘ ここに個別の業務ロジックを書く
‘ 例:プロパティの書き換え、エクスポートなど
Debug.Print “Processing: ” & swModel.GetPathName
End Sub
—
3. この設計の「魂」:なぜこの書き方なのか
① `swOpenDocOptions_ReadOnly` の強制
バッチ処理において、ファイルを書き込み許可で開くのは自殺行為だ。他者が開いている場合やネットワーク遅延により、プロセスがハングアップする。「読み取り専用」で開き、変更が必要な場合のみ `SaveAs` で別名保存する。 これが事故を防ぐ鉄則だ。
② `swApp.CloseDoc` の絶対的遵守
SolidWorksのAPIは、`OpenDoc`でメモリにロードしたオブジェクトを明示的に解放しないと、ガベージコレクションが即座に働かないことが多い。特に数千ファイル扱う場合、これを怠ればプロセスがメモリ不足で落ちるか、SolidWorksが「重い」という不満を抱えることになる。
③ 処理の分離(Separation of Concerns)
`ProcessFolder`(ファイル検索)と `ExecuteTask`(業務ロジック)を分けているのは、「テストのしやすさ」のためだ。万が一、特定のファイルでエラーが起きた場合、どの層でコケたかが一目瞭然となる。
—
4. プロの現場でのプラスアルファ
実務でこれを使うなら、以下の改善を検討せよ。
- ログ出力の実装: 成功したファイル、失敗したファイル(パスとエラーコード)をテキストファイルに書き出す処理を追加しろ。管理者に報告する際に、これが最強の証拠となる。
- エラーハンドリング: `On Error Resume Next` を多用する素人とは別れを告げよう。`If Not swModel Is Nothing Then` を徹底し、開けなかったファイルはログに吐いて次へスキップする。
- DB連携: 処理結果をSQLiteやCSVに蓄積すれば、進捗管理ダッシュボードも作れる。
最後に:エンジニアとしての矜持
自動化とは、単にコードを書くことではない。「誰が実行しても同じ結果が、安全かつ高速に得られる仕組み」を創ることだ。
このコードをベースに、君の現場の課題を解決してくれ。もしコードが巨大化しすぎたら、それは設計の見直しが必要なサインだ。だが、この基盤さえあれば、君はSolidWorksのルーチンワークから解放され、より創造的な設計業務に時間を割けるはずだ。
さあ、IDEを開け。コードを書く時間だ。
