In Excel VBA, the After argument in Range.Find tells Excel which single cell to search after when beginning a find. Excel starts with the next cell in the chosen search direction, and it can wrap around the range—so the cell named by After is checked only after that wraparound.
What the After argument means
After sets the starting position for a search; it does not restrict the search to cells after that position. For example, if you search down a column and set After to A5, Excel checks the next cell in the search order, then continues through the range. Once it reaches the end, it wraps to the beginning and eventually checks A5 itself.
This is why the argument can be surprising: it names the cell to search after, not the first cell to inspect. If your goal is to begin at the top-left of a range while searching forward, set After to the range’s last cell. Excel moves forward from there, wraps, and starts checking at the first cell. If you omit After, the search begins after the range’s upper-left cell.
The argument must refer to one cell inside the range being searched. Passing a cell outside that range, or a multi-cell range, is not a valid way to set the starting point.
Range.Find syntax and argument order
The method’s general form is someRange.Find(What, After, LookIn, LookAt, SearchOrder, SearchDirection, MatchCase, MatchByte, SearchFormat). In VBA, named arguments make it easier to read and reduce mistakes caused by putting optional arguments in the wrong order. A typical search explicitly sets its options:
Set result = searchRange.Find(What:="Ready", _
After:=searchRange.Cells(searchRange.Cells.Count), _
LookIn:=xlValues, LookAt:=xlWhole, _
SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, MatchByte:=False, SearchFormat:=False)
Here, searchRange.Cells(searchRange.Cells.Count) selects the last cell in the range. With a forward search, using it as After makes the search begin at the range’s first cell after wrapping. This pattern works for a rectangular range too: the last cell in the range is its bottom-right cell.
When no match exists, Find returns Nothing, so check the result before reading its address or value. The method returns a Range object when it finds something.
Example: find the first exact match
This macro searches A2:A100 on Sheet1 for a cell whose value is exactly “Ready.” It starts at the top of the range by setting After to its last cell. The example deliberately specifies the search options rather than relying on settings left over from another search.
Save a copy of the workbook before running a macro. Macros cannot be undone with Ctrl+Z. In Excel for Microsoft 365 on Windows, open the Visual Basic Editor with Alt+F11 and run the procedure from there. Excel for Mac also supports VBA, though the keyboard shortcut and editor access can differ by keyboard and Excel settings. Excel for the web cannot run VBA macros.
Sub FindFirstReady()
Dim ws As Worksheet
Dim searchRange As Range
Dim result As Range
' Set the worksheet and cells to search.
Set ws = ThisWorkbook.Worksheets("Sheet1")
Set searchRange = ws.Range("A2:A100")
' Start after the last cell so a forward search begins at the top.
Set result = searchRange.Find(What:="Ready", _
After:=searchRange.Cells(searchRange.Cells.Count), _
LookIn:=xlValues, LookAt:=xlWhole, _
SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, MatchByte:=False, SearchFormat:=False)
If result Is Nothing Then
MsgBox "No exact match was found."
Else
MsgBox "Found at " & result.Address(False, False)
End If
End Sub
LookIn:=xlValues searches the values Excel displays, while LookAt:=xlWhole requires the entire cell value to match. Thus, a cell containing “Ready for review” is not an exact match. Change LookAt to xlPart if finding “Ready” inside a longer value is intended.
Finding every match without looping forever
A single call to Find returns one match, not a collection of all matching cells. To process every match, capture the address of the first result, then use FindNext until the search returns to that address. The address check matters because Excel wraps around; without it, a loop can revisit the same results indefinitely.
This example prints the addresses of all cells containing “Ready” anywhere within their values in A2:A100. It uses the same range and search settings throughout.
Sub FindAllReady()
Dim ws As Worksheet
Dim searchRange As Range
Dim result As Range
Dim firstAddress As String
' Set the worksheet and cells to search.
Set ws = ThisWorkbook.Worksheets("Sheet1")
Set searchRange = ws.Range("A2:A100")
' Begin at the top of the range and allow partial matches.
Set result = searchRange.Find(What:="Ready", _
After:=searchRange.Cells(searchRange.Cells.Count), _
LookIn:=xlValues, LookAt:=xlPart, _
SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, MatchByte:=False, SearchFormat:=False)
If Not result Is Nothing Then
firstAddress = result.Address
Do
Debug.Print result.Address(False, False)
Set result = searchRange.FindNext(After:=result)
If result Is Nothing Then Exit Do
Loop While result.Address <> firstAddress
End If
End Sub
FindNext continues using the previous search settings, which is why it can follow the initial call without repeating every option. If you change the search criteria, start a new Find call and reset the first address for that search.
Choose the right search settings
After controls position, but other arguments determine what counts as a match and the order Excel follows. For a dependable macro, set the relevant options explicitly:
LookIn: usexlValuesto search displayed values orxlFormulasto search formula text. A formula cell can have a displayed result that differs from the formula stored in the cell.LookAt: choosexlWholefor a full-cell match orxlPartto match text within a cell.SearchOrder: choosexlByRowsto search across rows before moving down, orxlByColumnsto search down columns before moving right in a multi-cell range.SearchDirection:xlNextsearches forward in the selected order;xlPrevioussearches backward.MatchCase: set toTruefor case-sensitive text matching orFalseto ignore case.SearchFormat: set toFalsewhen formatting should not be part of the search criteria.
The meanings of “next” and “previous” depend on the search order. For a simple one-column range, the distinction is intuitive. For a rectangular range, set both arguments deliberately so the scan path is predictable.
Common After mistakes and how to fix them
- The first cell seems to be skipped. That can be expected:
Aftermarks the cell to search after, and that cell is checked only after wrapping. To start at the beginning while moving forward, setAfterto the range’s last cell. - The macro starts in an unexpected place. If
Afteris omitted, Excel uses its default starting position after the upper-left cell. Set it explicitly when the starting position matters. - The search finds a partial match. Check whether
LookAtis set toxlPart. UsexlWholewhen the entire cell must match. - The result differs from what the Find dialog showed. Excel retains several Find settings, and VBA’s
Findmethod shares settings with the Find dialog. Specify arguments such asLookIn,LookAt, andSearchOrderon every call rather than assuming their current values. - The macro errors when there is no match. A missing result is
Nothing. Test for that before using properties such asAddressorValue. - The loop repeats results. Searches wrap around. Save the first result’s address and stop when the search reaches it again.
Also check that the After cell belongs to the exact range on which Find is called. If the range is A2:A100, for example, A1 is not a valid starting cell for that call. Set the range and the start cell from the same range object to avoid a mismatch.
After compared with FindNext and Offset
After is an argument to Find; it establishes where that search starts. FindNext is a separate method for continuing a prior search. It advances to another match using the previous search criteria, and it wraps around just like a Find search. Use it with a first-address stopping check when iterating through results.
Offset, by contrast, refers to a cell at a relative row or column distance from another cell. It does not search for content. For example, getting the cell one row below a match is a navigation operation; using After tells Excel where to begin looking for the next matching value. These tools can be combined, but they solve different problems.
Another common misconception is that After:=A5 means “search only below A5.” It does not. The search still covers the specified range and wraps. If you need to search only below a certain row, define a smaller range containing only those cells, then use an After cell inside that smaller range.
When to use a different search approach
Use Range.Find when VBA needs to locate a matching cell while honoring Excel-style options such as partial matching, formula-versus-value searching, or search direction. It is especially useful when the range is large and you want to jump directly to matches rather than inspect every cell individually.
For a small, fixed range, a loop through each cell may be easier to understand when the match condition is more complex than a text search. For example, a loop can test several columns together or apply custom conditions to dates and numbers. However, looping cell by cell can be slower on large ranges, and it requires writing and maintaining the comparison logic yourself. Choose based on the condition and the size of the data, not simply because one method looks shorter.
Frequently Asked Questions
Does After include the cell I specify?
Not at the start. Excel searches after that cell in the chosen direction, then checks the specified cell only if the search wraps back around.
How do I make Find start at the first cell?
For a forward search, set After to the last cell of the range. Excel wraps from that position and begins with the range’s first cell.
Can After point to a cell outside the search range?
No. The After argument must be a single cell contained in the range used for Find.
Why does Find return Nothing even though I can see the text?
Check whether the macro searches values or formulas, whether LookAt requires a whole-cell match, and whether the text has different spaces or characters. Also confirm that the visible cell is inside the searched range.
Does Find After work in Excel for the web?
VBA code does not run in Excel for the web. Use desktop Excel for Microsoft 365 on Windows or Mac to run VBA macros; the Range.Find logic is VBA code for the desktop app.
Related
- Protect Excel Sheets in Teams: What It Does and How
- Python Goal Seek Like Excel? Methods and Examples
- Power BI Compare Two Excel Sheets: A Practical Guide
Try it: the Column Letter to Number: aA is 27, XFD is 16,384. Converts both ways.
More in VBA & macros
- Excel VBA vs Power Query: Key Differences and When to Use EachUse Power Query when the main job is importing, cleaning, combining, and reshaping data that you will refresh;…
- Outlook Excel VBA: Automate Email and Calendar TasksYes—Excel VBA can automate classic Outlook for Windows, including creating email drafts from spreadsheet rows and working with…
- VBA Delete Row If Cell Is Blank: Safe MethodsTo delete rows when a cell in a chosen column is blank, loop through the data from the…
- VBA Range Is Nothing? Meaning, Checks, and Common FixesIn Excel VBA, a Range is Nothing when an object variable does not currently refer to a range…
- Macro Recorder for Windows 11: Options That Actually WorkWindows 11 does not include a universal built-in macro recorder that can record and replay actions across every…
- Excel Range Find VBA: Search Cells ReliablyIn Excel VBA, use the Range.Find method to search a specified range; check whether it returned a cell…
Sources: Function behaviour and menu paths: Microsoft Support documentation for Excel. Method & sources
Spotted an error in this guide? Let us know.