简体   繁体   中英

Excel VBA - Find Row Number for Given Value in a Table Column

Background

I built this code a while ago and it works in one spreadsheet. It essentially gets called to find the table row number for a given value in the 1st table column. The rest of the code then uses this table row number to update the values for that row.

I recently applied the same to another spreadsheet and it was working until yesterday. Now on the line myArray = tbl.DataBodyRange I get a Run-time error '6' (Overflow). The table in the recent spreadsheet has much more data, so myArray can no longer hold the table data.

I have revised my code to search through the table rows using ListRows and then checking each value of the 1st column until I find what I am looking for.

In both routines, if the value is not found, it returns 0 and the other code knows not to attempt to update the table row.

Question

Am I likely to come across further issues with my revised approach and/or is there a more efficient way to find the row number I'm looking for. The table currently has about 700 rows of data and will grow to over 4,000 over the next few months.

Code with Overflow Error

Function getRowNum(ByVal valueToFind As String)
    Dim tbl As ListObject
    Dim myArray As Variant
    Dim x As Long
    Dim checkvalueToFind As String
    Dim rowFound As Integer
    
    rowFound = 0
    
    Set tbl = Range("table_masterList").ListObject
    
    myArray = tbl.DataBodyRange
    
    For x = LBound(myArray) To UBound(myArray)
        checkvalueToFind = myArray(x, 1)
        'Debug.Print checkvalueToFind
        If checkvalueToFind = valueToFind Then
            rowFound = x
            GoTo foundIt
        End If
    Next x
    
foundIt:
    
    Set tbl = Nothing
    getRowNum = rowFound
    
End Function

Revised Code

Function getRowNum2(ByVal valueToFind As String)
    Dim tbl As ListObject
    Dim row As ListRow
    Dim checkvalueToFind As String
    Dim rowFound As Integer
    
    rowFound = 0
    
    Set tbl = Range("table_masterList").ListObject
    
    For Each row In tbl.ListRows
        checkvalueToFind = tbl.DataBodyRange.Cells(row.Index, 1).Value
         If checkvalueToFind = valueToFind Then
            rowFound = row.Index
            GoTo foundIt
        End If
    Next row
        
foundIt:
    
    Set tbl = Nothing
    getRowNum2 = rowFound
    
End Function

Looping is over-complicating. Just use Match :

Function getRowNum(ByVal valueToFind As String) As Long
    ...
    Dim matchResult As Variant
    matchResult = Application.Match(valueToFind, tbl.ListColumns(1).DataBodyRange, 0)

    If IsError(matchResult) Then
       getRowNum = 0
    Else
       getRowNum = matchResult
    End If
End Function

Or slightly simpler:

Function getRowNum(ByVal valueToFind As String) As Long
    ...
    Dim matchResult As Variant
    matchResult = Application.Match(valueToFind, tbl.ListColumns(1).DataBodyRange, 0)

    If Not IsError(matchResult) Then
       getRowNum = matchResult
    End If
End Function

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM