まえおき
自作アドインを追加した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)のアドインのパスが異なる場合のみ、行うものとする。
一度更新がかかれば、後はエクセルの再起動が必要になることはない。
あとは表示するメッセージに気を付けること。
「アドインを更新します」だけではウィルス的な何かと勘違いされかねないのでいいかんじに変えてあげる必要がある。