How to Get Last Match Cell Contains in Excel

Learn multiple Excel methods to get the last matching cell that contains specific text, with step-by-step examples and practical applications.

excelformulaspreadsheettutorial
10 min read • Last updated: 7/2/2025

How to Get Last Match Cell Contains in Excel

Why This Task Matters in Excel

Data lists rarely stay static. As rows are appended over time—daily sales, weekly inventory receipts, running meeting notes, or help-desk tickets—the most recent row is often the one decision-makers care about first. Imagine:

  • A sales manager reviews the last order that contains the SKU “XL-RED” to verify discounting.
  • A service supervisor checks the most recent ticket description that contains the phrase “error 105” to see if it was resolved.
  • A project analyst needs the latest status update containing the word “delayed” to raise an escalation.

In each case, only rows that contain a target word or partial code matter, and only the last such row is significant. Manually scrolling through thousands of lines is not feasible; Excel must identify that row instantly whenever new data arrives.

Excel is perfectly suited for this because:

  1. It holds large, append-only lists that grow continuously—think transaction logs or IoT sensor dumps.
  2. It offers powerful lookup engines (LOOKUP, XLOOKUP, FILTER, INDEX/MATCH) able to traverse entire ranges in milliseconds.
  3. Excel formulas recalculate automatically, so the “last match” updates the moment new rows appear—ideal for dashboards and alerts.

Failing to master this skill leads to stale KPIs, missed deadlines, or wrong pricing. Even advanced users sometimes mistake “largest row number” with “last match,” especially when blanks and partial text are involved. Knowing the proper pattern protects you from such traps and ties into broader competencies: dynamic named ranges, error-proof dashboards, and advanced text analysis.

Best Excel Approach

The fastest, most flexible technique works in all modern Excel versions and requires no Dynamic Array support:

=LOOKUP(2,1/(ISNUMBER(SEARCH($F$1,$A$2:$A$1000))),$A$2:$A$1000)

How it works:

  • SEARCH($F$1,$A$2:$A$1000) scans each cell for the substring typed in F1.
  • ISNUMBER(...) converts found positions to TRUE/FALSE.
  • Dividing 1 by TRUE/FALSE coerces TRUE to 1 and FALSE to a #DIV/0! error.
  • LOOKUP(2,1/...) exploits the fact that LOOKUP ignores errors and seeks the largest numeric value less than or equal to 2, effectively the last 1 in the array.
  • The third argument ($A$2:$A$1000) returns the corresponding cell’s content.

When you have Microsoft 365, the approach becomes simpler and more readable with XLOOKUP because of its built-in search mode:

=XLOOKUP("*"&$F$1&"*",$A$2:$A$1000,$A$2:$A$1000,,0,-1)

Key arguments:

  • Lookup value: "*"&$F$1&"*" enables wildcard contains.
  • Lookup array: the data column.
  • Return array: same as lookup array (return full cell).
  • If not found: blank.
  • Match mode: 0 (wildcards allowed).
  • Search mode: -1 (search last-to-first).

Use LOOKUP when you need backward compatibility with Excel 2010-2013, use XLOOKUP when speed and readability matter, and use FILTER plus TAKE (365 only) when you want to return entire rows, not just one cell.

Parameters and Inputs

  • Search Text (single cell) – usually in a driver cell like F1. Accepts numbers, words, or part numbers.
  • Data Range (single column) – ideally a fixed column [A2:A1000] or a structured column like Table1[SKU]. Must be of consistent data type (text).
  • Return Range (single column) – often identical to Data Range, but could be another column if you want to return, say, a price instead of the matched description.
  • Optional Wildcard Setting (XLOOKUP only) – Match mode 0 to allow asterisks and question marks.
  • Range Size – bigger ranges slow down SEARCH. Limit it with dynamic last-row detection or convert to an Excel Table so ranges resize automatically.
  • Data Preparation – trim extra spaces with TRIM, force consistent case if using FIND (case-sensitive).
  • Edge Cases – empty search string, empty data range, cells with errors, multiple matches but none containing the text. Include IFERROR or IFNA to trap problems.

Step-by-Step Examples

Example 1: Basic Scenario

Suppose you track project milestones in column A. New updates are appended daily. You want the latest note that mentions “overdue.”

Sample data (rows 2-11):
[A]
Project kickoff complete
Budget approved
Risk flagged – overdue by two days
Milestone 1 complete
Design review scheduled
Testing overdue – awaiting resources
Milestone 2 complete
Overdue tasks escalated
Final review done
Launch approved

  1. Type the word overdue in cell F1.
  2. Enter this formula in cell G1:
=LOOKUP(2,1/(ISNUMBER(SEARCH($F$1,$A$2:$A$100))),$A$2:$A$100)
  1. Press Enter. The result is “Overdue tasks escalated”—the last cell in [A] that contains “overdue.”

Why it works: SEARCH returns positions of “overdue” (case-insensitive). Only the rows with “Testing overdue ...” and “Overdue tasks escalated” return numbers. LOOKUP picks the last numeric hit.

Troubleshooting:

  • If F1 is blank, SEARCH returns 1 in every row (because empty string exists everywhere), and LOOKUP returns the last cell of the range. Mitigate by wrapping the whole formula in IF(F\1=\"\",\"\",…).

Variations:

  • Switch to FIND for case-sensitive searches.
  • Lock rows with the $ sign if copying formula sideways.

Example 2: Real-World Application

Scenario: You maintain a help-desk log in a structured table named Tickets. Column State holds status values: “Open,” “In Progress,” “Closed,” plus descriptive comments. You need the latest entry containing “error 105” and want to bring back the entire ticket row into a dashboard.

  1. In G2, store the keyword error 105.
  2. Fetch the row number:
=AGGREGATE(14,6,ROW(Tickets[State])/(ISNUMBER(SEARCH($G$2,Tickets[State]))),1)

Explanation: AGGREGATE function 14 returns LARGE, option 6 ignores errors. It returns the maximum row number where SEARCH is numeric, effectively the last match.

  1. Return the full row with INDEX:
=INDEX(Tickets[#All],$G$3,)   'assuming the AGGREGATE output is in G3
  1. Alternatively, if on Microsoft 365, combine FILTER and TAKE in a single step:
=TAKE(FILTER(Tickets,ISNUMBER(SEARCH($G$2,Tickets[State]))),-1)

The dashboard now displays every column of the last ticket containing “error 105” (ticket ID, client, priority, owner, etc.). Because FILTER returns an array, spill formatting can highlight the row, and charts can reference those spill cells.

Performance: On a 30 000-row table, this dynamic array solution recalculates nearly instantly because modern Excel leverages multi-threading.

Example 3: Advanced Technique

Suppose your dataset spans multiple years of point-of-sale transactions stored in column pairs: A – DateTime, B – Description, C – Amount, repeating every month in separate sheets. You need the last transaction description containing “refund” across all worksheets for monthly compliance reports.

Approach:

  1. Create a named range wsList that lists the worksheet names in [Z2:Z13].
  2. Enter keyword refund in H1.
  3. Use LET plus REDUCE (365) to iterate through every sheet:
=LET(
  keyword,$H$1,
  sheets,wsList,
  result,
    REDUCE("",sheets,
      LAMBDA(acc,sh,
        LET(
          rng,INDIRECT("'"&sh&"'!B2:B10000"),
          last,LOOKUP(2,1/(ISNUMBER(SEARCH(keyword,rng))),rng),
          IF(last<>"",last,acc)
        )
      )
    ),
  result
)

Explanation:

  • REDUCE loops through each sheet.
  • acc keeps the latest match encountered so far.
  • LOOKUP finds the last match within one sheet.
  • If a sheet has no match, acc retains the previous value.
  • The final output is the last description containing “refund” across all sheets.

Edge Cases handled: missing sheets, empty ranges, or no match anywhere returns a blank string. Wrap with IF(result=\"\",\"No refund found\",result) for user feedback.

Tips and Best Practices

  1. Convert raw data to an Excel Table—ranges auto-expand, formulas require no manual range edits.
  2. Store the search term in a dedicated driver cell and protect it with Data Validation to block blanks.
  3. When performance lags on 100 000+ rows, replace SEARCH with FIND if case matters or with TEXTSPLIT pre-processing to limit substring scans.
  4. Avoid volatile functions like INDIRECT in large workbooks unless paired with LET or LAMBDA caching.
  5. Combine the last-match formula with conditional formatting to visually flag the entire row, aiding quick audits.
  6. Document every lookup range in a “Definitions” sheet—future editors know exactly what the formula refers to.

Common Mistakes to Avoid

  1. Using MAX(IF(...)) without handling errors – MAX ignores errors only in AGGREGATE mode; basic MAX chokes on #VALUE!. Wrap arrays with IFERROR or use AGGREGATE option 6.
  2. Forgetting absolute references – If $A$2:$A$1000 shifts while dragging formulas, results become unpredictable. Anchor the range with $ signs or use structured references.
  3. Blank search string – When the driver cell is empty, the formula matches every row and returns the last cell in the range, which is rarely the intent. Insert IF(search=\"\",\"\",formula).
  4. Wrong wildcard placement in XLOOKUP"*"&F1&"*" is mandatory for “contains.” Omitting asterisks forces exact matches and returns #N/A.
  5. Overusing volatile functions – INDIRECT and OFFSET recalculate constantly, slowing large models. Prefer INDEX or structured references whenever possible.

Alternative Methods

MethodWorks in VersionsSyntax ComplexityReturnsProsCons
LOOKUP with 1/division2007+MediumSingle cellBackward compatible, fastHarder to read, array logic needed
XLOOKUP with search mode -1365 / 2021LowSingle cellIntuitive, wildcard built-inNot in older versions
FILTER + TAKE365LowEntire row(s)Spill dynamic arrays, easy to expandRequires 365
AGGREGATE + INDEX2010+HighEntire row(s)Works pre-365, good for tablesTwo-step, more typing
Power Query2016+GUITableNot formula-based, refreshableRequires refresh action, slower for real-time

Use the LOOKUP trick for universal compatibility, XLOOKUP for simplicity, FILTER when you need the entire record, and Power Query when pre-processing is acceptable and real-time updates are unnecessary.

FAQ

When should I use this approach?

Anytime you append rows chronologically and care about the most recent record containing certain text: sales, logs, audit trails, or tracking sheets.

Can this work across multiple sheets?

Yes. Use INDIRECT or, better, REDUCE with INDIRECT in 365 to loop through sheet names, or consolidate data in Power Query and then run the last-match formula on the merged table.

What are the limitations?

LOOKUP ignores errors but not blanks in the 1/division trick. XLOOKUP requires 365 or 2021. SEARCH is case-insensitive; if you need case sensitivity, swap with FIND.

How do I handle errors?

Wrap the formula in IFNA or IFERROR:

=IFNA( XLOOKUP(...), "No match" )

For LOOKUP, nest inside IFERROR after the lookup call.

Does this work in older Excel versions?

LOOKUP and AGGREGATE methods work in 2007+. XLOOKUP, FILTER, TAKE, REDUCE, LET are only available in Microsoft 365 and Excel 2021.

What about performance with large datasets?

Keep ranges to the minimum rows needed. Convert to Tables so formulas avoid full-column references like A:A. Consider helper columns storing the SEARCH result so heavy text scanning happens only once.

Conclusion

Mastering “get last match cell contains” unlocks a real-time lens into your ever-growing lists. Whether you rely on universal LOOKUP tricks or modern XLOOKUP/FILTER elegance, the ability to instantly pull the newest relevant record keeps reports accurate, dashboards current, and decisions swift. Combine these patterns with data-cleaning habits and structured tables to scale effortlessly. Continue exploring LET, LAMBDA, and dynamic arrays to push your automation even further—Excel is ready when you are.

We use tracking cookies to understand how you use the product and help us improve it. Please accept cookies to help us improve.