[VBA] 同名アドインの参照パスを自動更新を行う方法

まえおき

自作アドインを追加したVBAをファイルサーバ上で公開したとする。
そのままVBAとアドインをローカルに落とした場合、VBAはファイルサーバの方のアドインを参照したままになる。

そこで困ることとしては、アドインのファイルから同階層にある「Process1.xlsx」を開くとする。
処理としてはThisworkbook.Path & “Process1xlsx” のような書き方になる。

ただ、サーバにあるアドインを参照しているのだから、アドインはサーバ上にあるProcess1.xlsxを探し出そうとしてしまう。

やりたいこと

サーバーVBAとアドインを落としたとき、VBAはローカルに落としたアドインを参照するようにしたい。

ソースコード

Option Explicit

Private Sub Workbook_Open()
    Call UpdateAddin
End Sub

' 最新の参照設定を設定する
Private Sub UpdateAddin()

    Dim has_configured As Boolean
    has_configured = False
    
    ' アドイン名
    Const ADDIN_FILE_NAME As String = "ConfigManager.xlam"
    With ThisWorkbook.VBProject
        Dim ref
        For Each ref In .References
            If (InStr(ref.fullPath, ADDIN_FILE_NAME) > 0) Then
                
                ' 追加済みアドインのパスを取得
                Dim fso As Object
                Set fso = CreateObject("Scripting.FileSystemObject")
                Dim put_config_folder As String
                Dim f As Object
                Set f = fso.getfile(ref.fullPath)
                put_config_folder = f.parentFolder.parentFolder.path
                
                ' Configファイルの配置場所に変更があった場合、一度アドインを削除し、エクセルの再起動を行う
                ' ※ エクセル起動中ではアドインの削除が反映されないため、再起動が必要
                If (ThisWorkbook.path <> put_config_folder) Then
                    MsgBox ("アドインのパスを更新します。" & vbCrLf & "もう一度エクセルファイルを開きなおしてください")
                    Call .References.Remove(ref)
                    ThisWorkbook.Save
                    ThisWorkbook.Close
                Else
                    has_configured = True
                End If
            End If
        Next
    End With

    ' 旧アドイン削除に再度本ブックが開かれた場合
    ' 直下のConfigフォルダにあるアドインを参照先として加える
    If (has_configured = False) Then
        With ThisWorkbook.VBProject
            Dim addin_path As String
            addin_path = ThisWorkbook.path & "/Config/" & ADDIN_FILE_NAME
            Call .References.AddFromFile(addin_path)
        End With
        MsgBox ("アドインのパスを更新しました。")
        ThisWorkbook.Save
    End If
End Sub

解説

  • For Each ref In ThisWorkbook.VBProjectでVBAに設定されているアドインを取得する。
  • .References.Remove(ref)がアドインの削除であり、.References.AddFromFile(addin_path)がアドインの追加である。

エクセルの仕様(バグ?)として、パス1にあるアドインを削除 > パス2にある同名のアドインを追加とした場合、そのパスは更新されない。一度削除した後にエクセルを保存してから閉じる処理を挟む必要がある。
アドインの更新は、設定済み(パス1)のアドインと、参照したい(パス2)のアドインのパスが異なる場合のみ、行うものとする。
一度更新がかかれば、後はエクセルの再起動が必要になることはない。

あとは表示するメッセージに気を付けること。
「アドインを更新します」だけではウィルス的な何かと勘違いされかねないのでいいかんじに変えてあげる必要がある。