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) Else Debug.Print("not found (EF1)") Return Nothing End If End Function
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 Loop cl = cl + 1 Loop 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
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 Next
s = Replace(s, " ", "")
before you look for it. This removes any blanks from variable s