Excel VBA Find

If you just need to excel vba find and move on, the boxed answer at the top is all you need. The rest of this page is for when you want to understand why it works in Excel, adapt it to a trickier version, or make it robust enough to hand to a colleague. We keep the opening short on purpose — the depth is here when you want it, not in your way when you don’t.

Exact answer

In Excel: Set hit = ws.Cells.Find(What:="text", LookIn:=xlValues, LookAt:=xlPart) locates the first match, and ws.Cells.Replace What:="old", Replacement:="new" changes them all in one call.

VBA macro: Find and Replace with VBA

Sub FindAndReplaceInSheet()
    Dim ws As Worksheet
    Dim hit As Range
    Set ws = ActiveSheet
    Set hit = ws.Cells.Find(What:="draft", LookIn:=xlValues, _
                            LookAt:=xlPart, MatchCase:=False)
    If hit Is Nothing Then
        MsgBox "Nothing to replace.", vbExclamation
        Exit Sub
    End If
    MsgBox "First match: " & hit.Address, vbInformation
    ws.Cells.Replace What:="draft", Replacement:="final", _
                     LookAt:=xlPart, MatchCase:=False
End Sub

Range.Find returns Nothing rather than raising an error when there is no match, so the If hit Is Nothing guard is required — using .Address on Nothing is error 91. Always name LookIn, LookAt and MatchCase explicitly; unset arguments inherit whatever the user last chose in the Find dialog.

How to run this macro

  1. Press Alt + F11 to open the VBA editor.
  2. Insert > Module.
  3. Paste the code above.
  4. Press F5, or close the editor and run it from Developer > Macros.
  5. Save the file as .xlsm so the macro is kept.
Annotated stepsExcel
1

Decide whether you need the location of matches (Find) or just to change them (Replace).

2

For Find, assign the result with Set and name What, LookIn, LookAt and MatchCase explicitly.

3

Guard immediately with If hit Is Nothing Then — a miss returns Nothing, not an error.

4

To visit every match, save the first hit's Address and loop with FindNext until the address comes round again.

5

For a bulk change, call Range.Replace once on the whole range instead of looping — it is dramatically faster.

Ctrl+CthenCtrl+Shift+V+Cthen+Ctrl+VPaste values · WindowsMac

What this does

VBA offers three related tools and they solve different problems. Range.Find locates a value and hands back the cell as a Range object, or Nothing when there is no match — it tells you where something is. Range.Replace changes every match in the target range in a single call and returns only True or False; it is far faster than looping when you do not need to know which cells changed. FindNext continues a search from a previous hit, and the correct way to iterate is to remember the address of the first result and stop when the search wraps back round to it, since Find loops the range endlessly otherwise. Separately, VBA's own Replace() function works on a string rather than a sheet: Replace(text, "a", "b") returns a modified copy and never touches a cell, which is what you want inside a loop over values you have already read. The single biggest trap is that Find's unspecified arguments persist from the last search anyone performed, including one a user did through the dialog — so a macro that omits LookIn behaves differently depending on the session. Keep the inputs visible and clearly labelled and the whole thing stays auditable — anyone who opens the file later, including you, can see at a glance exactly what feeds the result and change one assumption without hunting through the formula. Treat “excel vba find” as a small repeatable workflow rather than a one-off click you hope to remember next time. Use a small test block before the live file, so any surprise in the affected cells shows up while it is still harmless. When this is a ribbon command, the selection matters more than the button: confirm the range, apply the command, then spot-check the output before saving. That turns a workflow that saves repeating the same clicks every week into a method you can reuse, explain, and defend when the workbook leaves your screen.

A worked example

A sheet full of records is marked "DRAFT" in mixed positions and casing, and every one should read "FINAL". Sub FindAndReplaceInSheet() first calls Find to confirm at least one match exists and reports its address, then calls Replace once to change them all. The If hit Is Nothing guard is what stops the macro dying on the .Address line when the sheet is already clean. When you need to act on each match rather than just rewrite it — say, colouring every cell containing "draft" — use the FindNext pattern: store firstAddress = hit.Address, do the work, then Set hit = ws.Cells.FindNext(hit) and loop while Not hit Is Nothing And hit.Address <> firstAddress. Without that address comparison the loop never ends, because Find wraps around to the beginning of the range. Find and Replace is where macros meet messy real data — inconsistent labels, stray markers, values that need normalising before anything else can run. The two behaviours worth internalising are that a miss returns Nothing rather than erroring, and that omitted arguments are inherited rather than defaulted; between them they account for most of the bug reports this pair of methods generates. If there is any chance you will reuse this, drop it into a small template tab right now: a labelled input area on the left and the formula beside it, checked once against the tool above. Next time the same question comes up, the answer is a single paste away instead of a rebuild from memory.

In Google Sheets

If you are in Google Sheets rather than Excel, the good news is that the formula shown here is identical and the workflow barely changes — menus sit across the top instead of in a ribbon, and a few function names differ slightly, but anything you build here moves across with little or no rework. The aim was to get you unstuck fast and leave you a little more capable than a copy-paste would. The answer is at the top, the tool proves it, and the detail above shows why it holds — so the next time a colleague asks, you can answer without reaching for search. The short version of “excel vba find”: the answer is at the top of this page, the tool proves it on your own numbers, and the sections above explain why it holds so the next variation does not stump you. Excel rewards people who reference cells instead of typing values and who keep inputs separate from formulas, because that is what makes a result you can audit months later. Build it once, deliberately, with the live tool as a check, and you convert a one-off lookup into a reusable skill — which is the whole point of learning the why and not just the what.

Common mistakes

  • Using the result of Find without checking for Nothing. Any property access on Nothing raises error 91, and a sheet that simply has no match is the normal case, not an exceptional one.
  • Leaving LookIn and LookAt unspecified. Those arguments persist between searches — including from the user's last use of Ctrl + F — so the same macro can match whole cells one day and partial text the next.
  • Looping FindNext without tracking the first address. The search wraps around at the end of the range, so the loop runs forever; comparing against the stored first address is the standard termination test.
  • Searching with LookIn:=xlValues when you meant formulas. xlValues sees displayed results, xlFormulas sees the underlying text, so a macro hunting for a cell reference must use the latter.
  • Confusing Range.Replace with VBA's Replace() function. The first edits cells on a sheet, the second returns a modified string and changes nothing — using the wrong one produces code that appears to do nothing at all.

Frequently asked questions

Why does my Find raise error 91?

Because it found nothing and returned Nothing, and the next line asked it for a property. Test If hit Is Nothing Then before touching the result — that branch is not optional.

How do I loop through every match?

Save the first hit's Address, act on it, then Set hit = rng.FindNext(hit) and repeat while the address differs from the saved one. Find wraps at the end of the range, so that comparison is what ends the loop.

Is Replace faster than looping over cells?

Considerably. Range.Replace performs the whole operation inside Excel in one call, while a loop crosses the VBA-to-Excel boundary once per cell. Loop only when each match needs different handling.

How do I search only part of a cell rather than the whole value?

Pass LookAt:=xlPart. LookAt:=xlWhole requires the entire cell to equal the search text. Always state it explicitly, because the unset value carries over from the previous search.

Other ways people ask this

On the way here you may have searched this as “find in vba excel”, “how to find macros in excel”, “excel vba selection find” and “find vba excel” — it is all the same task, and this page is the single, complete answer to it.

This guide also answers

  • excel vba search

Why do people search for this in so many different ways?

Because the same task has many names. “find in vba excel”, “how to find macros in excel”, “excel vba selection find” all point at the one operation explained on this page, which is why they all lead here.