使用 VBA 检测 Excel 版本中是否启用动态数组

Ben*_*Ben 4 excel vba excel-365

我正在尝试实施 Microsoft 所说的最佳实践,但没有成功。这是由于 Excel 中现在支持新的动态数组。这是他们的文章,下面是具体部分。这里

\n
\n

最佳实践

\n

如果针对 DA 版本的 Excel,则应优先使用 Range.Formula2,而不是 Range.Formula。

\n

如果针对 Excel 的 Pre 和 Post DA 版本,您应该继续使用 Range.Formula。但是,如果您希望严格控制用户公式栏的公式外观,则应检测是否支持 .Formula2,如果支持,则使用 .Formula2,否则使用 .Formula

\n
\n

在 VBA 中如何检测版本(Pre DA 或 Post DA)?

\n

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

\n
\xe2\x80\x98Detect Pre or Post DA version\nDim ExcelVersion As Variant\nExcelVersion = blabla bla test     \xe2\x80\x98Some test function HERE, return vbTrue if Post DA Version Enabled\n\nIf ExcelVersion = vbTure Then\n    Range.Formula2 = "=CustomFunction("& variable & ")"\nElse\n    Range.Formula = "=CustomFunction("& variable & ")"\nEnd If\n
Run Code Online (Sandbox Code Playgroud)\n

*上面使用 vbTure 作为示例,它可以是任何内容,与“变量”相同

\n

Mat*_*don 6

您应该检测是否支持 .Formula2,如果支持,则使用 .Formula2,否则使用 .Formula

这就是您确定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
Run Code Online (Sandbox Code Playgroud)

我想我会用一个过程来包装调用Sub,该过程需要一个Object参数来后期绑定 a 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
Run Code Online (Sandbox Code Playgroud)

这样,代码的其余部分就可以完成,SetFormula someCell, someFormula而无需担心是否会是Formula2or Formula,但他们仍然可以检查是否ThisWorkbook.SupportsDynamicArrays有条件地确定要传递的公式...并且如果有更好的方法,则留下了 1 个地方可以在之后进行调整遇到!


Cri*_*use 5

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

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
Run Code Online (Sandbox Code Playgroud)

  • 这也是一个很棒的方法! (2认同)