專案管理教學、範本與工具比較 訂閱電子報 →
Excel 教學 UPDATED 2026.09

【VBA Find】完整教學:語法參數、5大除錯技巧與多條件搜尋實作

學會 VBA Find 方法的完整語法、參數設定、多條件搜尋與常見錯誤排查,讓你在 Excel 大量資料中快速定位並自動化處理目標儲存格。

KEY TAKEAWAYS90 秒摘要
  • 01Find方法搜尋速度遠優於逐格遍歷但需明確指定LookIn LookAt等參數
  • 02Find會記憶上次搜尋設定容易導致同段程式碼結果不一致
  • 03搜尋不到時回傳Nothing須用If Not result Is Nothing判斷防錯
  • 04FindNext可搭配firstAddress避免循環搜尋造成無限迴圈
  • 05找不到常見原因包含前後空白型別不符及搜尋範圍未涵蓋目標

VBA Find 方法是 Excel 內建的高效搜尋工具,能在指定範圍內快速定位符合條件的儲存格,速度遠優於逐格遍歷。 本文完整解析 Find 語法與 9 大參數、完全符合與部分符合差異、FindNext 多結果搜尋、多條件搜尋實作,以及 5 大「找不到」除錯技巧,所有範例皆可直接複製使用。

VBA Find 方法是什麼?與其他搜尋方式的差異

VBA 的 Find 方法等同於你在 Excel 中按下 Ctrl+F 的程式化版本——它在指定的 Range 物件中搜尋符合條件的第一個儲存格,並回傳該儲存格的 Range 物件。與手動搜尋不同的是,Find 方法可以嵌入自動化流程,搭配迴圈與條件判斷,實現批次處理。

常見的應用場景包括:

  • 在數千筆訂單資料中定位特定訂單編號
  • 自動化報表中找到特定欄位並填入計算結果
  • 搭配 FindNext 批次標記所有符合條件的資料列
  • 結合 AutoFilter 先篩選再精確定位

不過,Find 並不是唯一的搜尋方式。在決定使用哪種方法之前,先了解三種常見搜尋方式的差異:

比較維度 Find 方法 For Each 逐格遍歷 AutoFilter 篩選
速度(大量資料) 快 慢,資料越多差距越大 快
適用場景 定位單一或多個匹配值 需複雜多欄條件判斷 大量資料批次篩選
程式複雜度 中等(需處理 Nothing) 低(直覺式迴圈) 中等(需管理篩選狀態)
回傳結果 單一儲存格 Range 自行收集 篩選後的可見列
多條件支援 需搭配 If 判斷 原生支援 原生支援(Criteria)
VBA 搜尋方式選擇指南:已知搜尋值且需快速定位→Find 方法、需多欄複雜條件判斷→For Each 遍歷、需批次篩選大量資料→AutoFilter、需定位後批次處理→Find + AutoFilter 組合
▲ VBA 搜尋方式選擇指南:已知搜尋值且需快速定位→Find 方法、需多欄複雜條件判斷→For Each 遍歷、需批次篩選大量資料→AutoFilter、需定位後批次處理→Find + AutoFilter 組合

何時不適合用 Find? 當你需要同時比對三個以上欄位的條件(例如「A 欄是台北、B 欄大於 100、C 欄日期在本月」),For Each 迴圈搭配 If 條件判斷會更直覺。Find 的強項在於「已知搜尋值、快速定位」,而非複雜的多維度篩選。

免費下載:Excel 函數 & 快捷鍵速查表
最常用的 30+ 函數、快捷鍵與錯誤代碼,整理成一頁,放桌邊隨時查。輸入 Email,速查表立即寄到你的信箱;一併訂閱《借力 Lever Stack》每週電子報——精選省時工具與方法,隨時可退訂。
由《借力 Lever Stack》每週電子報寄送

Find 方法完整語法與參數詳解

Find 方法的完整語法如下:

Set result = Range.Find(What, After, LookIn, LookAt, SearchOrder, SearchDirection, MatchCase, MatchByte, SearchFormat)

以下是每個參數的詳細說明,特別注意「預設值」欄位——這是 Find 方法最常見 bug 的根源:

參數 說明 可用值 預設值
What 必填。要搜尋的內容 字串或數值,如 "Test"、123 無(必填)
After 從哪個儲存格之後開始搜尋 Range 物件 搜尋範圍的左上角
LookIn 搜尋內容類型 xlValues(值)、xlFormulas(公式)、xlComments(註解) 記憶上次設定
LookAt 符合方式 xlWhole(完全符合)、xlPart(部分符合) 記憶上次設定
SearchOrder 搜尋方向 xlByRows(逐列)、xlByColumns(逐欄) 記憶上次設定
SearchDirection 搜尋順序 xlNext(向後)、xlPrevious(向前) xlNext
MatchCase 是否區分大小寫 True / False 記憶上次設定
MatchByte 雙字節語言比對 True / False False
SearchFormat 是否比對格式 True / False(需搭配 FindFormat) False
Find 方法 9 大參數分類:必填參數—What、搜尋範圍控制—After 與 SearchOrder 與 SearchDirection、比對方式—LookIn 與 LookAt 與 MatchCase、特殊用途—MatchByte 與 Sear
▲ Find 方法 9 大參數分類:必填參數—What、搜尋範圍控制—After 與 SearchOrder 與 SearchDirection、比對方式—LookIn 與 LookAt 與 MatchCase、特殊用途—MatchByte 與 SearchFormat

⚠️ 重要警告:Find 會記憶上次搜尋設定

這是 Microsoft Learn 官方文件特別強調的行為:LookIn、LookAt、SearchOrder、MatchCase 這四個參數,如果你沒有明確指定,Find 會沿用上次搜尋(包括使用者手動 Ctrl+F)的設定值。這代表同一段程式碼在不同時間執行,可能因為使用者中途手動搜尋過而產生不同結果。

建議每次使用 Find 時,都明確指定所有關鍵參數:

Set result = ws.Range("A1:A1000").Find( _
    What:="目標值", _
    LookIn:=xlValues, _
    LookAt:=xlWhole, _
    SearchOrder:=xlByRows, _
    MatchCase:=False _
)

這個寫法雖然比較長,但能確保程式行為一致,避免難以追蹤的 bug。如果你正在學習 VBA 基礎語法,養成明確指定參數的習慣會省去大量除錯時間。

基本用法:搜尋單一值並取得位置

搜尋並回傳儲存格位置(.Address、.Row、.Column)

Find 方法回傳的是一個 Range 物件,你可以透過它的屬性取得不同格式的位置資訊:

  • .Address:回傳絕對位址字串,如 $A$5,適合用於顯示或記錄
  • .Row:回傳列號(數字),如 5,適合用於操作同列其他欄位
  • .Column:回傳欄號(數字),如 1,適合用於動態欄位計算

以下是一個完整的實務範例——在員工名單的 A 欄搜尋姓名,找到後取得同列 B 欄的部門資訊:

Sub FindEmployeeDepartment()
    Dim ws As Worksheet
    Dim result As Range

    Set ws = ThisWorkbook.Sheets("員工名單")

    Set result = ws.Range("A2:A500").Find( _
        What:="王小明", _
        LookIn:=xlValues, _
        LookAt:=xlWhole, _
        MatchCase:=False _
    )

    If Not result Is Nothing Then
        ' 找到了,取得同列 B 欄的部門
        Dim dept As String
        dept = ws.Cells(result.Row, 2).Value
        MsgBox "王小明在第 " & result.Row & " 列,部門:" & dept
        ' result.Address 會回傳 "$A$15" 這樣的絕對位址
    Else
        MsgBox "找不到王小明"
    End If
End Sub

這個模式——「Find 定位 → 取得 .Row → 操作同列其他欄位」——是 VBA Find 最常見的使用方式,幾乎所有進階應用都建立在這個基礎上。

完全符合 vs 部分符合(xlWhole vs xlPart)

LookAt 參數決定了搜尋的精確程度,這是初學者最容易搞混的設定之一。

xlWhole(完全符合):儲存格的完整內容必須與搜尋值完全一致。

xlPart(部分符合):只要儲存格內容包含搜尋值即可。

用一個具體例子說明差異——假設 A 欄有以下資料:

儲存格 內容
A1 台北
A2 台北市
A3 新北市
A4 台北市信義區
' xlWhole:只找到 A1(完全等於「台北」)
Set result = Range("A1:A4").Find(What:="台北", LookAt:=xlWhole)
' result.Address = "$A$1"

' xlPart:找到 A1(第一個包含「台北」的儲存格)
Set result = Range("A1:A4").Find(What:="台北", LookAt:=xlPart)
' result.Address = "$A$1"
' 但 FindNext 會繼續找到 A2 和 A4

判斷指引:

  • 搜尋 ID、員工編號、訂單號碼等唯一識別碼 → 用 xlWhole
  • 搜尋關鍵字、地址片段、產品名稱中的部分文字 → 用 xlPart
  • 不確定時 → 先用 xlWhole,找不到再改 xlPart
xlWhole vs xlPart 選擇指南:搜尋唯一識別碼如 ID 或編號→xlWhole 完全符合、搜尋關鍵字或部分文字→xlPart 部分符合、搜尋可能有前後綴的資料→xlPart 加後續驗證
▲ xlWhole vs xlPart 選擇指南:搜尋唯一識別碼如 ID 或編號→xlWhole 完全符合、搜尋關鍵字或部分文字→xlPart 部分符合、搜尋可能有前後綴的資料→xlPart 加後續驗證

搜尋不到時的處理(Nothing 判斷)

Find 方法在搜尋不到時會回傳 Nothing,如果你直接對 Nothing 操作(例如取 .Row),VBA 會拋出「執行階段錯誤 91:物件變數或 With 區塊變數未設定」。

標準防錯寫法:

Dim result As Range
Set result = ws.Range("A:A").Find(What:="目標值", LookIn:=xlValues, LookAt:=xlWhole)

If Not result Is Nothing Then
    ' 找到了,安全地操作 result
    Debug.Print "位置:" & result.Address
    Debug.Print "列號:" & result.Row
    Debug.Print "值:" & result.Value
Else
    ' 找不到,執行替代邏輯
    MsgBox "搜尋不到指定資料,請確認搜尋條件"
End If

這個 If Not result Is Nothing 判斷是 VBA Find 的必備寫法,無論你的程式多簡單,都不要省略它。更多 Excel 基礎操作與公式的防錯技巧,可以參考我們的教學指南。

進階搜尋:多結果、多條件與格式搜尋

用 FindNext 搜尋所有匹配結果

Find 方法只回傳第一個匹配結果。如果資料中有多個符合條件的儲存格,你需要搭配 FindNext 進行迴圈搜尋。

FindNext 的運作原理是「接續上次 Find 或 FindNext 的位置繼續搜尋」。但因為 Find 的搜尋是循環式(wrap-around)的——搜尋到範圍底部後會自動回到頂部繼續——如果不設定停止條件,迴圈會無限執行。

解決方法是記錄第一個找到的位址(firstAddress),當 FindNext 回到這個位址時,代表已經搜尋完一圈:

Sub FindAllMatches()
    Dim ws As Worksheet
    Dim c As Range
    Dim firstAddress As String
    Dim count As Long

    Set ws = ThisWorkbook.Sheets("資料表")

    Set c = ws.Range("A2:A10000").Find( _
        What:="Test", _
        LookIn:=xlValues, _
        LookAt:=xlWhole, _
        MatchCase:=False _
    )

    If Not c Is Nothing Then
        firstAddress = c.Address  ' 記錄起點
        count = 0

        Do
            count = count + 1
            Debug.Print "第 " & count & " 筆:" & c.Address & " = " & c.Value

            ' 這裡可以加入你的處理邏輯
            ' 例如:ws.Cells(c.Row, 3).Value = "已處理"

            Set c = ws.Range("A2:A10000").FindNext(c)
        Loop While Not c Is Nothing And c.Address <> firstAddress

        MsgBox "共找到 " & count & " 筆匹配資料"
    Else
        MsgBox "未找到任何匹配資料"
    End If
End Sub

關於 After 參數的循環搜尋行為: Find 方法從 After 參數指定的儲存格之後開始搜尋,而非從該儲存格本身開始。如果你不指定 After,預設從範圍的左上角之後開始,這意味著左上角那格會是最後被搜尋到的。在 FindNext 迴圈中,這個行為通常不會造成問題,因為迴圈會繞完整圈。

自訂 FindAll 函數(回傳所有結果集合)

VBA 沒有內建的 FindAll 方法,但你可以自訂一個函數,將所有匹配結果存入 Collection,方便後續統一處理:

Function FindAll(rng As Range, val As String) As Collection
    Dim c As Range, firstAddress As String
    Dim results As New Collection

    Set c = rng.Find(What:=val, LookIn:=xlValues, LookAt:=xlWhole, MatchCase:=False)

    If Not c Is Nothing Then
        firstAddress = c.Address
        Do
            results.Add c
            Set c = rng.FindNext(c)
        Loop While Not c Is Nothing And c.Address <> firstAddress
    End If

    Set FindAll = results
End Function

呼叫範例與結果輸出:

Sub UseFindAll()
    Dim ws As Worksheet
    Dim matches As Collection
    Dim cell As Range

    Set ws = ThisWorkbook.Sheets("訂單資料")
    Set matches = FindAll(ws.Range("B2:B5000"), "已出貨")

    If matches.count > 0 Then
        Debug.Print "共找到 " & matches.count & " 筆「已出貨」訂單:"
        For Each cell In matches
            Debug.Print "  列 " & cell.Row & ":訂單編號 " & ws.Cells(cell.Row, 1).Value
        Next cell
    Else
        Debug.Print "沒有找到「已出貨」的訂單"
    End If
End Sub

多條件搜尋實作

VBA Find 原生只支援單一搜尋值,但你可以透過兩種方式實現多條件搜尋。

方法一:FindNext 迴圈內加 If 判斷第二條件

這是最常用的做法——先用 Find 定位第一個條件,再用 If 檢查同列其他欄位是否符合第二條件:

Sub FindWithMultipleConditions()
    Dim ws As Worksheet
    Dim c As Range, firstAddress As String
    Dim matchCount As Long

    Set ws = ThisWorkbook.Sheets("銷售資料")

    ' 第一條件:A 欄產品名稱包含「筆電」
    Set c = ws.Range("A2:A10000").Find( _
        What:="筆電", LookIn:=xlValues, LookAt:=xlPart, MatchCase:=False)

    If Not c Is Nothing Then
        firstAddress = c.Address
        matchCount = 0

        Do
            ' 第二條件:同列 C 欄金額大於 30000
            If ws.Cells(c.Row, 3).Value > 30000 Then
                matchCount = matchCount + 1
                Debug.Print "符合:列 " & c.Row & _
                    ",產品:" & c.Value & _
                    ",金額:" & ws.Cells(c.Row, 3).Value
            End If

            Set c = ws.Range("A2:A10000").FindNext(c)
        Loop While Not c Is Nothing And c.Address <> firstAddress

        MsgBox "共 " & matchCount & " 筆符合雙條件"
    End If
End Sub

方法二:搭配 Like 運算子進行模糊多條件

當你需要更靈活的文字比對時,可以在迴圈內使用 Like 運算子:

Do
    ' 用 Like 進行模糊比對:A 欄以「TW-」開頭,且 B 欄包含「急件」
    If c.Value Like "TW-*" And ws.Cells(c.Row, 2).Value Like "*急件*" Then
        ' 處理符合條件的資料
        ws.Cells(c.Row, 5).Value = "優先處理"
    End If

    Set c = ws.Range("A2:A10000").FindNext(c)
Loop While Not c Is Nothing And c.Address <> firstAddress

如果你的多條件邏輯更複雜(超過三個條件),建議改用 For Each 迴圈搭配完整的 If 條件判斷,程式碼會更易讀。

多條件搜尋方法選擇:單一條件快速定位→Find 方法、兩個條件且第一條件可用 Find→Find + If 判斷、三個以上條件或複雜邏輯→For Each 迴圈、大量資料批次篩選→AutoFilter
▲ 多條件搜尋方法選擇:單一條件快速定位→Find 方法、兩個條件且第一條件可用 Find→Find + If 判斷、三個以上條件或複雜邏輯→For Each 迴圈、大量資料批次篩選→AutoFilter

搜尋格式(底色、字型)

Find 方法可以搜尋儲存格的格式(如底色、字型顏色),但需要先透過 Application.FindFormat 物件設定搜尋條件。

以下是搜尋黃色底色儲存格的完整範例:

Sub FindYellowCells()
    Dim ws As Worksheet
    Dim c As Range, firstAddress As String

    Set ws = ThisWorkbook.Sheets("報表")

    ' 步驟 1:設定要搜尋的格式(黃色底色)
    Application.FindFormat.Clear  ' 先清除之前的設定
    Application.FindFormat.Interior.Color = RGB(255, 255, 0)  ' 黃色

    ' 步驟 2:執行搜尋,SearchFormat 設為 True
    Set c = ws.Range("A1:Z100").Find( _
        What:="", _
        SearchFormat:=True _
    )

    If Not c Is Nothing Then
        firstAddress = c.Address
        Do
            Debug.Print "黃色儲存格:" & c.Address & " = " & c.Value
            Set c = ws.Range("A1:Z100").FindNext(c)
        Loop While Not c Is Nothing And c.Address <> firstAddress
    Else
        MsgBox "沒有找到黃色底色的儲存格"
    End If

    ' 步驟 3:重要!使用後必須清除 FindFormat
    Application.FindFormat.Clear
End Sub

⚠️ 注意: 使用 SearchFormat 後,務必執行 Application.FindFormat.Clear。否則後續所有 Find 操作都會套用這個格式條件,導致搜尋結果不正確——這是一個非常隱蔽的 bug。

「VBA Find 找不到」完整除錯指南

「明明資料就在那裡,為什麼 Find 回傳 Nothing?」這是 VBA 開發者最常遇到的挫折之一。以下是 5 大常見原因與對應的修正方式,按照發生頻率排序:

原因 1:Find 記憶上次 LookIn / LookAt 設定

這是最常見的原因。 如前文所述,Find 會記憶上次的搜尋設定。如果使用者在你的程式執行前手動用 Ctrl+F 搜尋過,並且選了「部分符合」,你的程式即使預期用「完全符合」,實際上卻會用「部分符合」。

' ❌ 危險寫法:沒有指定 LookIn 和 LookAt
Set result = Range("A:A").Find(What:="100")

' ✅ 安全寫法:明確指定所有關鍵參數
Set result = Range("A:A").Find( _
    What:="100", _
    LookIn:=xlValues, _
    LookAt:=xlWhole, _
    MatchCase:=False _
)

原因 2:資料含前後空白

從外部系統匯入的資料經常帶有看不見的前後空白或特殊字元。儲存格顯示「台北」,實際內容可能是「 台北 」或「台北 」(全形空白)。

' 修正方式:搜尋前先清理資料
Dim searchVal As String
searchVal = Trim("台北")  ' 清除前後空白

' 或者改用 xlPart 部分符合來容忍空白
Set result = Range("A:A").Find( _
    What:=searchVal, _
    LookIn:=xlValues, _
    LookAt:=xlPart _
)

如果問題頻繁發生,建議先用迴圈清理整欄資料:

Dim cell As Range
For Each cell In ws.Range("A2:A" & ws.Cells(ws.Rows.count, 1).End(xlUp).Row)
    cell.Value = Trim(cell.Value)
Next cell

原因 3:數值儲存為文字格式(型別不符)

儲存格顯示 100,但實際上是以文字格式儲存的「100」。當你用 Find(What:=100) 搜尋數值 100 時,如果 LookIn:=xlValues,Find 會比對顯示值(字串),通常能找到。但如果 LookIn:=xlFormulas,型別不符就可能導致找不到。

' 修正方式 1:確保 LookIn 使用 xlValues
Set result = Range("A:A").Find(What:=100, LookIn:=xlValues)

' 修正方式 2:將搜尋值轉為字串
Set result = Range("A:A").Find(What:=CStr(100), LookIn:=xlValues)

原因 4:After 參數設定導致漏找第一格

After 參數指定的儲存格不會被搜尋,搜尋從它的下一格開始。如果你的目標值恰好在 After 指定的那一格,Find 會跳過它(雖然循環搜尋最終會繞回來,但在某些非迴圈場景下會漏找)。

' 假設 A1 就是目標值
' ❌ 這樣會跳過 A1,從 A2 開始搜尋
Set result = Range("A1:A100").Find(What:="目標", After:=Range("A1"))

' ✅ 不指定 After,讓 Find 使用預設值(範圍左上角)
' 搜尋會從 A1 之後開始,最後繞回 A1
Set result = Range("A1:A100").Find(What:="目標", LookIn:=xlValues, LookAt:=xlWhole)

原因 5:搜尋範圍不含目標儲存格

最容易被忽略的原因——你的搜尋範圍可能沒有涵蓋到目標資料。特別是當資料列數會變動時,寫死的範圍(如 A1:A100)可能不夠。

' ❌ 寫死範圍,資料超過 100 列就找不到
Set result = ws.Range("A1:A100").Find(What:="目標")

' ✅ 動態範圍,自動偵測最後一列
Dim lastRow As Long
lastRow = ws.Cells(ws.Rows.count, 1).End(xlUp).Row
Set result = ws.Range("A1:A" & lastRow).Find( _
    What:="目標", _
    LookIn:=xlValues, _
    LookAt:=xlWhole _
)

更多關於 VBA Range 動態範圍的寫法,可以參考我們的專題教學。

Find 找不到除錯流程:第一步檢查是否明確指定 LookIn 和 LookAt 參數、第二步檢查資料是否有前後空白用 Trim 清理、第三步確認數值型別是否一致、第四步確認 After 參數設定、第五步確認搜尋範圍是否涵蓋目標儲存格
▲ Find 找不到除錯流程:第一步檢查是否明確指定 LookIn 和 LookAt 參數、第二步檢查資料是否有前後空白用 Trim 清理、第三步確認數值型別是否一致、第四步確認 After 參數設定、第五步確認搜尋範圍是否涵蓋目標儲存格

快速排查清單(逐項確認):

  • ☐ 是否明確指定了 LookIn、LookAt、MatchCase 參數?
  • ☐ 搜尋值是否有前後空白?(用 Trim() 處理)
  • ☐ 儲存格的資料型別是否與搜尋值一致?(數值 vs 文字)
  • ☐ After 參數是否指向了目標儲存格本身?
  • ☐ 搜尋範圍是否涵蓋了所有資料列?(用動態範圍)
  • ☐ 是否之前使用過 SearchFormat 但忘了 Clear?
  • ☐ 是否有合併儲存格影響搜尋結果?

如果你經常需要在 Excel 中做類似 Find 的查找操作,也可以參考 VBA VLOOKUP 函數的用法,兩者在不同場景各有優勢。

效能比較與實務整合案例

Find vs For Each 效能差異

搜尋單一值時,Find 通常比 For Each 逐格比對快很多,資料量越大差距越明顯。實際快多少取決於你的電腦、資料型別與搜尋範圍;想知道自己的檔案差多少,可以在程式前後用 VBA 的 Timer 函數計時比較。

Find 方法的速度優勢來自於它使用 Excel 內部的搜尋引擎,而非 VBA 層級的逐格比對。

但 For Each 反而更合適的情境:

  • 需要同時檢查並修改多個欄位的值(Find 只能定位,修改需要額外操作)
  • 條件邏輯複雜到無法用 Find + If 簡潔表達
  • 需要對每一列都執行某種計算(即使不符合條件也要處理)
  • 資料量小於 1000 筆時,兩者差異可忽略,選擇更易讀的寫法即可
搜尋方法選擇矩陣:橫軸為資料量(小量 vs 大量)、縱軸為條件複雜度(簡單 vs 複雜)、左下象限小量簡單用 Find 或 For Each 皆可、右下象限大量簡單用 Find 最佳、左上象限小量複雜用 For Each、右上象限大量複雜用 Auto
▲ 搜尋方法選擇矩陣:橫軸為資料量(小量 vs 大量)、縱軸為條件複雜度(簡單 vs 複雜)、左下象限小量簡單用 Find 或 For Each 皆可、右下象限大量簡單用 Find 最佳、左上象限小量複雜用 For Each、右上象限大量複雜用 AutoFilter 加 Find 組合

實務案例:專案進度表自動標記

在實際的專案管理工作中,常需要在進度表中自動標記已完成的項目。以下範例結合 AutoFilter 與 Find,先篩選特定狀態的資料,再進行批次更新:

Sub MarkCompletedTasks()
    Dim ws As Worksheet
    Dim c As Range, firstAddress As String

    Set ws = ThisWorkbook.Sheets("專案進度")

    ' 步驟 1:用 AutoFilter 篩選 C 欄狀態為「已完成」的列
    If ws.AutoFilterMode Then ws.AutoFilterMode = False  ' 先清除既有篩選
    ws.Range("A1:E500").AutoFilter Field:=3, Criteria1:="已完成"

    ' 步驟 2:在篩選結果中,用 Find 定位 D 欄(驗收日期)為空的列
    Set c = ws.Range("D2:D500").Find( _
        What:="", _
        LookIn:=xlValues, _
        LookAt:=xlWhole _
    )

    ' 步驟 3:對找到的空白驗收日期欄填入今天日期
    If Not c Is Nothing Then
        firstAddress = c.Address
        Do
            ' 只處理可見列(篩選後的結果)
            If c.EntireRow.Hidden = False Then
                c.Value = Date  ' 填入今天日期
                ws.Cells(c.Row, 5).Value = "自動填入"  ' E 欄備註
            End If
            Set c = ws.Range("D2:D500").FindNext(c)
        Loop While Not c Is Nothing And c.Address <> firstAddress
    End If

    ' 步驟 4:清除篩選
    ws.AutoFilterMode = False

    MsgBox "已完成項目的驗收日期已自動填入"
End Sub

篩選後只處理可見列的技巧: 在上面的範例中,我們用 c.EntireRow.Hidden = False 來判斷該列是否為篩選後的可見列。另一種更精確的做法是使用 SpecialCells(xlCellTypeVisible):

' 取得篩選後的可見範圍
Dim visibleRange As Range
On Error Resume Next
Set visibleRange = ws.Range("D2:D500").SpecialCells(xlCellTypeVisible)
On Error GoTo 0

If Not visibleRange Is Nothing Then
    ' 在可見範圍中搜尋
    Set c = visibleRange.Find(What:="", LookIn:=xlValues)
    ' ... 後續處理
End If

搜尋後的後續操作範例

找到目標儲存格後,以下三種後續操作最為常見:

操作一:複製整列到另一工作表

Sub CopyMatchingRows()
    Dim wsSrc As Worksheet, wsDst As Worksheet
    Dim c As Range, firstAddress As String
    Dim dstRow As Long

    Set wsSrc = ThisWorkbook.Sheets("原始資料")
    Set wsDst = ThisWorkbook.Sheets("篩選結果")
    dstRow = 2  ' 目標工作表從第 2 列開始貼上

    ' 先複製標題列
    wsSrc.Rows(1).Copy Destination:=wsDst.Rows(1)

    Set c = wsSrc.Range("A2:A10000").Find( _
        What:="VIP", LookIn:=xlValues, LookAt:=xlPart, MatchCase:=False)

    If Not c Is Nothing Then
        firstAddress = c.Address
        Do
            c.EntireRow.Copy Destination:=wsDst.Rows(dstRow)
            dstRow = dstRow + 1
            Set c = wsSrc.Range("A2:A10000").FindNext(c)
        Loop While Not c Is Nothing And c.Address <> firstAddress
    End If

    MsgBox "已複製 " & (dstRow - 2) & " 列到篩選結果工作表"
End Sub

操作二:刪除符合條件的列(由下往上刪)

Sub DeleteMatchingRows()
    Dim ws As Worksheet
    Dim c As Range
    Dim deleteRange As Range
    Dim firstAddress As String

    Set ws = ThisWorkbook.Sheets("資料表")

    Set c = ws.Range("B2:B10000").Find( _
        What:="已取消", LookIn:=xlValues, LookAt:=xlWhole)

    If Not c Is Nothing Then
        firstAddress = c.Address
        Do
            ' 收集所有要刪除的列,最後一次刪除(效能較好)
            If deleteRange Is Nothing Then
                Set deleteRange = c.EntireRow
            Else
                Set deleteRange = Union(deleteRange, c.EntireRow)
            End If
            Set c = ws.Range("B2:B10000").FindNext(c)
        Loop While Not c Is Nothing And c.Address <> firstAddress

        deleteRange.Delete Shift:=xlUp
        MsgBox "已刪除所有「已取消」的資料列"
    End If
End Sub

操作三:修改同列其他欄位的值

' 找到 A 欄的產品代碼,更新 D 欄的價格
Set c = ws.Range("A2:A5000").Find(What:="PRD-001", LookIn:=xlValues, LookAt:=xlWhole)

If Not c Is Nothing Then
    ws.Cells(c.Row, 4).Value = 1299  ' 更新 D 欄價格
    ws.Cells(c.Row, 5).Value = Now   ' E 欄記錄更新時間
End If

想深入學習更多 Excel 公式與函數的進階應用,可以參考我們的完整教學指南。

如果你想系統性地提升 Excel 與 VBA 技能,Coursera 上的 Excel 專業課程提供從基礎到進階的完整學習路徑,適合想取得認證或強化數據分析能力的職場工作者。

VBA Find 方法總整理與學習路徑

掌握 VBA Find 方法的核心重點:

  • 每次使用 Find 都明確指定 LookIn、LookAt、MatchCase 參數——這能避免 90% 的「找不到」問題
  • 一定要加 If Not result Is Nothing 判斷——這是防止執行階段錯誤的必備寫法
  • 搜尋多個結果用 FindNext 迴圈,記得用 firstAddress 防止無限迴圈
  • 多條件搜尋用 Find + If 組合,超過三個條件時改用 For Each
  • 動態範圍取代寫死範圍——用 Cells(Rows.Count, 1).End(xlUp).Row 確保涵蓋所有資料

建議學習路徑:

  1. 基礎:Find 單一值搜尋 → Nothing 判斷 → .Row / .Address 取值
  2. 進階:FindNext 多結果迴圈 → 自訂 FindAll 函數 → 多條件搜尋
  3. 整合:結合 AutoFilter 批次處理 → 搭配 VLOOKUP 跨表查找
  4. 優化:效能調校 → 錯誤處理完善 → 封裝為可重用模組

如果你是 VBA 初學者,建議先從 VBA 入門全指南開始,建立完整的基礎觀念後再回來深入 Find 方法的進階用法。更多 Excel 實戰技巧也能幫助你在日常工作中更有效率。

當你的 Excel 自動化需求從「個人報表處理」擴展到「團隊協作追蹤」時,VBA 巨集的維護成本會快速上升——版本衝突、檔案鎖定、無法即時同步都是常見痛點。這時候可以考慮用 monday.com 這類雲端工具來管理團隊的專案進度與資料追蹤,內建的自動化規則能取代許多原本需要寫 VBA 才能完成的重複性工作,免費方案不需要信用卡就能開始使用。

VBA Find 常見問題 FAQ

VBA Find 可以同時搜尋多個值嗎?

Find 方法每次只能搜尋一個值。如果需要搜尋多個值(例如同時找「台北」和「高雄」),你需要對每個值分別執行 Find,或者改用 For Each 迴圈搭配 Select Case 或 If 判斷一次處理多個條件。

Find 方法能搜尋註解或公式嗎?

可以。透過 LookIn 參數指定搜尋範圍:LookIn:=xlComments 搜尋註解內容,LookIn:=xlFormulas 搜尋公式文字(例如找出所有包含 VLOOKUP 的儲存格)。注意 xlValues 搜尋的是儲存格顯示的值,而 xlFormulas 搜尋的是公式本身的文字。

Find 和 VLOOKUP 有什麼不同?該用哪個?

VLOOKUP 是查找函數,用於「根據 A 值找到對應的 B 值」,適合跨欄位的資料對照。Find 是搜尋方法,用於「定位某個值在哪個儲存格」,適合需要知道位置並進行後續操作的場景。如果你只需要取得對應值,用 VLOOKUP 更簡潔;如果你需要對找到的儲存格進行修改、刪除、複製等操作,用 Find。

如何讓 Find 搜尋多個工作表?

Find 方法只能在單一 Range 內搜尋。要跨工作表搜尋,需要用迴圈遍歷每個工作表:

Dim ws As Worksheet
Dim result As Range

For Each ws In ThisWorkbook.Worksheets
    Set result = ws.Cells.Find(What:="目標值", LookIn:=xlValues, LookAt:=xlWhole)
    If Not result Is Nothing Then
        MsgBox "在「" & ws.Name & "」工作表找到,位置:" & result.Address
        Exit For  ' 找到就停止,或移除此行以搜尋所有工作表
    End If
Next ws

搜尋速度很慢怎麼辦?

如果 Find 搜尋速度異常緩慢,通常不是 Find 本身的問題,而是搜尋範圍設定過大(例如 Cells.Find 搜尋整個工作表的 100 多萬列)。解決方法是用動態範圍限縮搜尋區域,只搜尋有資料的範圍。另外,在 FindNext 迴圈中如果同時進行大量寫入操作,建議在迴圈前加上 Application.ScreenUpdating = False 關閉畫面更新,結束後再設回 True。

表格視圖 · 自動化公式 · 即時協作 · 永久免費
用 monday.com 取代手動 Excel 追蹤
免費試用 →