【上級プロ向け】図面とモデルの「絆」を守る:`FindReferences` によるリンク切れ完全自動修復術
「昨日まで動いていたマクロが、急に動かなくなった……」
「ファイル名を少し変えただけで、図面が真っ白(またはエラー)になってしまった……」
SolidWorksで業務自動化に携わる皆さんは、一度はこの「参照切れ(Broken Links)」という名の悪夢に直面したことがあるはずです。
マクロの記録機能を使って「なんとなく」コードを書く段階を卒業し、設計プロセスの根幹を支える「堅牢なシステム」を構築しようとする時、避けては通れないのがこの「参照の管理」です。
今日は、図面(Drawing)とモデル(Part/Assembly)の繋がりをAPIの深層から制御し、リンク切れを検知・自動修復する「トランザクション・レベルの設計思想」を伝授します。ここをクリアすれば、あなたのマクロは「便利ツール」から「信頼される業務基盤」へと進化します。
1. なぜ「マクロの記録」では参照切れを防げないのか?
多くの初学者が陥る罠は、「図面が見えていること」と「図面がモデルと正しくリンクしていること」を混同してしまうことです。
マクロの記録は、あくまで「今、画面上で行った操作」を記録します。しかし、ファイルのリネームや移動は「画面上の操作」ではなく、「OSレベルのファイルシステムの変化」です。
図面ファイルの中身(バイナリデータ)には、「このビューは `C:\Project\Part1.SLDPRT` を参照している」というパス情報が書き込まれています。ファイルが移動すると、図面は「存在しない幽霊」を追いかけ続けることになります。
これを解決するには、図面を開いた直後に「今、図面が追いかけているパスは、本当に実在するか?」をプログラムで問い直す必要があるのです。
2. 核心となる武器:`DrawingDoc.FindReferences`
ここで登場するのが、プロフェッショナルのための強力なメソッド、`DrawingDoc.FindReferences` です。
このメソッドは、図面内に配置されたすべてのビューが「どのモデルファイルを参照しているか」のリストを、`Reference` オブジェクトの配列として返してくれます。
仕組みを図解すると:
1. スキャン: `FindReferences` が図面内の全ビューを巡回。
2. 抽出: 各ビューが持っている「参照パス」を `Reference` オブジェクトとしてリストアップ。
3. 検証: 私たちがそのパスを `Dir()` 関数などでチェックし、実在するか確認。
4. 修復: もし存在しなければ、新しい正しいパスを `ReplaceReference` で流し込む。
この一連の流れを、単なる「修正」ではなく、「検知 $\to$ 検証 $\to$ 修復 $\to$ 保存」という一つのトランザクション(一連の不可分な処理)として設計するのが、エンジニアの腕の見せ所です。
3. 実践:自動修復エンジンの実装
それでは、実際に現場で使えるレベルの堅牢なコードを見ていきましょう。
このコードは、単にパスを書き換えるだけでなく、エラーハンドリングを組み込み、安全に動作するように設計しています。
'**
' Module: DrawingLinkRepairManager
' Description: 図面内の参照切れを検知し、指定した新パスへ自動修復する
'**
Option Explicit
Sub RepairDrawingReferences()
Dim swApp As SldWorks.SldWorks
Dim swModel As SldWorks.ModelDoc2
Dim swDraw As SldWorks.DrawingDoc
Dim vRefs As Variant
Dim i As Long
Dim swRef As SldWorks.Reference
Dim oldPath As String
Dim newPath As String
Dim targetFileName As String
Dim searchDirectory As String
Dim foundNewPath As String
Set swApp = Application.SldWorks
Set swModel = swApp.ActiveDoc
' 1. 基本チェック: ドキュメントが図面であるか?
If swModel Is Nothing Then Exit Sub
If swModel.GetType <> swDocDRAWING Then
MsgBox "図面ファイルを開いた状態で実行してください。", vbExclamation
Exit Sub
End If
Set swDraw = swModel
' 【設定エリア】ここを環境に合わせて調整します
' 例: モデルが移動した先の新しいルートディレクトリ
searchDirectory = "C:\Work\Project_New\"
' 探したいファイル名(部分一致でも可)
targetFileName = "Part1.SLDPRT"
' 2. 参照リストの取得
' FindReferencesは、図面内の全参照をVariant配列として返します
vRefs = swDraw.FindReferences
If IsEmpty(vRefs) Then
MsgBox "参照が見つかりませんでした。リンク切れの可能性はありません。", vbInformation
Exit Sub
End If
Debug.Print "--- 参照修復トランザクション開始 ---"
' 3. トランザクション・ループ
For i = 0 To UBound(vRefs)
Set swRef = vRefs(i)
oldPath = swRef.GetPathName
' 参照ファイルが実在するかチェック
If Dir(oldPath) = "" Then
Debug.Print "【警告】リンク切れ検知: " & oldPath
' 新しいパスを探索(ここでは単純な結合例ですが、実際にはロジックを組みます)
foundNewPath = searchDirectory & targetFileName
' 4. 修復の実行
If Dir(foundNewPath) <> "" Then
Debug.Print " -> 修復実行: " & foundNewPath
' ★ここが極意:ReplaceReferenceメソッドでリンクを繋ぎ直す
' 引数: (新しいフルパス)
swRef.ReplaceReference foundNewPath
' 参照を更新するためにモデルを再構築
swModel.ForceRebuild3 True
Else
Debug.Print " !! エラー: 新しいパスにもファイルが存在しません。"
End If
Else
Debug.Print "【正常】リンク維持: " & oldPath
End If
Next i
' 5. 完了処理
Debug.Print "--- トランザクション終了 ---"
MsgBox "参照の検証と修復プロセスが完了しました。ログを確認してください。", vbInformation
End Sub
4. プロフェッショナルへの階段:設計の勘所
このコードをさらに進化させ、現場の「プロ」として運用するための知見をいくつか共有します。
① 「再構築(Rebuild)」の重みを知る
コード内で `swModel.ForceRebuild3 True` を呼び出しています。これは非常に強力ですが、図面が巨大な場合、処理が重くなります。
プロのテクニック: ループの中で毎回 Rebuild するのではなく、すべての `ReplaceReference` が終わった後に、最後に一度だけ Rebuild を実行するのがパフォーマンス最適化の鉄則です。
② エラーハンドリングの重要性
ファイルシステム操作(`Dir` 関数など)は、ネットワークドライブの切断や権限不足で予期せぬエラーを吐くことがあります。
実務では `On Error GoTo ErrorHandler` を使い、エラーが発生した際に「どのファイルで失敗したか」をログに残し、プログラムを安全に終了させる設計にしてください。
③ 検索ロジックの高度化
上記の例ではパスを固定していますが、実際には以下のようなロジックを組み込むのが理想的です。
- ハッシュ値比較: ファイル名が違っても、中身(バイナリ)が同じなら同一モデルとみなしてリンク。
- 再帰的検索: 指定フォルダ配下をサブフォルダまで全て探索。
まとめ:ここをクリアすれば、あなたはもう「初級者」ではない
`DrawingDoc.FindReferences` を使いこなすということは、単に「エラーを直す」ことではありません。「データの整合性をプログラムによって保証する」という、エンジニアリングの本質に踏み込むことです。
1. 構造を理解する: 図面はモデルへのポインタ(参照)の集合体である。
2. 検知する: `FindReferences` で実在しないパスを特定する。
3. 修復する: `ReplaceReference` で新しい絆を定義する。
このステップを意識してコードを書くようになれば、あなたの作る自動化ツールは、どんな環境の変化にも動じない、真に価値のあるものへと変わるはずです。
さあ、恐れずに、この深淵なAPIの世界へ踏み出しましょう。応援していますよ!
