检测是否在带有VBA的Excel版本中启用了动态阵列



我正试图实现微软所称的最佳实践,但没有成功。这是由于最新支持的动态数组现在在excel中得到支持。这是他们的文章,下面是具体部分。这里

最佳实践

如果目标是Excel的DA版本,则应使用Range。公式2优先于范围。公式

如果目标是Excel的DA前和DA后版本,则应继续使用Range。公式但是,如果您希望严格控制用户公式栏中公式的外观,则应检测是否。支持公式2,如果支持,则使用。公式2否则使用。公式

VBA中如何检测版本(预DA或后DA(?

我已经在excel中创建了宏,这些宏在旧版本的excel中都能很好地工作,但一旦引入新版本,公式就会发生变化,因为它依赖于以前的默认值";隐含交叉点评估(IIE(";。由于新版excel中的方法被取代,所有VBA实现都依赖于旧方法,而新版excel在公式中添加了隐式交集运算符@。因为这可能会破坏复杂的工作表,所以我希望能够检测当前版本的excel是否支持动态数组,如果是这样,我希望能够将range.formula的所有实现替换为range.formula2

‘Detect Pre or Post DA version
Dim ExcelVersion As Variant
ExcelVersion = blabla bla test     ‘Some test function HERE, return vbTrue if Post DA Version Enabled
If ExcelVersion = vbTure Then
Range.Formula2 = "=CustomFunction("& variable & ")"
Else
Range.Formula = "=CustomFunction("& variable & ")"
End If

*上面使用vbTure作为例子,它可以是任何东西,与";变量";

您应该检测是否。支持公式2,如果支持,则使用。公式2否则使用。公式

这就是您了解Excel版本是否支持DA函数的方法。它没有说明的是,您可以在不支持DA函数的系统上通过尝试分配给该属性来捕获错误1004。

因此,我们可以想象地封装一个检查,看看是否支持Formula2,作为ThisWorkbook模块的属性:

Private SupportsDA As Boolean
Public Property Get SupportsDynamicArrays() As Boolean
Static BeenThere As Boolean
If Not BeenThere Then ' only do this once
Dim LateBoundCell As Object
Set LateBoundCell = Application.ActiveCell
If LateBoundCell Is Nothing Then 
'if there is no active sheet/cell, we cannot tell
SupportsDA = False ' err on the safer side
BeenThere = False ' better luck next time, maybe
Else
BeenThere = True
On Error Resume Next
LateBoundCell.Formula2 = LateBoundCell.Formula2
If Err.Number = 438 Then
'Range.Formula2 is inexistent, return false.
SupportsDA  = False
ElseIf Err.Number = 1004 Then
'DA not supported
SupportsDA = False
Else
SupportsDA = True
End If

On Error GoTo 0
End If
End If
SupportsDynamicArrays = SupportsDA
End Property

我想我应该用Sub过程来包装调用,该过程使用Object参数来延迟绑定Range,以及公式字符串,如下所示:

Public Sub SetFormula(ByVal Target As Object, ByVal Formula As String)
If Not TypeOf Target Is Range Then Err.Raise 5 ' invalid argument
If ThisWorkbook.SupportsDynamicArrays Then
Target.Formula2 = Formula ' late-bound call will still compile in older hosts
Else
Target.Formula = Formula
End If
Else
End If

这样,代码的其余部分就可以执行SetFormula someCell, someFormula,而不必担心是Formula2还是Formula,但他们仍然可以检查ThisWorkbook.SupportsDynamicArrays是否有条件地确定要通过的公式……如果有更好的方法,之后只剩下一个地方可以调整!

我们可以使用隐式交集运算符(@(来检查动态数组支持:

Option Explicit
Public Function HasDynamicArrays() As Boolean
Static isDynamic As Boolean
Static ranCheck As Boolean

If Not ranCheck Then
isDynamic = Not IsError(Evaluate("=COUNT(@{1,2,3})"))
ranCheck = True
End If
HasDynamicArrays = isDynamic
End Function

另一个想法是:随着动态数组的新支持,也有了新的错误枚举。检查枚举是否存在,如果存在,则检查动态数组是否存在。。。

IsDynamicArrayHere = CLng(CVErr(xlErrSpill)) = 2045

*编辑:但请参阅下面的评论;由于错误枚举是在功能更新之前更新的,因此不完全防水。

这里有另一种方法:

On Error Resume Next
' test support for dynamic arrays
V = WorksheetFunction.Unique([{1;2}])
If Err <> 0 Then ... ' requires Excel 365/2021+
On Error GoTo 0

相关内容

最新更新