跳转至

08 查找替换

VBA 中 Find 方法详解

在 Excel VBA 中,如果你需要在工作表或指定区域中查找某个内容所在的单元格,那么 Find 方法几乎是唯一的选择。它对应的是 Excel 界面中的:“Ctrl + F → 查找”,但在 VBA 中,Find 远不只是“查一个值”这么简单,它涉及到查找方向、查找方式、匹配规则、以及非常容易踩坑的“参数记忆问题”,下面将对 Find 方法进行系统整理。

一、Find 方法的基本概念

Find 用于在指定区域中查找满足条件的第一个单元格,并返回一个 Range 对象,如果找不到,返回 Nothing,语法结构为

Range.Find(  What,   After,   LookIn,   LookAt, _
    SearchOrder,  SearchDirection,  MatchCase,  MatchByte, SearchFormat )
注意FindRange 的方法,并不是所有参数都必须写,但不写的参数会沿用 Excel 上一次查找的设置

二、参数的具体介绍

(1)What —— 查找内容(必填) 这个参数可以写作What:="张三"What:=100等,可以是字符串、数字,但是 不能省略, 如果是公式,取决于 LookIn 参数

(2) After —— 从哪个单元格“之后”开始查找

比如我们写作 After:=Range("A1"),含义是: 从 A1 之后的下一个单元格开始查找(A1 本身不参与),同时需要理解的是,查找是一个环形过程,到末尾后会从头继续。

(3)LookIn —— 在什么里面查找

枚举值 说明
xlValues 查找单元格显示的值
xlFormulas 查找公式(含返回值)
xlComments 查找批注

(4)LookAt —— 精确 / 模糊查找:一般包含xlWholexlPart两种方式,前者代表需要完全匹配,后者代表包含即可

(5)SearchOrder —— 查找顺序:一般包含xlByRowsxlByColumns两种方式,前者代表按行查找,后者代表按列查找

(6)SearchDirection —— 查找方向:一般包含xlNextxlPrevious两种方式,前者代表向后查找,后者代表向前查找

(7) MatchCase —— 是否区分大小写MatchCase:=True 代表区分大小写,否则不区分

(8) MatchByte —— 是否区分全角 / 半角(很少用): 中文环境下几乎不用,日文环境可能会用到

(9)SearchFormat —— 按格式查找(高级):按 字体、填充色或者边框进行查找,需配合 Application.FindFormat 使用,属于进阶内容。

三、最基础的 Find 示例

示例 1:查找某个值是否存在

Sub FindValue()
    Dim rng As Range

    Set rng = Range("A1:D100").Find( _
        What:="张三", _
        LookIn:=xlValues, _
        LookAt:=xlWhole _
    )

    If rng Is Nothing Then
        MsgBox "未找到"
    Else
        MsgBox "找到:" & rng.Address
    End If
End Sub
需要注意的是Find 只返回第一个结果。如果你想找“所有符合条件的单元格”,必须配合 FindNext,如下示例:

示例2:查找所有“张三”

Sub FindAll()
    Dim firstAddress As String
    Dim rng As Range

    Set rng = Range("A1:D100").Find( _
        What:="张三", _
        LookIn:=xlValues, _
        LookAt:=xlWhole _
    )

    If rng Is Nothing Then Exit Sub

    firstAddress = rng.Address ' 如果找到了,则保留初始地址

    Do
        Debug.Print rng.Address
        Set rng = Range("A1:D100").FindNext(rng)
    Loop While rng.Address <> firstAddress ' 重新找到了起始点,终止循环
End Sub

需要注意: 必须保存第一次的地址 firstAddress,否则会死循环。在前面的内容中,我们用了 Find 的常规参数。但在某些场景下:单元格内容相同 但 格式不同 或者 你只关心 被高亮 / 被标红 / 被加粗 的数据,这时,SearchFormat 就派上用场了

示例3:根据格式进行查找

Sub FindByCellColor()
    Dim rng As Range
    Dim firstAddress As String

    ' 1. 清空格式条件
    Application.FindFormat.Clear

    ' 2. 设置要查找的格式
    Application.FindFormat.Interior.Color = RGB(255, 0, 0)

    ' 3. 执行查找
    Set rng = Range("A1:D100").Find( _
        What:="", _
        LookIn:=xlValues, _
        SearchFormat:=True
    )

    If rng Is Nothing Then Exit Sub

    firstAddress = rng.Address

    Do
        Debug.Print rng.Address
        Set rng = Range("A1:D100").FindNext(rng)
    Loop While rng.Address <> firstAddress
End Sub

四、Find 最容易踩的 3 个坑

  1. Find 会“记住”上一次 Excel 查找参数:这是 Find 最恶心、也是最经典的坑。如果你不显式写:LookInLookAtSearchOrderSearchDirectionMatchCase,则 VBA 会直接沿用你 上一次在 Excel 界面 Ctrl+F 的设置,所以使用此方法的时候尽量关键参数一律写全
  2. 找到后直接用,不判断 Nothing:比如错误的写法如下:

    Range("A1:D100").Find("张三").Select
    
    而正确的写法应该是下面这样,因为find可能找不到值:

    If Not rng Is Nothing Then rng.Select
    
    3. After 参数误解: After:=Range("A1"),这样的写法注意是不包含A1的, A1 不会被查找


VBA中Replace方法详解

在 Excel VBA 中,如果你需要对单元格内容进行批量替换,那么 Replace 方法是最高效、也是最常用的选择。它等价于 Excel 界面中的:“Ctrl + H → 查找和替换”,但在 VBA 中,Replace 不仅可以替换内容,还可以 按格式替换、限制查找范围、同时修改格式

一、Replace 方法的基本作用

Replace 用于在指定的 Range 中:

  • 查找满足条件的内容
  • 并将其批量替换为指定内容
  • 直接修改原数据(不可撤销)

Find 不同的是:Replace 没有返回值,执行后即生效。其基本语法可以写作:

Range.Replace(   What,  Replacement,   LookAt,  SearchOrder, _
    MatchCase,  MatchByte, SearchFormat, ReplaceFormat )
Find 一样,不写的参数会沿用 Excel 上一次 Ctrl+H 的设置

二、Replace参数详解

(1)What —— 要查找的内容:例如What:="张三"What:=100,可以是字符串或数字,支持通配符 *?

(2)Replacement —— 替换成什么:例如Replacement:="李四",也可以使用Replacement:=""清空内容

(3)LookAt —— 精确 / 模糊匹配:和Find类似,xlWhole表示精确匹配,xlPart表示包含即可

(4) SearchOrder —— 查找顺序xlByRows表示按行查找,xlByColumns表示按列查找,通常不影响结果,但在结合 SearchDirection 时有意义

(5)MatchCase —— 是否区分大小写MatchCase:=True代表区分大小写,反之则为不区分

(6)MatchByte —— 是否区分全角 / 半角:中文环境基本不用,日文环境可能涉及

(7) SearchFormat —— 是否限制“原格式”:如果SearchFormat:=True表示 只替换满足指定格式的单元格,但是需要配合Application.FindFormat进行使用

(8)ReplaceFormat —— 是否替换为新格式(进阶):如果ReplaceFormat:=True表示 在替换内容的同时,修改单元格格式,需要配合Application.ReplaceFormat进行使用

三、最基础的 Replace 示例

示例 1:全量文本替换

1
2
3
4
5
6
Sub ReplaceName()
    Range("A1:A100").Replace _
        What:="张三", _
        Replacement:="李四", _
        LookAt:=xlWhole
End Sub
示例 2:模糊替换(删除前缀)

1
2
3
4
Range("A1:A100").Replace _
    What:="测试*", _
    Replacement:="", _
    LookAt:=xlPart

示例 3:只替换“字体为红色”的单元格内容SearchFormat

1
2
3
4
5
6
7
8
Application.FindFormat.Clear
Application.FindFormat.Font.Color = RGB(255, 0, 0)

Range("A1:D100").Replace _
    What:="异常", _
    Replacement:="正常", _
    LookAt:=xlWhole, _
    SearchFormat:=True

通过设置SearchFormat:=True,搭配Application.FindFormat实现只有 红色字体的“异常” 才会被替换。

示例 4:替换内容并改成绿色字体ReplaceFormat

1
2
3
4
5
6
7
8
Application.ReplaceFormat.Clear
Application.ReplaceFormat.Font.Color = RGB(0, 176, 80)

Range("A1:D100").Replace _
    What:="完成", _
    Replacement:="已完成", _
    LookAt:=xlWhole, _
    ReplaceFormat:=True
通过设置ReplaceFormat:=True,搭配Application.ReplaceFormat实现替换内容的时候修改字体颜色。

示例 5:红色“异常” → 绿色“正常”SearchFormat + ReplaceFormat

Application.FindFormat.Clear
Application.ReplaceFormat.Clear

With Application.FindFormat
    .Font.Color = RGB(255, 0, 0)
End With

With Application.ReplaceFormat
    .Font.Color = RGB(0, 176, 80)
End With

Range("A1:D100").Replace _
    What:="异常", _
    Replacement:="正常", _
    LookAt:=xlWhole, _
    SearchFormat:=True, _
    ReplaceFormat:=True

四、Replace 的 6 个关键注意事项(必看)

  1. Replace 是不可逆操作,没有返回值, 不支持 “只替换第一个”,因此会把区域内全部替换,建议先备份
  2. Replace 同样会“记住上一次 Ctrl+H 设置”:和 Find 一样,尽量把 关键参数一律显式写出
  3. Replace 不支持 FindNext 逻辑:如果你需要:精确控制替换次数或者只替换某几条,应该用 Find + Replace 组合
  4. 通配符在 LookAt=xlWhole 时无效LookAt:=xlWhole 时 通配符 * ? 不生效,只有xlPart 才生效
  5. SearchFormat / ReplaceFormat 是全局状态:用前 Clear,用后也建议 Clear。
  6. Replace 只影响 Range 内部:例如 Range("A:A").Replace 只影响 A 列

VBA 中 RemoveDuplicates 用法简述

在 Excel VBA 中,如果需要对数据区域进行快速去重,最直接、最高效的方法就是 RemoveDuplicates。它等价于 Excel 界面中的:“数据 → 删除重复项”,语法结构可以写成下面这个式子:

Range.RemoveDuplicates Columns, Header

  • Columns —— 去重的列,可以是单列也可以是多列,例如Columns:=1(第1列)和Columns:=Array(1,2)(第1,2列)
  • Header —— 是否包含标题行,xlYes表示是,xlNo表示否,xlGuess表示让表格自己判断(不推荐)

示例 1:按单列去重

1
2
3
Range("A1:A100").RemoveDuplicates _
    Columns:=1, _
    Header:=xlYes
示例 2:按多列组合去重:如下表示 A 列 + B 列完全相同 的行视为重复

1
2
3
Range("A1:C100").RemoveDuplicates _
    Columns:=Array(1, 2), _
    Header:=xlYes

本期系统带大家梳理了VBA中查找、替换和去重三大方法,参数比较多,忘记的时候可以回来参考