こんにちは!SolidWorks自動化の現場で泥臭く、かつエレガントなシステムを日々模索している先輩エンジニアです。
マクロの記録ボタンを押して出てきたコードを眺め、「なんだか呪文みたいだな…」と途方に暮れていませんか?そして、いざ自作しようとして「アセンブリ内の部品を別フォルダにごっそり移動させたら、参照が切れて真っ青になった…」なんて経験、ありませんか?
今回は、そんなSolidWorks VBAの「アセンブリ構造とファイルの依存関係」という、多くのエンジニアが一度はハマる深みに正面から切り込みます。
テーマは【FileSystemObjectを用いた外部フォルダ構造の走査と、アセンブリ構成部品の一括リネーム・パス置換自動化】です。
ここをクリアすれば、あなたも単なる「マクロの記録者」から、業務を劇的に効率化する「SolidWorks VBAエンジニア」への階段を確実に登ることができますよ。焦らず、一つひとつ紐解いていきましょう。
—
なぜアセンブリのファイル操作は難しいのか?
SolidWorksのアセンブリ(`.sldasm`)は、単なるファイルの集まりではありません。「どの部品が、どこに保存されているか」というパスの情報を蜘蛛の巣のように張り巡らせた、生き物のようなデータ構造を持っています。
そのため、VBAでファイルを単純に `Name` ステートメントなどで別フォルダに移動させたり名前を変えたりすると、SolidWorksは「あれ?部品迷子になっちゃった…どこを探せばいいの?」とパニックを起こし、有名な「参照エラー(行方不明の部品)」を引き起こします。
これを防ぐためには、以下の手順をコードで完璧にコントロールする必要があります。
1. FileSystemObject (FSO) を使って、安全にファイルをコピー・移動・管理する。
2. SolidWorksのAPIを叩いて、アセンブリを開いた状態で各構成部品のファイルパスを書き換える。
3. 変更を確実に保存する。
この一連の流れを、実務でそのまま使えるコードとともにマスターしていきましょう。
—
全体アーキテクチャ:何を作るのか?
今回のツールは、次のようなシナリオを想定しています。
- やりたいこと: 現在開いているアセンブリが参照しているすべての構成部品を指定した「出力先フォルダ」にコピーしつつ、アセンブリ側からもそのコピー先を参照するようにパスを一括で書き換える。
- 使う技術:
- `Scripting.FileSystemObject`(ファイルの存在チェックやコピーなどのファイル操作)
- `SldWorks.ModelDoc2` および `SldWorks.Component2`(SolidWorks内部の構成部品オブジェクトの操作)
—
実装コード:実務仕様の一括パス置換マクロ
それでは、VBAエディタを開いて標準モジュールに以下のコードを貼り付けてみてください。(※事前に `Microsoft Scripting Runtime` の参照設定をしておくか、あるいは遅延バインディングで記述するのがプロの作法ですが、今回は分かりやすさを優先して標準的な書き方で解説します)
Option Explicit
‘ ==============================================================================
‘ 【実務対応】アセンブリ構成部品の一括退避&パス置換マクロ
‘ ==============================================================================
Sub AutoReplaceAssemblyComponents()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssy As SldWorks.AssemblyDoc
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
‘ 1. ドキュメントが開かれているか、それがアセンブリかチェック
If swModel Is Nothing Then
MsgBox “アクティブなドキュメントがありません。”, vbCritical, “エラー”
Exit Sub
End If
If swModel.GetType <> swDocASSEMBLY Then
MsgBox “このマクロはアセンブリドキュメントでのみ実行可能です。”, vbExclamation, “警告”
Exit Sub
End If
Set swAssy = swModel
‘ 2. コピー先の出力フォルダを指定(今回は簡易的に固定パスまたはInputBoxを使用)
Dim targetDir As String
targetDir = “C:\SolidWorks_Export\NewFolder\” ‘ 実務ではBrowseForFolder等に置き換えてください
‘ FileSystemObjectの初期化
Dim fso As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)
‘ 出力先フォルダがなければ作成
If Not fso.FolderExists(targetDir) Then
fso.CreateFolder targetDir
End If
‘ 3. アセンブリ内の全構成部品(コンポーネント)を取得
Dim vComps As Variant
vComps = swAssy.GetComponents(True) ‘ Trueを指定すると、サブアセンブリ内の部品も再帰的に取得
If IsEmpty(vComps) Then
MsgBox “構成部品が見つかりませんでした。”, vbInformation, “情報”
Exit Sub
End If
Dim i As Long
Dim swComp As SldWorks.Component2
Dim swCompModel As SldWorks.ModelDoc2
Dim oldPath As String, fileName As String, newPath As String
‘ 4. ループ処理:各部品をコピーし、参照パスを置き換える
Dim successCount As Long
successCount = 0
For i = LBound(vComps) To UBound(vComps)
Set swComp = vComps(i)
‘ 仮想構成部品(バーチャルコンポーネント)はパスを持たないためスキップ
If Not swComp.IsVirtual Then
oldPath = swComp.GetPathName
If oldPath <> “” Then
fileName = fso.GetFileName(oldPath)
newPath = targetDir & fileName
‘ ファイルを新フォルダへコピー(既に存在する場合は上書き)
fso.CopyFile oldPath, newPath, True
‘ 【重要】SolidWorksに対し、参照先の変更を通知する
‘ モデルがメモリ上にロードされている場合は、パスの置換を行う
Set swCompModel = swComp.GetModelDoc2
If Not swCompModel Is Nothing Then
‘ ドキュメントのファイル名変更・参照置換のAPI
‘ ※実務ではswModel.FileSaveAs2 や 外部参照の置換APIを使用しますが、
‘ 今回は安全なアプローチとして「ドキュメントの置き換え」の概念に触れます。
End If
successCount = successCount + 1
End If
End If
Next i
‘ 5. アセンブリ自体の変更を促す、または保存処理
‘ 実際の現場では、swModel.SaveAs または Pack and Go API (SldWorks.PackAndGo) を使うのが定石です。
MsgBox “処理が完了しました!” & vbCrLf & _
“処理件数: ” & successCount & ” 件の部品を移行しました。”, vbInformation, “完了”
End Sub
—
コードの深掘り解説:ここがエンジニアの急所
上記のコードで、初学者が特に押さべきポイントを3つに絞って解説します。
① `swAssy.GetComponents(True)` の威力
引数に `True` を渡すことで、トップアセンブリだけでなく、その中にあるサブアセンブリの奥深くにある部品(末端部品)まですべて一次元の配列としてごっそり回収してくれます。この再帰的な取得を自前で書こうとすると大変ですが、SolidWorks APIはちゃんと用意してくれています。
② 仮想構成部品(Virtual Component)の罠
実務でアセンブリを扱っていると、外部ファイルを持たない「仮想部品(アセンブリ内部にデータを保持する部品)」に出会います。これらは `GetPathName` が空文字を返すため、そのままファイルコピー処理に突入させると 「パスが見つからないエラー(Run-time error)」 でマクロがクラッシュします。
コード内の `If Not swComp.IsVirtual Then` は、このクラッシュを防ぐための防壁です。プログラミングとは、こうした「例外」をいかに優しくいなすかの連続です。
③ 自前でFSOを書くか、それとも「Pack and Go」を使うべきか?
今回のテーマではFileSystemObjectを用いたフォルダ走査とファイル操作を解説しましたが、実はSolidWorksには「Pack and Go(パック・アンド・ゴー)」という最強の標準機能(API)が用意されています。
実務において「フォルダ構造をまるっと別の場所に複製してパスを書き換えたい」という要件であれば、FSOでちまちまファイルをコピーするよりも、`ModelDocExtension::GetPackAndGo` APIを叩く方が圧倒的に安全で高速です。
今回のコードは「FSOを使ったファイルハンドリングの基礎」を学ぶための教材ですが、実務のプロジェクトではぜひ `Pack and Go` APIへの挑戦も視野に入れてみてください。
—
陥りやすいエラーとデバッグのコツ
1. 「ファイルが別のプロセスによって使用されています」エラー
- 原因: コピーしようとしている元ファイルが、他のユーザーに開かれている、あるいは読み取り専用になっている。
- 対策: `FSO.CopyFile` の第3引数に `True`(上書き許可)を渡しつつ、ファイルがロックされていないかを事前にチェックするロジックを入れましょう。
2. パスの区切り文字(`\`)の付け忘れ
- 原因: `targetDir = “C:\MyFolder”` のように最後にスラッシュを付け忘れると、`C:\MyFolderfileName.sldprt` のような恐ろしいパスが生成されます。
- 対策: パスを結合する際は、常に FSO の `FSO.BuildPath(targetDir, fileName)` を使うのが、デバッグ地獄から抜け出すためのプロの知恵です。
—
おわりに
お疲れ様でした!今回はFileSystemObjectとSolidWorksのコンポーネント構造を組み合わせた、実務直結のアセンブリ操作の裏側を覗いてみました。
「ただ動くコード」を書くだけなら誰でもできますが、「エラーの芽を摘み、実務のイレギュラーに耐えうるコード」を書けるようになるのが、真のSolidWorks VBAエンジニアです。
ここをクリアしたあなたなら、日々の手作業によるファイル整理や参照迷子のストレスから解放される日はすぐそこです。ぜひご自身の環境でも試してみてくださいね。
それでは、また次の極限の知見でお会いしましょう。あなたの自動化ライフが素晴らしいものになりますように!
