Home » excel » vb.net – More control over XlFind

vb.net – More control over XlFind

Posted by: admin April 23, 2020 Leave a comment


I’m using a script to allow users to find a serialnumber in a column of an excel sheet. A problem however is the flexibility of the search.

The serialnumbers may occur as the following examples: “12345678      “, “1 345678        “, “12 345678    ” as you see, there are a varying number of spaces after the numbers which are causing problems. Additionally, the first two (or occasionally single) digits show the year of the serial number, and may or may not be separated by a space.

Is there any way to account for these variations without having to perform multiple searches or adjust the data?

Private Function ExcelFind(r As Excel.Range, s As String)
    Dim currentFind As Excel.Range = Nothing
    currentFind = r.Find(s, ,
Excel.XlFindLookIn.xlValues, Excel.XlLookAt.xlPart,
Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlNext, False)

    If currentFind IsNot Nothing Then
        Debug.Print("foundrow " & currentFind.Row)
        Debug.Print("foundcol " & currentFind.Column)
        Return (currentFind)
        Debug.Print("not found (EF1)")
        Return Nothing
    End If
End Function
How to&Answers:

Alright, an approach using an array to check against – This will be a lot faster than checking against each cell with as in Maddy Nikam’s answer.
I did a run against A1:AN10000 and that took around 3 seconds. Still not optimal, but more workable than checking against the full range cell by cell.

Sub test(r As Excel.Range, s As String)
Dim arr() As Variant
Dim cl as long
Dim rw as long

arr = r.value

cl = 1
Do While cl <= r.Columns.Count
    rw = 1
    Do While rw <= r.Rows.Count
        arr(rw, cl) = Replace(arr(rw, cl), " ", "")
        If arr(rw, cl) = s Then
            Debug.Print r.Cells(rw, cl).Address
        End If
        rw = rw + 1
    cl = cl + 1
End Sub

Edit: I’m assuming r will be a continuous range with this approach. If it’s not you’ll run into trouble with the addresses.
For example calling this with Set rng = Union(Range("A1:A3"), Range("B5:B7")) and passing rng to r, the only found addresses by Debug.Print will be A1:A3, whereas a Debug.Print(rng.Address) will tell you $A$1:$A$3,$B$5:$B$7


Try like this

    For Each cell In Rng
    Str = cell.Value
    Str = Replace(Str, " ", "")
        If s = Str Then
            Debug.Print ("foundrow " & cell.Row)
            Debug.Print ("foundcol " & cell.Column)
        End If



s = Replace(s, " ", "")

before you look for it. This removes any blanks from variable s