Home » excel » excel – VBA Index function size limit

excel – VBA Index function size limit

Posted by: admin May 14, 2020 Leave a comment

Questions:

In cells A1:A66000 I have the numbers 1, 2, … 66000.

Sub addData()
    Application.ScreenUpdating = False
    Cells(1, 1) = 1
    Cells(2, 1).Formula = "=A1+1"
    Range(Range("A66000"), Range("A66000").End(xlUp)).Select
    Selection.FillDown
    Application.ScreenUpdating = True
End Sub

The following code loads the data into an array and finds the index of the number 2. It returns the correct result, 2.

Sub test()
    Dim arr As Variant
    arr = ArrayFromRange(Range("A1:A65536"))
    MsgBox Application.WorksheetFunction.Match(2, Application.Index(arr, 0, 1), 0)
End Sub

However, changing the array size causes a Type Mismatch error due to the Index function.

Sub test()
    Dim arr As Variant
    arr = ArrayFromRange(Range("A1:A65537"))
    MsgBox Application.WorksheetFunction.Match(2, Application.Index(arr, 0, 1), 0)
End Sub

How can I get around this? I’m using Excel 2007.

EDIT: I forgot to include this handy function that I’m calling

Function ArrayFromRange(rg As Range) As Variant()
'==============================================================================================
'Returns an array from a given range
'                                                                                   BG Feb 2013
'==============================================================================================

    If (rg.Cells.Count = 1) Then
        Dim arr(1 To 1, 1 To 1) As Variant
        arr(1, 1) = rg.Value
        ArrayFromRange = arr
    Else
        ArrayFromRange = rg ' Arr is now an allocated array
    End If
End Function
How to&Answers:

Since there’s a hard limit on the size of an array you can pass to WorksheetFunction.xxxx in VBA, you can instead leave the data on the sheet, and query it directly. This has the advantage of being much faster…

Sub test()
    Dim arr As Variant, v, t, i As Long
    Dim rng As Range

    Set rng = ActiveSheet.Range("A1:A65536")

    arr = rng.Value

    'array-based approach
    t = Timer
    For i = 1 To 100
        v = Application.WorksheetFunction.Match(i, Application.Index(arr, 0, 1), 0)
        If i <= 5 Then Debug.Print v
    Next i
    Debug.Print Timer - t '>> 1.55 sec

    'query worksheet directly
    t = Timer
    For i = 1 To 100
        v = rng.Parent.Evaluate("MATCH(" & i & ", INDEX(" & rng.Address() & ", 0, 1), 0)")
        If i < 5 Then Debug.Print v
    Next i
    Debug.Print Timer - t  '>> 0.008 sec

End Sub