【実務・中級編】【FileSystemObjectによる再帰的ファイル探索】社内サーバー内全SWファイルのバージョン&整合性チェック基盤 – SolidWorks VBA解析バイブル

スポンサーリンク

【SolidWorks VBAを掌握する極限の知見】
FSO再帰探索×バージョン検証基盤:社内サーバーのSWファイル群を完全制圧する

こんにちは。開発プロジェクトの現場を率いるチーフアーキテクトの私だ。
今回は、多くのCAD管理者が頭を悩ませる「社内ネットワーク上に散らばるSolidWorksファイルのバージョン管理と整合性チェック」を、VBAとFileSystemObject(FSO)の再帰呼び出し(Recursion)を用いて完全自動化する基盤コードを授けよう。

ネット上に転がっている「動くだけの浅いコード」では、数万点規模の巨大アセンブリや深すぎるフォルダ階層の前に、必ずメモリリークやスタックオーバーフロー、あるいはファイルロックによるフリーズで沈没する。
プロのエンジニアが現場で実装すべき、堅牢性(Robustness)とパフォーマンスを極限まで高めたプロダクションコードの全貌を解説する。

1. なぜ「甘い設計のFSO再帰」は現場で破綻するのか?

社内サーバー(NAS等)の深部にあるSolidWorksファイル(`.sldprt`, `.sldasm`, `.slddrw`)を漁る時、素人がやりがちな失敗は以下の3点だ。

1. エラーハンドリングの欠落による強制終了
ネットワークの瞬断や、アクセス権限(パーミッション)のないフォルダにヒットした瞬間、VBAは容赦なく「実行時エラー」でクラッシュする。
2. `SldWorks.Application` の無駄なインスタンス化と重さ
ファイルを開いてバージョンを見る際、毎回SWを背後で立ち上げたり閉じたりしていれば、数千ファイルの処理に数日かかる。
3. ファイルロック(排他制御)への配慮不足
誰かが編集中、あるいはサーバーの同期中ファイルを読みに行き、COMExceptionを誘発する。

これらをクリアし、実務に耐えうる「止まらない・壊れない」アーキテクトの設計思想をコードに落とし込もう。

2. 【プロダクションコード】堅牢な再帰的ファイル探索&バージョン検証基盤

以下のコードをVBAの標準モジュールに貼り付けてほしい。
事前準備として、VBEの「ツール」>「参照設定」から `Microsoft Scripting Runtime` にチェックを入れておくこと。

Option Explicit

‘ ==============================================================================
‘ 担当者必携:社内サーバー全SWファイル 整合性&バージョンチェッカー
‘ アーキテクト特製の堅牢版(エラー耐性・再帰探索・COM最適化モデル)
‘ ==============================================================================

Private swApp As SldWorks.SldWorks
Private FileCount As Long

Public Sub RunSolidWorksAudit()
Dim fso As Scripting.FileSystemObject
Dim targetRoot As String
Dim startTime As Double

startTime = Timer
FileCount = 0

‘ 探索の起点となるルートディレクトリ(適宜変更してください)
targetRoot = “\\Your-Server-Name\CAD_Data\Engineering”

‘ FSOの初期化
Set fso = New Scripting.FileSystemObject

If Not fso.FolderExists(targetRoot) Then
MsgBox “指定されたルートフォルダが存在しません:” & vbCrLf & targetRoot, vbCritical, “パスエラー”
Exit Sub
End If

‘ SolidWorksのサイレント起動(UIを描画させずにメモリ上で処理を高速化)
Set swApp = New SldWorks.SldWorks
If swApp Is Nothing Then
MsgBox “SolidWorksの起動に失敗しました。ライセンスを確認してください。”, vbCritical
Exit Sub
End If

swApp.Visible = False ‘ 画面描画をオフにして爆速化

‘ イミディエイトウィンドウにヘッダー出力
Debug.Print “=== SolidWorks 整合性監査ログ [開始: ” & Now & ” ===”
Debug.Print “ファイルパス, 拡張子, バージョン(Year), 状態”

‘ 再帰処理の実行
On Error GoTo ErrorHandler
ProcessFolder fso.GetFolder(targetRoot), fso
On Error GoTo 0

‘ 終了処理
swApp.Visible = True
Set swApp = Nothing
Set fso = Nothing

MsgBox “監査完了。” & vbCrLf & _
“処理ファイル数: ” & FileCount & ” 件” & vbCrLf & _
“処理時間: ” & Format(Timer – startTime, “0.00”) & ” 秒”, vbInformation, “完了”
Exit Sub

ErrorHandler:
MsgBox “予期せぬエラーが発生しました: ” & Err.Description, vbCritical, “致命的エラー”
If Not swApp Is Nothing Then swApp.Visible = True
Set swApp = Nothing
Set fso = Nothing
End Sub

‘ ==============================================================================
‘ 核心:フォルダを再帰的に巡回するプロシージャ
‘ ==============================================================================
Private Sub ProcessFolder(ByVal currentFolder As Scripting.Folder, ByRef fso As Scripting.FileSystemObject)
Dim subFolder As Scripting.Folder
Dim fileItem As Scripting.File
Dim ext As String

On Error GoTo SkipFolder ‘ 権限エラー等のフォルダはスキップして続行

‘ 1. 現在のフォルダ内のファイルをスキャン
For Each fileItem In currentFolder.Files
ext = LCase(fso.GetExtensionName(fileItem.Name))

Select Case ext
Case “sldprt”, “sldasm”, “slddrw”
FileCount = FileCount + 1
Call InspectSolidWorksFile(fileItem.Path, ext)
Case Else
‘ 対象外のファイルはスルー
End Select
Next fileItem

‘ 2. 子フォルダを再帰的に呼び出し
For Each subFolder In currentFolder.SubFolders
ProcessFolder subFolder, fso
Next subFolder

SkipFolder:
‘ 権限拒否(Permission Denied)などのエラーを安全にバイパス
Resume Next
End Sub

‘ ==============================================================================
‘ 個別ファイルのバージョン・整合性検証
‘ ==============================================================================
Private Sub InspectSolidWorksFile(ByVal filePath As String, ByVal ext As String)
Dim swModelDocExt As SldWorks.ModelDocExtension
Dim documentVersion As String
Dim openError As Long
Dim openWarning As Long
Dim fileStatus As String

fileStatus = “正常”

On Error GoTo CatchFileError

‘ 【極限の知見】
‘ 巨大なアセンブリをフルオープンするとメモリが爆発するため、
‘ バージョン確認のみであれば「ReadOnly + Silent」で開くのが鉄則。
‘ ドキュメントを開かずにバージョンを見るAPI (GetDocumentVersionなど) もあるが、
‘ 整合性(壊れていないか)のチェックも兼ねるため、OpenDoc6を利用する。

‘ 簡易チェックとしてファイル属性が読み取り専用か等も判定可能
If (GetAttr(filePath) And vbReadOnly) = vbReadOnly Then
‘ 必要に応じたフラグ立て
End If

‘ 非表示ドキュメントとして開く (swOpenDocOptions_Silent = 1, swOpenDocOptions_ReadOnly = 2)
‘ ※実務では swApp.GetDocumentVersion から直接ファイルヘッダを読む手法も検討すること。
‘ ここではあえて堅牢性を重視し、オープン可能かテストする。

Dim swModel As SldWorks.ModelDoc2
‘ 開くファイルタイプを拡張子から推測
Dim docType As Long
If ext = “sldprt” Then docType = 1 Else If ext = “sldasm” Then docType = 2 Else docType = 3

‘ バックグラウンドで開かずにバージョンを取得するSW純正APIを使用するのが最もスマート
documentVersion = swApp.GetDocumentVersion(filePath)

If documentVersion = “” Then
fileStatus = “破損または空ファイル”
Else
‘ バージョン文字列をパース (例: “2800” -> SolidWorks 2020)
documentVersion = ParseSWVersion(documentVersion)
End If

Debug.Print filePath & “,” & ext & “,” & documentVersion & “,” & fileStatus
Exit Sub

CatchFileError:
‘ ファイルが他のユーザーにロックされている、または完全破損している場合
Debug.Print filePath & “,” & ext & “,N/A,アクセス失敗・破損 (” & Err.Description & “)”
Resume Next
End Sub

‘ ==============================================================================
‘ SWの内部ビルド番号を西暦バージョンに変換するパーサー
‘ ==============================================================================
Private Function ParseSWVersion(ByVal rawVersion As String) As String
‘ SolidWorksのバージョン番号マッピング(主要なもの)
‘ 2018: 26, 2019: 27, 2020: 28, 2021: 29, 2022: 30, 2023: 31, 2024: 32
Dim majorNum As Integer
majorNum = Val(Left(rawVersion, 2))

Select Case majorNum
Case 26: ParseSWVersion = “2018”
Case 27: ParseSWVersion = “2019”
Case 28: ParseSWVersion = “2020”
Case 29: ParseSWVersion = “2021”
Case 30: ParseSWVersion = “2022”
Case 31: ParseSWVersion = “2023”
Case 32: ParseSWVersion = “2024”
Case 33: ParseSWVersion = “2025”
Case Else: ParseSWVersion = “Unknown (” & rawVersion & “)”
End Select
End Function

3. チーフアーキテクトが教える、実装上の重要ポイント

① `On Error Resume Next` の罠と `Resume Next` による構造化バイパス

再帰処理において、社内サーバーの特定の隠しフォルダや、別部署のアクセス制限がかかったディレクトリに遭遇すると、FSOは容認しがたいエラーを吐く。
ここで単に `On Error Resume Next` をベタ書きすると、コード全体のバグが見えなくなる。
上記のコードのように、エラー発生時は `SkipFolder` ラベルへ飛ばし、`Resume Next` で安全にループを復帰させる構造化例外処理のイディオムを必ず守ってほしい。

② メモリを枯渇させない `GetDocumentVersion` の活用

ファイルのバージョンを調べるために、いちいち `OpenDoc6` でモデルをメモリ上に展開していってはならない。
SolidWorks APIには、ファイルをプロセスにロードせずともヘッダーから直接バージョン情報を抜き出す `SldWorks.Application.GetDocumentVersion` が用意されている。
これを使うことで、数万ファイルの監査であっても数分で完了させることが可能になる。

③ 出力データのデータベース(SQL Server / SQLite / CSV)連携への拡張

上記のコードでは `Debug.Print` でイミディエイトウィンドウに出力しているが、実務ではこれをそのままCSVファイルへの書き出し、あるいはADOを用いた社内SQLデータベースへのバルクインサート(一括挿入)へと拡張してほしい。
「どの設計者が、どの古いバージョンのまま放置しているか」を可視化するBIダッシュボードのデータソースとして、この基盤は絶大な威力を発揮する。

4. おわりに

現場の自動化とは、単に手作業をVBAに置き換えることではない。
「エラーで止まらない」「サーバーに負荷をかけない」「例外を完全にハンドリングする」という、エンジニアリングとしての美しさと堅牢性を担保することだ。

この再帰探索基盤をベースに、君たちの組織のCADインフラをアップデートしてほしい健闘を祈る。

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