我正在为 UDF 的 VBA 开发人员开发一个 VBA 模块(称之为“
Greg
”),这增强了他们现有的模块。他们只需将一个片段复制到自己的模块中(称之为 Dev
):如果 Greg
被加载,该片段会增强行为;否则没有什么区别。
这是
Greg.bas
... 的简化草图
Attribute VB_Name = "Greg"
' Keep these functions invisible to Excel users.
Option Private Module
' Enhancement Function.
Public Function Enhancer(Optional x)
' ...
End Function
' Assert the 'Greg' module is loaded.
Public Function IsLoaded() As Boolean
IsLoaded = True
End Function
...以及
Dev.bas
:
Attribute VB_Name = "Dev"
' Some UDF by the dev.
Public Function DevRegular()
' ...
End Function
' #############
' ## Snippet ##
' #############
' Use the enhancer, if available via the 'Greg' module.
Public Function DevEnhanced(Optional x)
If Enhance_IsSupported() Then
DevEnhanced = Greg.Enhancer(x)
Else
DevEnhanced = DevRegular()
' Prompt the user to import the enhancer.
MsgBox "Import the 'Greg' module to enhance your experience."
End If
End Function
' Check if enhancement is supported via the 'Greg' module.
Private Function Enhance_IsSupported() As Boolean
On Error GoTo Fail
Enhance_IsSupported = Greg.IsLoaded()
Exit Function
Fail:
Enhance_IsSupported = False
End Function
虽然这在 Windows 上偶尔有效,但在 Mac 上却经常失败。关键似乎是
Enhance_IsSupported()
内Dev
:
Private Function Enhance_IsSupported() As Boolean
On Error GoTo Fail
Enhance_IsSupported = Greg.IsLoaded()
Exit Function
Fail:
Enhance_IsSupported = False
End Function
我假设
Greg.IsLoaded()
行会编译,即使没有 Greg
模块存在......而且确实如此!仅当 Greg
模块 不存在 名为 IsLoaded()
的成员时才会失败。
不幸的是,VBA 似乎无法可靠地刷新其对具有 Greg
函数的
IsLoaded()
模块的“感知”。
当我导入
Greg.bas
和 Dev.bas
一起时,一切都会按预期工作:Enhance_IsSupported()
返回 True
,如果删除 False
,它会更新为
Greg
。
但是当我第一次导入
Dev.bas
和 run DevEnhanced()
,并且只有 afterwards 导入 Greg.bas
时,然后 Enhance_IsSupported()
显然会返回 False
尽管 存在 Greg
。
后一个工作流程绝对重要:Excel 用户必须首先运行
DevEnhanced()
并查看提示,以便首先了解 Greg.bas
!
不幸的是,没有任何实验有效。在
Greg
本身,我尝试使用常量...
Public Const IS_LOADED As Boolean = True
...还有一个程序:
Public Function IsLoaded() As Boolean
IsLoaded = True
End Function
在
Dev
的片段中,我已经隐式尝试了Application.Evaluate()
...
Private Function Enhance_IsSupported() As Boolean
On Error GoTo Fail
Enhance_IsSupported = [Greg.IsLoaded()]
' ^^^^^^^^^^^^^^^^^
' Application.Evaluate("Greg.IsLoaded()")
Exit Function
Fail:
Enhance_IsSupported = False
End Function
...但是虽然这适用于
Enhance_IsSupported()
本身,同样的错误只会在其他地方出现 - 就像在 Greg.*
的其他实例上打地鼠一样 - 并且 只有手动编辑才能“刷新”这些程序。我还希望避免对任何 .Evaluate()
方法的不稳定调用,即使是在 Worksheet
范围内。
Dev
模块的最简单方法是什么,以便其程序现在识别对Greg.*
的调用?Static
中的缓存或
Dev
变量的情况下实现?IS_LOADED
常量而不是 IsLoaded()
过程来完成吗?Sub
这样在 Dev.Refresh()
开始时自动调用的 Enhance_IsSupported()
来完成吗?Sub
(如 Greg.Refresh()
)来完成吗?由用户在 VBA 编辑器中手动运行?这个项目代表了我大量的时间和精力的投入,并且它在其他方面是可操作的,因此非常感谢您的帮助来克服这最后的障碍!
你已经提到了一个常数,为什么不呢:
在格雷格模块中:
Public Const GREG_IS_LOADED = True
在模块开发中:
' Use the enhancer, if available via the 'Greg' module.
Public Function DevEnhanced(Optional x)
#If GREG_IS_LOADED Then
'If Enhance_IsSupported() Then
DevEnhanced = Greg.Enhancer(x)
#Else
'Else
DevEnhanced = DevRegular()
' Prompt the user to import the enhancer.
MsgBox "Import the 'Greg' module to enhance your experience."
'End If
#End If
End Function