こんにちは!SolidWorksの自動化の世界へようこそ。
チーフアーキテクトの私だ。
設計の現場で、こんな絶望的な状況に直面したことはないだろうか?
「大型アセンブリの設計変更で、主要なユニットの型式違いモデル(A社製からB社製へ、あるいは標準品から特注品へ)をごっそり入れ替えなきゃいけない……しかも、何十箇所もある合致関係(メイト)が崩れないように手作業でやるなんて、気が狂いそうだ!」
マクロの記録ボタンをポチッと押して「さあコードを見てみよう!」と意気込んだものの、出てきたのはゴミのようなコードの羅列。コンポーネントの置換なんて、記録機能では到底太刀打ちできない壁に見えるかもしれない。
だが、安心してほしい。
今日、君はこの記事を通じて、SolidWorks VBAの至宝である `IComponent2.ReplaceComponents` メソッドを完全に手懐けることになる。ここさえクリアすれば、君はもう「マクロの記録の奴隷」ではない。自分の手でCADを自在に操る、真の自動化エンジニアの仲間入りだ。
さあ、深呼吸をして、私と一緒にコードの海へ飛び込もう。
—
1. なぜ「手作業の置換」は地獄なのか?
アセンブリの中でコンポーネントを右クリックし、「部品の置換(Replace Components)」を選んだことがあるだろう面々なら、その苦痛を知っているはずだ。
一個や二個ならまだしも、階層構造に入り組んだ50個のパーツを手動で置き換え、その都度「あれ? ここ側の同軸合致がエラーを起こしたぞ……」と黄色や赤色のエラーマーク(警告・エラー)と格闘する羽目になる。
これをVBAで一瞬にして、しかも「既存の合致関係(メイト)を保持したまま」一括で完結させるのが、今回紹介するアセンブリ一括置換の極意だ。
—
2. APIの核心:`ReplaceComponents` の正体
SolidWorks APIにおいて、アセンブリ内の部品(コンポーネント)を司る神様が `IComponent2` インターフェースだ。
そして、そのコンポーネントを別のファイルにすげ替える強力な魔法が `ReplaceComponents` メソッドである。
まずは、そのシグネチャ(引数の仕様)を覗いてみよう。
Dim nErrors As Long
Dim bRet As Boolean
bRet = swComponent.ReplaceComponents( _
NewFileName, _
StorageName, _
KeepMateReferences, _
ReplaceOption _
)
一見すると難しそうに見えるが、恐れることはない。重要なパラメータは以下の2つだ:
1. `NewFileName`: 新しく置き換えるモデルファイルのフルパス(文字列)。
2. `ReplaceOption`: 置き換えのスコープ(選択したインスタンスだけか、すべてか)。今回は基本となる `swReplaceComponentOption_All`(すべて)を主に使うことになる。
ここでの最大のポイントは、「元のコンポーネントが持っていた合致関係の参照IDを、新しいモデルが引き継げる状態にあるか」という点だ。
形状があまりにもかけ離れていると合致が破綻するが、「型式違い(形状互換)」であれば、APIは驚くほど美しく、完璧にメイトを維持したまま入れ替えてくれる。
—
3. 【実践】型式違いモデルを一瞬で一括置換するVBAコード
百聞は一見に如かず。開発の現場でそのままコピペして、即座に実用できる洗練されたコードをプレゼントしよう。
このコードは、アクティブなアセンブリから特定のファイル名を検索し、指定した新しいファイルへとスマートに置き換えるものだ。
Option Explicit
‘ —————————————————————–
‘ 【SolidWorks VBA】アセンブリ内コンポーネント一括置換マクロ
‘
‘ 概要:
‘ アクティブなアセンブリ走査し、指定した旧モデルのファイル名を検索。
‘ 合致関係を維持したまま、新モデルへ一瞬で一括置換します。
‘ —————————————————————–
Sub Main()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swAssocModel As SldWorks.AssemblyDoc
‘ 1. アプリケーションとドキュメントの取得
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
‘ ドキュメントが開かれていない、またはアセンブリでない場合は即座にガード
If swModel Is Nothing Then
MsgBox “ドキュメントが開かれていません。”, vbCritical, “エラー”
Exit Sub
End If
If swModel.GetType <> swDocASSEMBLY Then
MsgBox “アクティブなドキュメントがアセンブリではありません。”, vbCritical, “エラー”
Exit Sub
End If
Set swAssocModel = swModel
‘ ==========================================
‘ 設定エリア(必要に応じて書き換えてください)
‘ ==========================================
Dim targetOldFileName As String
Dim newModelFullPath As String
‘ 置き換え前のファイル名(拡張子含む・パスは含めないのが安全)
targetOldFileName = “bolt_M8_standard.sldprt”
‘ 置き換え後のモデルの【完全修飾ファイルパス】
newModelFullPath = “C:\CAD_Data\Parts\bolt_M8_special_sus.sldprt”
‘ ==========================================
‘ 2. 処理前の確認
Dim confirmMsg As String
confirmMsg = “以下の置換を実行します。” & vbCrLf & _
“対象: ” & targetOldFileName & vbCrLf & _
“新ファイル: ” & newModelFullPath & vbCrLf & vbCrLf & _
“よろしいですか?”
If MsgBox(confirmMsg, vbYesNo + vbQuestion, “一括置換の確認”) = vbNo Then
Exit Sub
End If
‘ 3. ルートコンポーネントから再帰的に探索・置換を実行
Dim swRootComp As SldWorks.Component2
Set swRootComp = swAssocModel.GetRootComponent3(True)
If swRootComp Is Nothing Then
MsgBox “ルートコンポーネントが見つかりません。”, vbCritical, “エラー”
Exit Sub
End If
Dim replaceCount As Long
replaceCount = 0
‘ 再帰処理の呼び出し
Call TraverseAndReplace(swRootComp, targetOldFileName, newModelFullPath, replaceCount)
‘ 4. 完了報告とモデルの再構築
swModel.ForceRebuild3 True ‘ 全体を強制再構築
MsgBox “置換処理が完了しました。” & vbCrLf & _
“合計 ” & replaceCount & ” 個のコンポーネントを置き換えました。”, vbInformation, “完了”
End Sub
‘ —————————————————————–
‘ サブルーチン: コンポーネントツリーを再帰的に巡回し、一致するものを置換する
‘ —————————————————————–
Sub TraverseAndReplace(ByVal swComp As SldWorks.Component2, ByVal oldName As String, ByVal newPath As String, ByRef count As Long)
Dim vChildComps As Variant
Dim swChildComp As SldWorks.Component2
Dim i As Long
‘ 子コンポーネントの配列を取得
vChildComps = swComp.GetChildren
If IsEmpty(vChildComps) Then Exit Sub
For i = LBound(vChildComps) To UBound(vChildComps)
Set swChildComp = vChildComps(i)
‘ 参照しているドキュメント名(ファイル名)を取得
Dim compDocName As String
compDocName = swChildComp.GetUserName2(True) ‘ ユーザー定義名やファイル名
‘ 簡易的にファイル名の一致を確認(必要に応じてパス全体や大文字小文字を調整)
‘ GetPathNameを使うと完全なパスが取得できるため、ファイル名だけを抽出して比較する
Dim fullPath As String
fullPath = swChildComp.GetPathName()
If GetFileNameFromPath(fullPath) = oldName Then
‘ 該当したので置換を実行!
Dim bRet As Boolean
Dim nOptions As Long
‘ すべてのインスタンスを置き換えるオプション
nOptions = swReplaceComponentOption_All ‘ 又は swReplaceComponentOption_Model
bRet = swChildComp.ReplaceComponents(newPath, “”, True, nOptions)
If bRet Then
count = count + 1
Else
Debug.Print “警告: コンポーネントの置換に失敗しました -> ” & fullPath
End If
End If
‘ サブアセンブリである場合はさらに深く潜る(再帰呼び出し)
If Not swChildComp.GetChildren Is Nothing Then
Call TraverseAndReplace(swChildComp, oldName, newPath, count)
End If
Next i
End Sub
‘ —————————————————————–
‘ ユーティリティ関数: フルパスからファイル名のみを抽出する
‘ —————————————————————–
Function GetFileNameFromPath(ByVal fullPath As String) As String
Dim pos As Long
pos = InStrRev(fullPath, “\”)
If pos > 0 Then
GetFileNameFromPath = Mid(fullPath, pos + 1)
Else
GetFileNameFromPath = fullPath
End If
End Function
—
4. 陥りやすい罠と、プロが教える回避の極意
このコードは実戦でそのまま使える非常に強力なものだが、SolidWorks API特有の「お作法」を知らないと、思わぬエラーで足をすくわれる。ここでよくあるハマりどころをシェアしておこう。
罠その1: パスの区切り文字やファイル名のスペルミス
`newModelFullPath` に指定するパスが間違っていると、`ReplaceComponents` は静かに(エラーも吐かずに)失敗する。
必ず対象のファイルがそのパスに存在し、読み取り専用になっていないことを確認すること。また、ネットワークドライブ上のファイルを指定する場合は、読み込み速度の遅延によるタイムアウトに注意してほしい。
罠その2: コンポーネントの「軽量(Lightweight)」モード
大型アセンブリを開いたとき、SolidWorksはメモリを節約するためにコンポーネントを「軽量状態」で読み込むことがある。
軽量状態のコンポーネントに対してAPIを実行すると、正確なジオメトリ情報が取得できず、置換に失敗したり合致が吹き飛ぶ原因になる。
極意: 大規模アセンブリを自動化する際は、マクロの実行前にアセンブリ全体を「完全解決(Resolve)」状態にしておくか、API側で `IComponent2.SetSolveMode()` 等を用いて事前に解決状態へ持っていくのがプロの鉄則だ。
罠その3: 変更前後の形状差による合致エラー
型式違いと言いながら、メイトの基準となる面(面IDや面の種類)が大きく変わっていると、SolidWorksは「どの面を繋げばいいかわからない!」とパニックを起こし、黄色いエラーフラグを立てる。
これを防ぐには、「新旧のモデルで、合致に使用している参照面や軸のネーミング(または構造)を極力統一する」という設計レイヤーでの配慮が必要不可欠である。VBAは魔法の杖だが、物理法則やCADの数学的制約を超えることはできないのだから。
—
5. さあ、エンジニアとしての次のステージへ
ここまで読み進めてくれた君ならもう分かるはずだ。
SolidWorks VBAは、単なる「お絵かきツールのオマケ機能」などではない。設計プロセスのボトルネックを物理的に破壊し、エンジニアを単調な単純作業から解放するための最強の武器なのだ。
今回手に入れた `ReplaceComponents` の知見をベースに、例えば「Excelの部品表(BOM)を読み込ませて、アセンブリ内の全型式を数秒で自動アプデするシステム」へと発展させることも、今の君なら十分に可能だろう。
ここをクリアした君は、もう初学者ではない。
さあ、自分の設計環境に戻って、このコードを試してみてほしい。一瞬でモデルがパチパチと置き換わっていく爽快感を、ぜひその肌で味わってくれ。
健闘を祈る!
