简体   繁体   中英

Excel VBA search within range from previous column

I tried to implement this but I have a compiler error ("wrong qualification", or something like this, it's not an English version of Excel I have). I suppose it has to do with range / string things ?

Function SearchForTotal(givenLocation As Range, searchText As String) As Range
    Debug.Print givenLocation 'gives $U$83
    Dim startSearchFrom As String
    '-1 because it's from previous column you'll be searching in
    startSearchFrom = givenLocation.Offset(0, -1).Address
    Debug.Print startSearchFrom
    Dim i As Integer: i = startSearchFrom.Row
    Do While i > 0
        If (searchText = ThisWorkbook.Sheets("Sheet1").Range(startSearchFrom.column & i).Value) Then
            Set SearchForTotal= Range(startSearchFrom.column & i)
            Exit Do
        End If
        i = i - 1
    Loop
End Function

The error comes from the line "Dim i As Integer: i = startSearchFrom.Row"

I also tried with the variable startSearchFrom as a range instead of a string (and then with the Set) but with this code I have a compiler error too ("types do not match").

startSearchFrom.column is a number so use .Cells(rowno,colno) rather than .Range()

Option Explicit

Function SearchForTotal(givenLocation As Range, searchText As String) As Range
    
    Dim ws As Worksheet, iCol As Long, iRow As Long
    Set ws = ThisWorkbook.Sheets("Sheet1")

    '-1 because it's from previous column you'll be searching in
    iCol = givenLocation.Offset(0, -1).Column
    iRow = givenLocation.Row

    Do While iRow > 0
        If (searchText = ws.Cells(iRow, iCol).Value) Then
            Set SearchForTotal = ws.Cells(iRow, iCol)
            Exit Do
        End If
        iRow = iRow - 1
    Loop
End Function

Sub test()
    Debug.Print SearchForTotal(Range("U83"), "test").Address
End Sub

Find Value Using Loop

  • Using the Find method would certainly be a better (more efficient) way.
Option Explicit

Function SearchForTotalLoop( _
    ByVal GivenLocation As Range, _
    ByVal SearchText As String) _
As Range
    
    If GivenLocation Is Nothing Then Exit Function
    ' There's nothing to left of column `A`:
    If GivenLocation.Column = 1 Then Exit Function

    '-1 because it's from the previous column you'll be searching in
    Dim rgStart As Range: Set rgStart = GivenLocation.Offset(0, -1)
    
    Dim ws As Worksheet: Set ws = GivenLocation.Worksheet
    
    Dim r As Long: r = rgStart.Row
    Dim Col As Long: Col = rgStart.Column
    
    Do While r > 0
        If ws.Cells(r, Col).Value = SearchText Then ' A<>a
        ' To ignore case i.e. 'A = a', rather use the following:
        'If StrComp(ws.Cells(r, Col).Value, SearchText, vbTextCompare) = 0 Then
            Set SearchForTotal = ws.Cells(r, Col)
            Exit Do
        End If
        r = r - 1
    Loop

End Function

Sub SearchForTotalTEST()
    ' s - Start
    ' f - Found
    Dim sCell As Range: Set sCell = Range("B83")
    Dim fCell As Range: Set fCell = SearchForTotal(sCell, "Total")
    If fCell Is Nothing Then Exit Sub
    MsgBox "Starting Cell: " & sCell.Address & vbLf _
        & "Found Cell: " & fCell.Address & vbLf _
        & "Found Value: " & fCell.Value, vbInformation, "Find Total"
End Sub

EDIT

  • Using the Find method, you could do something like the following (not tested).
Function SearchForTotal( _
    ByVal GivenLocation As Range, _
    ByVal SearchText As String) _
As Range
    
    ' These two could be additionally used as arguments of the function.
    Const FirstRow As Long = 1
    Const ColOffset As Long = -1
    
    If GivenLocation Is Nothing Then Exit Function
    ' There's nothing to left of column `A`:
    If GivenLocation.Column + ColOffset < 1 Then Exit Function
    If FirstRow > GivenLocation.Row Then Exit Function
    
    Dim ws As Worksheet: Set ws = GivenLocation.Worksheet
    
    If GivenLocation.Column + ColOffset > GivenLocation.Columns.Count _
        Then Exit Function
    If FirstRow > GivenLocation.Rows.Count Then Exit Function
    
    Dim lCell As Range: Set lCell = GivenLocation.Cells(1).Offset(0, ColOffset)
    Dim fCell As Range: Set fCell = ws.Cells(FirstRow, lCell.Column)
    
    Dim rg As Range: Set rg = ws.Range(fCell, lCell)
    
    Dim rCell As Range
    Set rCell = rg.Find(SearchText, , xlFormulas, xlWhole, , xlPrevious)
    If rCell Is Nothing Then Exit Function
    
    Set SearchForTotal = rCell

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