Tìm Kiếm Và Sử Dụng Hàm Find Trong Vba Excel: Hướng Dẫn Chi Tiết Từ Cơ Bản Đến Nâng Cao

Mở đầu

Trong môi trường làm việc với Excel, việc tìm kiếm dữ liệu nhanh chóng và chính xác là một nhu cầu thường xuyên gặp phải. Dù bạn đang xử lý một bảng tính nhỏ hay một dự án lớn với hàng ngàn dòng dữ liệu, việc nắm vững cách sử dụng hàm Find trong VBA (Visual Basic for Applications) sẽ giúp bạn tiết kiệm thời gian và tăng hiệu suất công việc đáng kể. Bài viết này sẽ cung cấp cho bạn một hướng dẫn chi tiết, từ những kiến thức cơ bản nhất về hàm Find, cách khai thác các tham số quan trọng, cho đến các kỹ thuật nâng cao và các ví dụ thực tế trong công việc hàng ngày.

1. Giới thiệu tổng quan về hàm Find trong VBA

1.1. Hàm Find là gì?

Find là một phương thức (method) của đối tượng Range trong Excel VBA. Nó cho phép bạn tìm kiếm một giá trị (hoặc mẫu) trong một phạm vi ô (range) và trả về một đối tượng Range đại diện cho ô đầu tiên chứa giá trị phù hợp. Khi sử dụng đúng, hàm này có thể thay thế hoàn toàn chức năng Ctrl + F trong giao diện người dùng, đồng thời cung cấp khả năng lập trình linh hoạt hơn.

1.2. Lợi ích khi dùng Find trong VBA

Lợi íchMô tả
Tự động hoáLoại bỏ việc phải tìm kiếm thủ công, giảm lỗi người dùng.
Tốc độSo với việc duyệt từng ô bằng vòng lặp For Each, Find nhanh hơn nhiều, đặc biệt với dữ liệu lớn.
Linh hoạtHỗ trợ tìm kiếm theo nhiều tiêu chí: toàn bộ nội dung, một phần, chữ hoa/thường, biểu thức chính quy (via Like).
Kết hợp với các hàm khácDễ dàng tích hợp với Offset, Resize, EntireRow, EntireColumn để thực hiện các thao tác phức tạp.

2. Cú pháp cơ bản của hàm Find

RangeObject.Find(What, After, LookIn, LookAt, SearchOrder, SearchDirection, MatchCase, MatchByte, SearchFormat)
  • RangeObject: Đối tượng Range mà bạn muốn thực hiện tìm kiếm (ví dụ: Sheets("Sheet1").Range("A1:D100")).
  • What: Giá trị hoặc chuỗi cần tìm (bắt buộc).
  • After (Optional): Ô bắt đầu tìm kiếm sau ô này. Mặc định là ô đầu tiên trong RangeObject.
  • LookIn (Optional): Xác định phần nào của ô được tìm kiếm (xlFormulas, xlValues, xlComments).
  • LookAt (Optional): Xác định cách so sánh (xlWhole – toàn bộ nội dung, xlPart – một phần).
  • SearchOrder (Optional): Thứ tự tìm kiếm (xlByRows hoặc xlByColumns).
  • SearchDirection (Optional): Hướng tìm kiếm (xlNext – từ trên xuống dưới, xlPrevious – ngược lại).
  • MatchCase (Optional): True nếu phân biệt chữ hoa/thường.
  • MatchByte (Optional): Dành cho ngôn ngữ có ký tự đôi byte (đại đa số không cần dùng).
  • SearchFormat (Optional): True nếu muốn tìm kiếm dựa trên định dạng ô (màu nền, font, …).

Lưu ý: Nếu hàm không tìm thấy giá trị, nó trả về Nothing. Vì vậy, luôn kiểm tra kết quả trước khi thao tác tiếp.

3. Ví dụ cơ bản: Tìm một giá trị trong một cột

Giả sử bạn có một danh sách khách hàng trong cột A và muốn tìm vị trí của khách hàng “Nguyễn Văn A”.

Sub TimKhachHang() Dim ws As Worksheet Dim rngSearch As Range Dim rngFound As Range Dim strName As String Set ws = ThisWorkbook.Sheets("KhachHang") Set rngSearch = ws.Range("A:A") ' Tìm trong toàn cột A strName = "Nguyễn Văn A" Set rngFound = rngSearch.Find(What:=strName, _ LookIn:=xlValues, _ LookAt:=xlWhole, _ SearchOrder:=xlByRows, _ SearchDirection:=xlNext, _ MatchCase:=False) If Not rngFound Is Nothing Then MsgBox "Tìm thấy tại ô " & rngFound.Address & vbCrLf & _ "Hàng: " & rngFound.Row Else MsgBox "Không tìm thấy khách hàng " & strName End If
End Sub

Giải thích:
– LookIn:=xlValues cho phép tìm kiếm trong giá trị hiển thị của ô, không phải công thức.
– LookAt:=xlWhole yêu cầu khớp toàn bộ nội dung ô.
– Khi tìm thấy, rngFound sẽ chứa tham chiếu tới ô chứa “Nguyễn Văn A”.

4. Tìm kiếm nhiều kết quả: Vòng lặp Find Next

Trong thực tế, một giá trị có thể xuất hiện nhiều lần. Để liệt kê tất cả các vị trí, bạn cần sử dụng vòng lặp Do...Loop kết hợp với FindNext.

Sub TimTatCaGiaTri() Dim ws As Worksheet Dim rngSearch As Range Dim rngFirst As Range Dim rngFound As Range Dim strSearch As String Dim sResult As String Set ws = ThisWorkbook.Sheets("Data") Set rngSearch = ws.Range("B2:B200") strSearch = "Hà Nội" Set rngFound = rngSearch.Find(What:=strSearch, _ LookIn:=xlValues, _ LookAt:=xlPart, _ SearchOrder:=xlByRows, _ SearchDirection:=xlNext, _ MatchCase:=False) If Not rngFound Is Nothing Then Set rngFirst = rngFound ' Lưu ô đầu tiên để so sánh sau Do sResult = sResult & rngFound.Address & vbCrLf Set rngFound = rngSearch.FindNext(rngFound) Loop While Not rngFound Is Nothing And rngFound.Address <> rngFirst.Address MsgBox "Các ô chứa '" & strSearch & "':" & vbCrLf & sResult Else MsgBox "Không tìm thấy giá trị '" & strSearch & "'." End If
End Sub

Điểm quan trọng:
– FindNext nhận đối tượng Range hiện tại và trả về kết quả tiếp theo.
– Khi rngFound quay lại ô đầu tiên, vòng lặp dừng để tránh vòng lặp vô hạn.

5. Tham số LookIn và LookAt: Khi nào dùng xlFormulas vs xlValues?

Tham sốMô tảKhi dùng
xlValuesTìm kiếm trong giá trị hiển thị (đã được Excel tính toán).Khi dữ liệu đã được nhập sẵn, không quan tâm tới công thức.
xlFormulasTìm kiếm trong công thức gốc của ô.Khi muốn tìm công thức cụ thể, ví dụ “=SUM(A1:A10)”.
xlWholeSo sánh toàn bộ nội dung ô.Khi bạn cần khớp chính xác.
xlPartSo sánh một phần nội dung.Khi tìm kiếm một chuỗi con, ví dụ “Hà” trong “Hà Nội”.

Ví dụ thực tế:
Bạn có cột chứa công thức =VLOOKUP(A2,Table,2,FALSE). Để tìm những ô đang dùng hàm VLOOKUP, bạn sẽ đặt LookIn:=xlFormulas và What:="VLOOKUP".

Set rngFound = ws.Range("C:C").Find(What:="VLOOKUP", LookIn:=xlFormulas, LookAt:=xlPart)

6. Tìm kiếm không phân biệt chữ hoa/thường (MatchCase)

Mặc định, Find không phân biệt chữ hoa/thường (MatchCase:=False). Nếu bạn muốn phân biệt, chỉ cần đặt MatchCase:=True.

Set rngFound = rngSearch.Find(What:="ABC", MatchCase:=True)

Trong trường hợp dữ liệu có sự khác biệt về chữ hoa/thường và bạn cần phân biệt, việc này rất hữu ích (ví dụ: mã sản phẩm “ABc123” vs “abc123”).

7. Tìm kiếm dựa trên định dạng (SearchFormat)

Bạn có thể tìm các ô có định dạng đặc biệt, ví dụ: màu nền vàng. Đầu tiên, cần thiết lập một ô mẫu có định dạng mong muốn, sau đó sử dụng SearchFormat:=True.

Sub TimTheoMauNen() Dim ws As Worksheet Dim rngSearch As Range Dim rngFound As Range Dim rngFormat As Range Set ws = ThisWorkbook.Sheets("Report") Set rngSearch = ws.UsedRange ' Ô mẫu: A1 đã được tô màu vàng Set rngFormat = ws.Range("A1") Application.FindFormat.Clear rngFormat.Copy Application.FindFormat.Interior.Color = rngFormat.Interior.Color Set rngFound = rngSearch.Find(What:="", _ LookIn:=xlFormulas, _ LookAt:=xlPart, _ SearchOrder:=xlByRows, _ SearchDirection:=xlNext, _ MatchCase:=False, _ SearchFormat:=True) If Not rngFound Is Nothing Then MsgBox "Ô đầu tiên có nền màu vàng: " & rngFound.Address Else MsgBox "Không tìm thấy ô nào có nền màu vàng." End If Application.FindFormat.Clear ' Reset
End Sub

Chú ý: Khi dùng SearchFormat, luôn xóa cấu hình tìm kiếm (Application.FindFormat.Clear) sau khi hoàn thành để tránh ảnh hưởng tới các tìm kiếm sau.

Find Function In Vba Excel
Find Function In Vba Excel

8. Xử lý trường hợp không tìm thấy (Nothing)

Nếu không có kết quả, hàm Find trả về Nothing. Việc không kiểm tra Nothing sẽ gây lỗi “Object variable or With block variable not set”. Thực hành tốt:

If rngFound Is Nothing Then ' Xử lý khi không có kết quả
Else ' Tiếp tục xử lý khi có kết quả
End If

9. Kỹ thuật nâng cao

9.1. Tìm kiếm trong nhiều sheet cùng lúc

Bạn có thể lặp qua tất cả các sheet và thực hiện tìm kiếm trên mỗi sheet:

Sub TimTrenTatCaSheet() Dim wb As Workbook Dim ws As Worksheet Dim rngFound As Range Dim strKey As String Dim sMsg As String Set wb = ThisWorkbook strKey = "2026" For Each ws In wb.Worksheets Set rngFound = ws.UsedRange.Find(What:=strKey, LookIn:=xlValues, LookAt:=xlPart) If Not rngFound Is Nothing Then sMsg = sMsg & ws.Name & " – " & rngFound.Address & vbCrLf End If Next ws If sMsg <> "" Then MsgBox "Tìm thấy trong các sheet:" & vbCrLf & sMsg Else MsgBox "Không tìm thấy '" & strKey & "' trong workbook." End If
End Sub

9.2. Tìm kiếm dựa trên biểu thức chính quy (Regular Expression) – Kết hợp với VBA

Excel VBA không hỗ trợ regex trực tiếp trong Find, nhưng bạn có thể dùng đối tượng RegExp trong thư viện Microsoft VBScript Regular Expressions 5.5 để lọc kết quả:

Sub TimBangRegex() Dim ws As Worksheet Dim rng As Range, cell As Range Dim regEx As Object Dim pattern As String Dim sResult As String Set ws = ThisWorkbook.Sheets("Data") Set rng = ws.Range("A2:A500") pattern = "^\d{3}-A-Z{2}$" ' Ví dụ: 123-AB Set regEx = CreateObject("VBScript.RegExp") regEx.Pattern = pattern regEx.IgnoreCase = True For Each cell In rng If Not IsError(cell.Value) Then If regEx.Test(cell.Value) Then sResult = sResult & cell.Address & ": " & cell.Value & vbCrLf End If End If Next cell If sResult <> "" Then MsgBox "Các ô phù hợp:" & vbCrLf & sResult Else MsgBox "Không có ô nào khớp regex." End If
End Sub

9.3. Tìm kiếm nhanh trong mảng (Array) – Khi dữ liệu quá lớn

Khi làm việc với hàng chục hoặc hàng trăm nghìn dòng, việc gọi Find trên từng sheet có thể vẫn chậm. Một cách tối ưu là đọc dữ liệu vào mảng và thực hiện tìm kiếm bằng VBA thuần (loop), sau đó trả về vị trí.

Sub TimTrongArray() Dim ws As Worksheet Dim arrData As Variant Dim i As Long, j As Long Dim strKey As String Dim sResult As String Set ws = ThisWorkbook.Sheets("BigData") arrData = ws.Range("A1:D100000").Value ' Đọc vào mảng 2 chiều strKey = "XYZ" For i = LBound(arrData, 1) To UBound(arrData, 1) For j = LBound(arrData, 2) To UBound(arrData, 2) If arrData(i, j) = strKey Then sResult = sResult & "R" & i & "C" & j & vbCrLf End If Next j Next i If sResult <> "" Then MsgBox "Tìm thấy tại:" & vbCrLf & sResult Else MsgBox "Không tìm thấy '" & strKey & "' trong mảng." End If
End Sub

Mặc dù không dùng Find trực tiếp, nhưng cách này thường nhanh hơn khi dữ liệu thực sự lớn và bạn cần thực hiện nhiều lần tìm kiếm.

9.4. Tự động cập nhật kết quả khi dữ liệu thay đổi (Event-driven)

Bạn có thể gắn hàm tìm kiếm vào Worksheet_Change để tự động phản hồi khi người dùng nhập dữ liệu mới.

Private Sub Worksheet_Change(ByVal Target As Range) Dim rngFound As Range Dim strKey As String strKey = "Urgent" If Not Intersect(Target, Me.Columns("B")) Is Nothing Then Set rngFound = Me.Columns("B").Find(What:=strKey, LookIn:=xlValues, LookAt:=xlWhole) If Not rngFound Is Nothing Then Me.Cells(rngFound.Row, "C").Value = "Cần xử lý ngay" End If End If
End Sub

Khi người dùng nhập “Urgent” vào cột B, ô cùng hàng ở cột C sẽ tự động được cập nhật.

10. Những lỗi thường gặp và cách khắc phục

LỗiNguyên nhânGiải pháp
Run-time error 91: Object variable or With block variable not setKhông kiểm tra Nothing sau Find.Luôn dùng If rngFound Is Nothing Then …
Find không trả về kết quả dù giá trị tồn tạiTham số After nằm sau ô chứa giá trị, hoặc LookIn sai.Đặt After:=rngSearch.Cells(rngSearch.Cells.Count) để bắt đầu từ đầu; kiểm tra LookIn.
Kết quả sai khi có dữ liệu dạng ngàyExcel lưu ngày dưới dạng số, LookIn:=xlValues có thể so sánh sai.Sử dụng CDate hoặc Format để chuẩn hoá trước khi tìm kiếm.
Find trả về cùng một ô lặp lạiKhông lưu rngFirst khi dùng FindNext.Ghi nhớ ô đầu tiên và so sánh trong vòng lặp.
SearchFormat không hoạt độngKhông xóa cấu hình tìm kiếm trước khi thay đổi hoặc không thiết lập mẫu đúng.Dùng Application.FindFormat.Clear và sao chép định dạng từ mẫu.

11. Thực hành: Xây dựng một công cụ tìm kiếm nhanh trong Excel

11.1. Yêu cầu

  • Người dùng nhập từ khóa vào ô E2 trên Sheet “Search”.
  • Khi nhấn nút “Tìm Kiếm”, macro sẽ:
  • Tìm trong toàn workbook (tất cả sheet) các ô chứa từ khóa (phần một, không phân biệt hoa/thường).
  • Hiển thị danh sách kết quả trong một UserForm dạng ListBox, mỗi mục gồm: Tên Sheet – Địa chỉ ô – Giá trị.
  • Khi người dùng double-click vào một mục, Excel sẽ tự động chuyển tới ô tương ứng.

11.2. Mã VBA

'--- Module: modSearch ---
Option Explicit Public Type SearchResult SheetName As String Address As String Value As String
End Type Public Sub RunSearch() Dim ws As Worksheet Dim rng As Range, rngFound As Range, rngFirst As Range Dim key As String Dim coll As Collection Dim res As SearchResult Dim frm As frmSearch key = Trim(ThisWorkbook.Sheets("Search").Range("E2").Value) If key = "" Then MsgBox "Vui lòng nhập từ khóa.", vbExclamation Exit Sub End If Set coll = New Collection For Each ws In ThisWorkbook.Worksheets Set rng = ws.UsedRange Set rngFound = rng.Find(What:=key, LookIn:=xlValues, LookAt:=xlPart, _ SearchOrder:=xlByRows, SearchDirection:=xlNext, _ MatchCase:=False) If Not rngFound Is Nothing Then Set rngFirst = rngFound Do res.SheetName = ws.Name res.Address = rngFound.Address(False, False) res.Value = CStr(rngFound.Value) coll.Add res Set rngFound = rng.FindNext(rngFound) Loop While Not rngFound Is Nothing And rngFound.Address <> rngFirst.Address End If Next ws Set frm = New frmSearch frm.LoadResults coll frm.Show vbModal
End Sub
'--- UserForm: frmSearch ---
Option Explicit Private mResults As Collection Public Sub LoadResults(col As Collection) Dim i As Long Set mResults = col Me.lstResults.Clear For i = 1 To mResults.Count With mResults(i) Me.lstResults.AddItem .SheetName & " | " & .Address & " | " & .Value End With Next i
End Sub Private Sub lstResults_DblClick(ByVal Cancel As MSForms.ReturnBoolean) Dim idx As Long Dim itm As SearchResult idx = Me.lstResults.ListIndex + 1 If idx > 0 Then itm = mResults(idx) With ThisWorkbook.Worksheets(itm.SheetName) .Activate .Range(itm.Address).Select End With Unload Me End If
End Sub Private Sub cmdClose_Click() Unload Me
End Sub

11.3. Hướng dẫn triển khai

  1. Thêm một Sheet tên “Search”, đặt ô E2 làm ô nhập từ khóa, tạo một nút (Insert > Shape) và gán macro RunSearch.
  2. Thêm một UserForm (frmSearch) với:
  3. ListBox (lstResults) – MultiColumn = False.
  4. CommandButton (cmdClose) – Caption = “Đóng”.
  5. Thêm một Module (modSearch) và dán mã ở trên.
  6. Lưu workbook dưới dạng .xlsm và thử nghiệm.

Kết quả: Khi người dùng nhập “2026” và nhấn nút, một cửa sổ hiện ra danh sách các ô chứa “2026”. Double-click sẽ đưa con trỏ tới ô tương ứng, giúp người dùng di chuyển nhanh chóng trong báo cáo lớn.

12. Tổng kết

  • Hàm Find trong VBA là công cụ mạnh mẽ, nhanh chóng và linh hoạt để tìm kiếm dữ liệu trong Excel.
  • Hiểu rõ cú pháp, các tham số (LookIn, LookAt, SearchDirection, …) giúp bạn tùy chỉnh tìm kiếm phù hợp với mọi tình huống.
  • Khi cần tìm nhiều kết quả, sử dụng vòng lặp Do…Loop kết hợp với FindNext và luôn ghi nhớ ô đầu tiên để tránh vòng lặp vô hạn.
  • SearchFormat mở ra khả năng tìm kiếm dựa trên định dạng – rất hữu ích khi dữ liệu được tô màu hoặc có font đặc biệt.
  • Đối với dữ liệu lớn, cân nhắc việc đọc vào mảng hoặc kết hợp RegExp để tối ưu tốc độ.
  • Cuối cùng, luôn kiểm tra Nothing, xóa cấu hình FindFormat, và xử lý lỗi để macro chạy ổn định.

Với những kiến thức và kỹ thuật trên, bạn đã sẵn sàng áp dụng hàm Find trong VBA vào mọi dự án Excel, từ các bảng tính đơn giản cho đến các hệ thống báo cáo phức tạp trong doanh nghiệp. Hãy thử viết một vài macro, tự động hoá quy trình tìm kiếm và cảm nhận sự khác biệt mà VBA mang lại cho công việc của bạn!

⚠️
LƯU Ý QUAN TRỌNG: Miễn trừ trách nhiệm: Mặc dù chúng tôi luôn nỗ lực để đảm bảo tính chính xác và cập nhật của thông tin, nhưng các quy định về giáo dục và tuyển sinh có thể thay đổi theo thời gian. BigSchool không chịu trách nhiệm về bất kỳ sai sót nào hoặc kết quả phát sinh từ việc sử dụng thông tin trên trang này. Độc giả nên liên hệ trực tiếp với nhà trường hoặc cơ quan chức năng để có thông tin mới nhất. Ngoài ra, BigSchool tuyệt đối không bán sản phẩm, khóa học hay cung cấp dịch vụ được nhắc đến trong bài.

Viết một bình luận