无法刷新对外部xlsm文件的引用

我有两个Excel文件,父项和子项,其中子项包含由父项function使用的函数库。 为了版本的目的,我把它们保存在同一个文件夹中,并在完全相同的位置复制和重命名文件夹以跟踪我的版本。 我也希望dynamic更新引用,以便当我移动到一个新的版本,父母总是指向同一地点的孩子。

所以为了做到这一点,我在父项中实现了两个例程。

一,在ThisWorkbook中我使用了Workbook_Open sub:

Private Sub Workbook_Open() 'Force the location of the shared library to the current project folder irrespective where the project is located Call reloadSharedLibrary End Sub 

二,在Modules.Libraries中,我添加了另一个sub reloadSharedLibrary:

 Public librName As Variant Public isRefReloaded As Boolean Sub reloadSharedLibrary() isRefReloaded = True Dim VBAEditor As VBIDE.VBE Dim vbProj As VBIDE.VBProject Dim chkRef As VBIDE.Reference Dim BoolExists As Boolean Dim librPath As String Set VBAEditor = Application.VBE Set vbProj = ActiveWorkbook.VBProject librName = "lib_emtm" librPath = Application.ActiveWorkbook.Path & "\lib.xlsm" ' delete any shared lib (if exists) For Each chkRef In vbProj.References If chkRef.Name = librName Then vbProj.References.Remove chkRef BoolExists = True End If Next ' you can only add it to VBAProject only after you quit the above loop On Error Resume Next vbProj.References.AddFromFile librPath If Err.Number <> 0 Then MsgBox "FATAR ERROR: Cannot find shared library file in project root": End End If Set vbProj = Nothing Set VBAEditor = Nothing End Sub 

现在,这个问题是,当我将项目文件夹复制到一个新的版本文件夹对子的引用不会得到更新。 版本使用的孩子来自旧版本。

我究竟做错了什么?

问题是,当VBA项目加载一个文档及其引用时,它会为它们分配一个名称,在您的情况下是lib_emtm 。 当您取消对引用的引用时,将从VBA项目中删除引用,但项目编辑器会将名称保留在其caching中。 此名称将保留在caching中,直到您closures工作簿并重新打开它。

您可以在项目引用菜单中validation:即使您取消选中引用,库lib_emtm的名称仍将显示在此处。

然后,当您尝试添加对“其他”子工作簿(同一个文件夹中的工作簿)的引用时,编辑器将会发现名称是lib_emtm ,它与caching中的名称相同,因此不必打开新的文件和parsing它,它会使用caching的版本,这是旧的!

如果closures然后重新打开应用程序,则库的名称将从caching中消失,因此您可以安装正确的版本。 为了完整起见,这种模式只会引用其他工作簿,而不是在系统上安装常规DLL

我试过,但无法find一个VBA的方式来重新安装之前,从编辑器的caching中删除Cached library 。 如果有人find了解决办法。 因此,在重新打开并安装lib之前,我们必须closures文档。 这个过程可能是自动的,但我build议一个解决scheme,提示用户。

 ' Module ThisWorkbook Option Explicit Private Sub Workbook_Open() 'Force the location of the shared library to the current project folder irrespective where the project is located Dim check As Boolean: check = checkSharedLibrary If check Then Exit Sub Dim prompt prompt = MsgBox("The installed lib_emtm library was uninstalled because it was not the correct version." & vbCrLf & _ "If you click Ok, document will close and the correct version will be automatically installed when you reopen it." & vbCrLf & _ "If you click Cancel, library will not be available in this session but will be installed next time you open the document", vbOKCancel) If prompt = vbOK Then ThisWorkbook.Close True End Sub ' Regular module Option Explicit Private librName As String, librpath As String ' if correct version already installed (correct path) return true ' if library installed with incorrect version, uninstall it and return false ' if library not installed, install it and return true Public Function checkSharedLibrary() As Boolean librName = "lib_emtm" librpath = ThisWorkbook.Path & "\lib_emtm.xlsm" Dim chkRef As VBIDE.Reference For Each chkRef In ThisWorkbook.VBProject.References If chkRef.name = librName Then Exit For Next If chkRef Is Nothing Then install_emtm checkSharedLibrary = True ElseIf Left(chkRef.FullPath, InStrRev(chkRef.FullPath, "\") - 1) = ThisWorkbook.Path Then checkSharedLibrary = True ' we have the correct version Else ThisWorkbook.VBProject.References.Remove chkRef ' return false End If End Function Private Sub install_emtm() On Error Resume Next ThisWorkbook.VBProject.References.AddFromFile(librpath) If Err.Number <> 0 Then MsgBox "FATAR ERROR: Could not install lib_emtm:" & vbCrLf & Err.Description & vbCrLf & vbCrLf & _ "Please verify that the library's file is present in the same folder or try a manual install" End Sub 

最后一点,如果我们直接closures应用程序,但在此之前,我们可以安排重新打开工作簿,这个过程可以在没有用户干预的情况下实现自动化。 但事情可能会变得复杂,因为用户可能有其他Excel文档打开,所以我们不能让她closures所有的东西。