将数组作为要查找的参数时在 INDEX(MATCH()) 中达到的限制

Limits reached in INDEX(MATCH()) when taking array as argument to look in

我使用这个公式:

=IFERROR(IF(MATCH(transf(E7);transf(Sheet2!$C:$C648);0)>0;"YES");"no")

transf 是一个 UDF,它只是 converts/transforms 将单元格中的实际文本值转换为小写并执行其他一些操作(不是该问题的主题)。

通常情况下,如果transf(E7)的值在构成的数组transf(Sheet2!$C:$C648)中找到,公式returnsYES,如果没有-no

UDF本身效果不错,经过多次测试。 问题是这次不行了。返回的答案是no,不正确。这个公式失败是否与 66k+ 项的大数组有关?用作数组公式的 UDF 有哪些限制?

编辑 1

这是我的 UDF 的简化版本:

Public Function transf(ByVal vText As Variant) As Variant
Dim aText() As Variant
Dim j As Long
    On Error GoTo ErrH

    If TypeName(vText) = "String" Then
        '...some code...
    ElseIf TypeName(vText) = "Variant()" Then
        '...some code...
    ElseIf TypeName(vText) = "Range" Then   ' <<< both instances of the UDF fall here
        ReDim aText(1 To vText.Count)
        For j = 1 To vText.Count
            aText(j) = Trim(LCase(vText(j)))
        Next
        transf = Application.Transpose(aText)   ' <<< this line causes an error 13
    Else
        transf = CVErr(xlErrValue)
    End If
ErrH:
    'This was created not for the current case, but the error the UDF gets has the same #
    If Err.Number = 13 Then
        Err.Clear
        Resume Next
    End If

End Function

如果您发现性能方面的任何其他缺陷,请告诉我。

编辑 2

我正在使用 Excel 2010。没有兼容模式,文件本身 - .xlsm,UDF 在 .xlam 加载项文件中。

Transpose 函数有一个限制,具体取决于您使用的 Excel 版本。在大多数情况下,它等于工作表中可能的列数——尽管在最新版本中它可能更大(我没有检查过)。

我建议您填充 aText 这样您就不必进行转置。虽然,只是为了在数组中找到一个值,您根本不必转置它。当然,您可能会对结果做其他事情。

例如:对于垂直阵列:

ReDim aText(1 To vText.Count, 1 to 1)
    For j = 1 To vText.Count
        aText(j,1) = Trim(LCase(vText(j)))
    Next

编辑: 在与 ZygD 讨论和一些测试之后,将工作表函数应用于变量数组似乎还有另一个限制。除了上面提到的 TRANSPOSE 限制外,第一维中似乎存在 65536 个元素的大小限制,如下面的代码所示。

我们用数字填充 A:A 范围。 然后我们生成这个范围的变体数组,它要么包含整个列,要么只包含 65,536 个元素。从输出可以看出,在整列的情况下,使用Range对象为lookup_array,宏按预期执行;但是使用变体数组作为“lookup_array”会导致错误,如果它大于 65,536 个元素。

使用INDEX函数也出现类似的错误;其他的我没有测试过。


Option Explicit
Sub Tester()
    TestArr Range("A1:A65536")
    TestArr Range("A1:A65537")
End Sub

Sub TestArr(R As Range)
    Dim V

V = R

On Error Resume Next
    Debug.Print "Array Size: " & R.Rows.Count
    Debug.Print "Variant Array: " & WorksheetFunction.Index(V, 147, 1)
    If Err.Number <> 0 Then
        Debug.Print "Variant array: Error " & Err.Number, Err.Description
        Err.Clear
    End If

Debug.Print "Range Array: " & WorksheetFunction.Index(R, 147, 1)
Debug.Print vbLf

End Sub