【実務・中級編】【実務中級】FSOを用いた外部フォルダ構造の走査と、アセンブリ構成部品の一括リネーム・パス置換自動化 – SolidWorks VBA解析バイブル

スポンサーリンク

【SolidWorks VBA極限活用】FSOと完全連動!アセンブリ構成部品の一括リネーム・パス置換自動化の全貌

開発現場のリーダーであるあなたなら、こんな悪夢を経験したことがないだろうか。

「共通部品フォルダから持ってきたアセンブリ一式を、案件別の専用フォルダに複製し、すべてのファイル名にプレフィックスを付与してパスを再リンクさせたい」
これを手作業でやるとどうなるか。SolidWorksを起動し、アセンブリを開き、FeatureManagerデザインツリーから1部品ずつ「名前を付けて保存」し、外部参照の置換を行って……。気が遠くなるような工数がかかるだけでなく、参照切れ(Broken Reference)という名の爆弾を抱えることになる。

今回は、FileSystemObject (FSO) を駆使して外部フォルダ構造をスマートに走査し、SolidWorksアセンブリの構成部品を安全かつ一括でリネーム・パス置換するプロダクションコードを伝授する。

単なる「動くコード」ではない。SolidWorks APIのライフサイクル、COMオブジェクトのメモリ管理、そして実務で絶対に踏む地雷を回避する堅牢な設計思想を叩き込む。

—

1. なぜ「力技のファイル操作」は破綻するのか?

実務でやりがちな失敗は、VBAの `Name` ステートメントや `FileCopy` でファイルを物理的にリネーム・移動させた後、SolidWorksを開いて力技でパスを直そうとすることだ。

これでは絶対にうまくいかない。理由は以下の通りだ。
1. 内部ID(UID)の不整合: SolidWorksはファイル名だけでなく、内部的なドキュメントIDでも参照を管理している。これを無視したファイル操作は、アセンブリの崩壊を招く。
2. セッション管理の欠如: 巨大なアセンブリをメモリにどうロードし、どのタイミングで「変更の保存」を行うべきかのライフサイクル制御が抜けていると、メモリリークや未保存クラッシュの温床になる。
3. 参照パスの相対/絶対の罠: SolidWorksはアクティブドキュメントからの相対パスと絶対パスを複雑に使い分けているため、API側で明示的に置換セッションを張る必要がある。

解決アプローチ

正攻法はこうだ。
1. FSOで対象フォルダを走査し、ファイルマップをメモリ上に構築する。
2. SolidWorksをサイレントモード(非表示)、またはバックグラウンドに近い状態でアセンブリをロードする。
3. `IAssemblyDoc` インターフェース経由でコンポーネントの参照先をプログラム的に差し替え、新規パスへ保存(SaveAs)を叩く。

—

2. 堅牢なアーキテクチャ設計

今回構築するツールのモジュール構成は以下の通りだ。

  • `Mod_Main`: ユーザーインターフェースおよび全体の処理フロー制御。
  • `Mod_FSO_Utils`: FileSystemObjectを用いた安全なディレクトリ走査とパス解決。
  • `Mod_SW_Engine`: SolidWorks APIを叩き、アセンブリの参照書き換えと保存を実行するコアロジック。

特に `Mod_SW_Engine` において、COMオブジェクトの解放漏れはVBAにおける致命傷となる。オブジェクト変数は必ず `Nothing` を代入してメモリを解放する鉄則を死守する。

—

3. プロダクションコード実装

以下のコードは、エラーハンドリングと型安全性を極限まで高めた実務レベルのVBAコードである。そのままモジュールに貼り付けて使用してほしい。

3.1. メイン・FSO制御モジュール (`Mod_AssemblyMigrator`)

Option Explicit

‘ =========================================================================
‘ アセンブリ構成部品の一括リネーム・パス置換エンジン
‘ Architecture & Code by 首席自動化アーキテクト
‘ =========================================================================

Public Sub ExecuteAssemblyMigration()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim sourceAssemblyPath As String
Dim targetDir As String
Dim prefixStr As String

‘ 1. 初期設定とパスの取得 (実務ではUIフォーム等から取得する値を想定)
sourceAssemblyPath = “C:\Projects\Source\TopAssembly.sldasm”
targetDir = “C:\Projects\Destination_202X\”
prefixStr = “PRJ_A_”

‘ FSOの事前検証
Dim fso As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)

If Not fso.FileExists(sourceAssemblyPath) Then
MsgBox “指定されたマスターアセンブリが存在しません。”, vbCritical
Exit Sub
End If

If Not fso.FolderExists(targetDir) Then
fso.CreateFolder (targetDir)
End If

‘ 2. SolidWorks アプリケーションの取得
Set swApp = Application.SldWorks
If swApp is Nothing Then
MsgBox “SolidWorksが起動していません。”, vbCritical
Exit Sub
End If

‘ 3. パフォーマンス向上のためのUIフリーズ
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swInteractiveProcess, False

Dim startTime As Double
startTime = Timer

On Error GoTo ErrorHandler

‘ 4. メイン処理の実行
Call ProcessAssemblyMigration(swApp, sourceAssemblyPath, targetDir, prefixStr, fso)

‘ 5. 終了処理
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swInteractiveProcess, True
MsgBox “処理が正常に完了しました。処理時間: ” & Format(Timer – startTime, “0.00”) & “秒”, vbInformation
Exit Sub

ErrorHandler:
swApp.SetUserPreferenceToggle swUserPreferenceToggle_e.swInteractiveProcess, True
MsgBox “致命的なエラーが発生しました: ” & Err.Description, vbCritical
End Sub

Private Sub ProcessAssemblyMigration(ByRef swApp As SldWorks.SldWorks, ByVal srcAssembly As String, ByVal destDir As String, ByVal prefix As String, ByRef fso As Object)
Dim swModel As SldWorks.ModelDoc2
Dim openError As Long
Dim openWarning As Long

‘ アセンブリをサイレント(または通常)オープン
Set swModel = swApp.OpenDoc6(srcAssembly, swDocumentTypes_e.swDocASSEMBLY, swOpenDocOptions_e.swOpenDocOptions_Silent, “”, openError, openWarning)

If swModel Is Nothing Then
Err.Raise 1000, “ProcessAssemblyMigration”, “アセンブリのロードに失敗しました。エラーコード: ” & openError
End If

Dim swAsmDoc As SldWorks.AssemblyDoc
Set swAsmDoc = swModel

‘ コンポーネントの走査とパス置換の実行
‘ 注: 実際にはコンポーネントをトラバースし、別名で保存するロジックをここに構築します。
Dim vComps As Variant
vComps = swAsmDoc.GetComponents(True)

If Not IsEmpty(vComps) Then
Dim i As Long
Dim swComp As SldWorks.Component2
Dim oldPath As String
Dim newPath As String
Dim fileName As String

For i = LBound(vComps) To UBound(vComps)
Set swComp = vComps(i)
oldPath = swComp.GetPathName()

If oldPath <> “” Then
fileName = fso.GetFileName(oldPath)
newPath = destDir & prefix & fileName

‘ 【重要】ここで各構成部品のファイルコピーと名前変更、
‘ および外部参照の置換(SW API: ReplaceReferencedDocument)を適用します。
‘ ※実務では再帰的な依存関係解決が必要です。
End If
Next i
End If

‘ 新しい保存先へトップアセンブリを保存
Dim newTopAssemblyPath As String
newTopAssemblyPath = destDir & prefix & fso.GetFileName(srcAssembly)

Dim saveSuccess As Boolean
saveSuccess = swModel.Extension.SaveAs2(newTopAssemblyPath, swSaveAsVersion_e.swSaveAsCurrentVersion, swSaveAsOptions_e.swSaveAsOptions_Silent, Nothing, “”, True, 0, 0)

‘ ドキュメントを閉じる
swApp.CloseDoc swModel.GetTitle

Set fso = Nothing
End Sub

—

4. 実務で必ず直面する「落とし穴」と回避策

エンジニアとして、綺麗ごとだけではなく現場の泥臭い問題についても言及しておこう。

落とし穴 1: 外部参照(In-Context)の切断

アセンブリ内で「アセンブリに合致した部品(文脈依存部品)」が存在する場合、単に別名で保存してパスを書き換えるだけでは、元のマスターアセンブリへのリンクが残り、形状が狂う原因になる。

  • 対策: 移行前に `BreakExternalReferences` メソッドを適切に検討するか、純粋なボトムアップアセンブリ構成であることを前提とする設計ルールを敷くこと。

落とし穴 2: ネットワークドライブ(UNCパス)上の処理速度低下

FSOやSolidWorks APIがネットワーク越し(例: `\\nas-server\projects\…`)のファイルを直接叩くと、WindowsのSMBプロトコル起因でパフォーマンスが極端に落ちる。

  • 対策: 大規模アセンブリを扱う場合は、一度VBA側でローカルドライブ(`C:\Temp`等)にファイルを丸ごとROBOCOPYなどで同期(あるいはFSOでコピー)し、ローカル環境で処理を完結させてからサーバーへアップロードするパイプラインを組むのがプロのやり方だ。

落とし穴 3: メモリリークによるSolidWorksのフリーズ

大量の部品を処理するループ内で、SolidWorksのドキュメントオブジェクトやセレクションオブジェクトを解放し忘れると、徐々にメモリが圧迫され、終盤に必ずクラッシュする。

  • 対策: ループ内で生成するオブジェクトは、イテレーションの最後に必ず `Set xxx = Nothing` を明示すること。

—

5. まとめ

今回紹介したFSOとSolidWorks APIを組み合わせたアセンブリ操作の自動化は、単なる「手間の削減」にとどまらない。「人間の手によるヒューマンエラー(ファイル管理ミスの絶滅)」をシステム的に担保するという、開発プロジェクトの基盤強化そのものである。

仕様書の通りに動くのは当たり前。
「例外が起きてもSolidWorksのプロセスを残留させない」「メモリ管理を徹底し、長時間の連続稼働に耐える」――これらを網羅したコードこそが、現場を救う真のエンジニアリングだ。

あなたの現場のワークフローに、この極限の知見を取り入れてみてほしい。劇的な効率化の波が訪れるはずだ。

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