【実務・中級編】【上級】AcadApplication.Preferences.Files.SupportPathの動的書き換え:プロジェクト専用フォルダを一時的に検索パスへ追加する – AutoCAD VBA解析バイブル

スポンサーリンク

【上級】AcadApplication.Preferences.Files.SupportPathの動的書き換え:プロジェクト専用フォルダを一時的に検索パスへ追加する

こんにちは。開発プロジェクトのリーダー、あるいは現場の自動化を極めんとするあなたへ。

AutoCAD VBAの実務において、最も頭を悩ませる問題の一つが「パスの解決」だ。
外部参照(Xref)、フォント(SHX/TTF)、カスタマイズされたハッチングパターンや線種ファイル、そしてブロック。これらがデフォルトの検索パスや図面と同じフォルダに収まっていない場合、AutoCADは容赦なく「ファイルが見つかりません」の警告を出し、処理を中断させる。

「じゃあ、事前にAutoCADのオプション画面からサポートファイル検索パスに追加しておけばいいじゃないか」

……甘い。そんな運用を強いるから、部署内で展開したときに「動かないトラブル」が頻発するのだ。開発者が手動で環境構築を強いるアプローチは、プロの仕事とは言えない。
さらに言えば、マクロの実行が終わった後も、一時的に必要だったプロジェクト専用パスが設定に残り続けるのは、環境汚染(Pollution)の何ものでもない。他の業務に悪影響を及ぼすリスクすらある。

今回は、「マクロ実行中だけ安全にサポートパスを動的追加し、例外が発生しようとも確実に元の状態へ復元する」という、極限まで堅牢な環境制御術を伝授しよう。

なぜ「その場しのぎのコード」は現場を崩壊させるのか?

まずは、よくある「やってはいけないアンチパターン」を確認する。

‘ 【悪例】エラー対策も復元処理もない危険なコード
Sub BadExample()
Dim currPath As String
currPath = ThisDrawing.Application.Preferences.Files.SupportPath

‘ 勝手にパスを追加するだけ
ThisDrawing.Application.Preferences.Files.SupportPath = currPath & “;C:\ProjectA\Resources”

‘ 何らかの処理…

‘ ※ここでエラーが起きたら、復元処理は永遠に実行されない!
End Sub

このコードの何が致命的か?
1. 例外耐性の欠如: 途中で実行時エラー(図面のオープン失敗など)が発生した瞬間、コードが停止し、`SupportPath`は汚染されたままになる。
2. セミコロン(`;`)の結合ミス: 文字列の連結でデリミタ(`;`)を忘れると、既存のパスと新しいパスが結合してしまい、AutoCADがパスを認識できなくなる。
3. レジストリ/メモリへの負荷: `Preferences`オブジェクトへの書き込みは、裏でAutoCADのプロファイル設定を書き換える重い処理である。無駄に頻発させるべきではない。

我々が目指すべきは、「トランザクションの発想を取り入れた、不可逆な環境汚染を起こさないコード」である。

堅牢な環境制御クラスの設計思想

プロフェッショナルなコードを書くためには、「リソースの確保と解放(RAIIの概念)」をVBAのスコープ管理に持ち込む必要がある。

今回は、以下の要件を満たす設計を行う。

  • パスの追加と削除をカプセル化する。
  • VBAの実行中に予期せぬエラーが発生し、`Err`オブジェクトが発火しても、必ず元のパスへ復元されるクリーンアップ保証(`On Error GoTo`の徹底)。
  • 重複パスの登録を防ぐバリデーション。

プロダクションコード:SupportPathManager

以下のコードを、そのままあなたのVBAプロジェクト(標準モジュール、またはクラスモジュール)に実装してほしい。実務でそのまま使える堅牢性を持たせている。

Option Explicit

‘ ==============================================================================
‘ módulo: ModSupportPathManager
‘ 概要 : AutoCADのサポートファイル検索パスを安全に一時変更・復元するマネージャー
‘ ==============================================================================

Private m_OriginalSupportPath As String
Private m_TargetAddedPath As String
Private m_IsModified As Boolean

‘——————————————————————————
‘ 目的のフォルダを一時的にサポートパスの先頭(または末尾)に追加する
‘——————————————————————————
Public Function TemporarilyAddSupportPath(ByVal folderPath As String) As Boolean
Dim acadApp As AcadApplication
Set acadApp = ThisDrawing.Application

‘ パスの存在確認(FileSystemObjectを使用)
Dim fso As Object
Set fso = CreateObject(“Scripting.FileSystemObject”)
If Not fso.FolderExists(folderPath) Then
MsgBox “指定されたパスが存在しません: ” & folderPath, vbCritical, “パス追加エラー”
TemporarilyAddSupportPath = False
Exit Function
End If

On Error GoTo ErrorHandler

‘ 現在の設定を退避
m_OriginalSupportPath = acadApp.Preferences.Files.SupportPath
m_TargetAddedPath = folderPath
m_IsModified = False

‘ 既にパスが含まれているかチェック(大文字小文字を区別しない比較)
If InStr(1, m_OriginalSupportPath, folderPath, vbTextCompare) > 0 Then
‘ すでに存在する場合は何もしない
TemporarilyAddSupportPath = True
Exit Function
End If

‘ パスを追加(AutoCADの仕様上、セミコロン区切り。先頭に追加して優先度を上げる)
‘ ※末尾に追加したい場合は “C;B” のように結合する
acadApp.Preferences.Files.SupportPath = folderPath & “;” & m_OriginalSupportPath
m_IsModified = True
TemporarilyAddSupportPath = True
Exit Function

ErrorHandler:
MsgBox “サポートパスの追加中に致命的なエラーが発生しました: ” & Err.Description, vbCritical
TemporarilyAddSupportPath = False
End Function

‘——————————————————————————
‘ パスを元の状態に確実に復元する
‘——————————————————————————
Public Sub RestoreSupportPath()
If Not m_IsModified Then Exit Sub

On Error GoTo ErrorHandler

Dim acadApp As AcadApplication
Set acadApp = ThisDrawing.Application

‘ 元のパスに戻す
acadApp.Preferences.Files.SupportPath = m_OriginalSupportPath
m_IsModified = False
Exit Sub

ErrorHandler:
‘ 復元失敗時は最低限ログやメッセージで管理者へ通知
MsgBox “【警告】AutoCADのサポートパスの復元に失敗しました。手動でオプションを確認してください。” & vbCrLf & _
“復元対象: ” & m_OriginalSupportPath, vbExclamation, “復元エラー”
End Sub

現場で使うための実践的メインルーチン

上記のマネージャーモジュールを呼び出すメイン処理の書き方だ。ここでも、「必ず最後に復元処理を通す(Finally句の代用)」構造を徹底する。

Sub Main_ProcessWithDynamicPath()
Dim targetProjectFolder As String
targetProjectFolder = “D:\CompanyStandard\ProjectX\SupportFiles”

‘ 1. パスを一時追加(失敗時は処理中断)
If Not TemporarilyAddSupportPath(targetProjectFolder) Then Exit Sub

‘ 2. エラー監視下のメイン処理ブロック
On Error GoTo CleanUp

‘ —————————————————-
‘ ここに実際の業務ロジックを書く
‘ 例:外部参照のバインド、特殊フォントを使う図面の処理など
Debug.Print “プロジェクト専用パスが適用された状態で処理を実行中…”

‘ わざとエラーを起こしてみるテスト(コメントアウト解除して確認可能)
‘ Err.Raise 9999, , “意図的なテストエラー”

‘ —————————————————-

CleanUp:
‘ 3. 正常終了・異常終了を問わず、必ず環境を復元する
Dim errNum As Long, errDesc As String
errNum = Err.Number
errDesc = Err.Description

RestoreSupportPath()

‘ エラーがあった場合はここで再送出
If errNum <> 0 Then
MsgBox “業務処理中にエラーが発生しました。” & vbCrLf & errDesc, vbCritical, “処理中断”
Else
MsgBox “すべての処理が正常に完了し、AutoCADの環境をクリーンアップしました。”, vbInformation, “完了”
End If
End Sub

チーフアーキテクトからの実務アドバイス

1. 優先度の制御について
コード内では `folderPath & “;” & m_OriginalSupportPath` とし、最優先(先頭)で検索させるようにしている。社内標準のフォントやブロックを優先的にロードさせたい場合は、先頭への追加が鉄則だ。逆に、ユーザー個人の設定を優先したい場合は末尾(`m_OriginalSupportPath & “;” & folderPath`)に調整せよ。
2. マルチドキュメント環境(MDI)への配慮
`AcadApplication.Preferences` はアプリケーションスコープ(セッション全体)の設定である。そのため、複数の図面(`AcadDocument`)をタブ切り替えして並行作業するようなマクロを組む場合、ある図面用のパス追加が、別の図面のバッチ処理に意図せず干渉するリスクがある。
そのため、パスの動的書き換えを行うマクロは、単一ドキュメントに対する重い一括処理(バッチ処理)の直前・直後でのみ使用するのが最も安全なライフサイクル管理である。

小手先のテクニックではなく、CADの裏側の状態(State)までコントロールする――これこそが、現場の信頼を勝ち取るエンジニアの作法である。
あなたの自動化ツールが、明日からより堅牢に稼働することを願っている。

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