方括号表达式在 M365 和 Excel 2016 中的计算方式不同

Square bracketed expression is evaluated differently in M365 vs Excel 2016

我工作的公司最近从 Office 2016 迁移到 M365。我们的一些启用宏的电子表格使用方括号表达式作为 Application.Evaluate 方法的快捷方式。例如:

Private Sub Worksheet_Change(ByVal Target As Range)

    Dim msg As String
    
    On Error GoTo ErrHandler:
    
    If Target.Columns.Count > 100 Then
        Dim row As Range
        For Each row In Target.Rows
            RemoveRowBorders row:=row.row, firstColumn:=[colSourceDevice], lastColumn:=[colItemNumber]
        Next
        
        UpdateItemNumbers startingRow:=[rowStart], maxRange:=[maxRange]
        GoTo My_Exit
    End If
    
    If Target.Column >= [colSourceDevice] And Target.Column <= [colItemNumber] Then
        SetCalculations cellRange:=Target
    End If
    
My_Exit:
    Exit Sub

ErrHandler:
    msg = "An error occurred on cell auto-update: " & vbNewLine & Err.Description
    MsgBox msg
    Resume My_Exit
End Sub

“colSourceDevice”是一个名为 range/object 的公式,它指的是 return 列号的公式,括号中的表达式是调用 Application.Evaluate 方法的快捷方式。 “colSourceDevice”中引用的公式为:

=VALUE(COLUMN('HS - Main'!$A))

在 Excel 2016 中,括号表达式 return 是列号 (Variant/Double).

在 M365 Excel 中,括号中的表达式 return 是一个数组 (Variant/Variant),其中包含一项 (Variant/Double)。

在 M365 Excel 中,这会导致类型不匹配错误。

我可以使用对象模型方法代替括号表达式并获得预期结果:

Application.Evaluate("colSourceDevice")(1) 'returns column number (Variant/Double)

为什么方括号表达式 return M365 与 Excel 2016 中的数据类型不同?

编辑:

正如 chris neilsen 所暗示的,Excel 计算引擎在 2018 年发生了重大变化。

看这里: Excel: Microsoft unveils Dynamic upgrades

实现方括号表达式遗留行为的另一种方法是将新的隐式交集运算符 (@) 添加到方括号内的命名范围:

    If Target.Column >= [@colSourceDevice] And Target.Column <= [@colItemNumber] Then
        SetCalculations cellRange:=Target
    End If

...如此处所述: Microsoft makes major Dynamic Arrays modifications

我怀疑这个问题与 32/64 位无关,而是从 Excel 2016 到 355 的变化。这引入了动态范围,这是公式工作方式的根本变化。

由于您没有在您的命名范围内提供公式,我将根据一个示例公式来回答这个问题,该公式可能反映也可能不反映您的公式。

colSourceDevice Refers to = =COLUMN()

这表现出您描述的行为

它实际做的是return创建一个包含 1 个元素的动态数组。

为了 return 该值作为变体,通过将其包装在 INDEX

中修改命名范围
colSourceDevice2 Refers to = =INDEX(COLUMN(),1,1)

结果如你所愿


免责声明:

综上所述,这是对某些设计不当的代码的创可贴修复。我的建议:重构您的代码以消除这种和其他不良做法。