最近在处理一张几千行的业务明细表时,同事问我:能不能一次性把“华东区”“已回款”“重要客户”这几个关键词同时筛出来?而且这些关键词分散在不同列,不是只筛某一列。我当时第一反应是“用高级筛选”,但试了一下发现高级筛选的多个条件属于“并且”逻辑,和我们要的“或者”逻辑不太一样。如果手动一条条条件去筛,表格字段一多,效率确实很低。
这篇文章就围绕“全表同时筛选多个关键词”这个真实需求,整理一套从入门到一劳永逸的完整方案。包含通配符条件格式、高级筛选的正确用法,以及一个可以一键高亮/筛选多关键词的 VBA 工具。无论你是做运营、财务、人事还是数据分析,只要经常在 Excel 里处理关键词匹配,都可以直接套用。
1. 需求分析:为什么“多个关键词”筛选这么麻烦
1.1 常见的筛选场景
先来看几个典型业务场景:
- 人事同事要从全表几百人里筛出“本科”“硕士”“重点大学”这些学历/院校关键词,但关键词分散在“学历”列和“毕业院校”列。
- 财务同事要对账单里的“已逾期”“已核销”“待复核”同时标记,这几个词分布在“状态”“备注”“结算说明”不同列。
- 运营同事要从用户反馈里找出包含“卡顿”“闪退”“无法登录”的意见记录,问题描述存在一列长文本中。
表面上看起来都是“筛选”,但实际上要满足两个条件:
- 关键词不限定在某一个固定列,而是全表范围内匹配。
- 多个关键词之间是“或者”关系,即只要某一列的单元格里包含任一关键词,这一行就要被筛出来。
1.2 手动操作的三个痛点
手动筛选模式下,你会遇到这些问题:
| 痛点 | 具体表现 |
|---|---|
| 单列筛选限制 | “包含”筛选只能针对当前列生效,无法自动扩展到其他列 |
| 多关键词难维护 | 每次换关键词都要重新设置筛选条件,关键词一多很难记 |
| 无法批量标记 | 筛选结果只能看,不能顺手给符合条件的行统一加颜色或状态 |
所以,真正“一劳永逸”的方案,应当做到:关键词集中维护、一键执行、结果可视化,而且不限制关键词数量。
2. 方案对比与选型思路
先看一张整体对比表,便于你根据自己的 Excel 水平选择。
| 方案 | 难度 | 适合场景 | 是否需要写代码 |
|---|---|---|---|
| 通配符+条件格式 | 入门 | 临时查看、少量关键词 | 否 |
| 高级筛选 | 入门 | 单列多关键词或全表单关键词 | 否 |
| 辅助列公式 | 中等 | 多列多关键词且需要动态结果 | 否 |
| VBA 宏 | 进阶 | 高频使用、一键完成、关键词可维护 | 是 |
这几种方案各有侧重:
- 条件格式适合“只看不筛”,适合给符合条件的数据加底色。
- 高级筛选的官方定位是“复杂条件筛选”,但它的同列多关键词需要借助通配符公式,而且跨列“或”逻辑也要单独构造条件区域。
- 辅助列公式是最稳妥的通用方案,不依赖任何高级功能,Excel 2016 以上都能用。
- VBA 宏把公式逻辑封装成按钮,适合需要长期重复操作的情况。
下面把这四种方案完整走一遍。
3. 基础方案一:通配符 + 条件格式标记关键词
3.1 通配符基础
Excel 里有三个最常用的通配符:
*代表任意多个字符。?代表任意一个字符。~用于转义,当你要匹配文本里真实的星号或问号时使用。
比如条件*华东*表示“包含华东”的任意文本。
3.2 条件格式实现步骤
先看一个实际例子。假设 A2:D20 是数据区域,A 列是客户名称,B 列是地区,C 列是状态,D 列是备注。现在要标记出“华东”“重要”“已回款”三个关键词。
操作步骤如下:
- 选中 A2:D20 整个数据区域。
- 点击“开始”选项卡 -> “条件格式” -> “新建规则”。
- 选择“使用公式确定要设置格式的单元格”。
- 输入公式:
=OR(ISNUMBER(SEARCH("华东",$A2&$B2&$C2&$D2)),ISNUMBER(SEARCH("重要",$A2&$B2&$C2&$D2)),ISNUMBER(SEARCH("已回款",$A2&$B2&$C2&$D2)))- 点击“格式”,在“填充”里选一个醒目的底色,比如浅黄色。
- 确认后,满足条件的整行就会被标记出来。
3.3 公式解释
这个公式的核心逻辑是:
- 用
$A2&$B2&$C2&$D2把当前行的四列内容拼接成一个完整的文本。 - 用
SEARCH函数判断拼接文本中是否包含某个关键词。 - 用
OR把多个关键词的判断结果串联起来,只要有一个成立就返回 TRUE。 - 条件格式中公式返回 TRUE 时,就应用你设置的格式。
这里要注意一个点:SEARCH不区分大小写,而且支持通配符。如果你要做精确的大小写匹配,可以把SEARCH换成FIND。
3.4 方案优缺点
这个方案的优点是完全不需要写代码,设置一次就能实时看到标记结果。缺点是它只能“标记”而不能真正“筛选”,而且关键词是写死在公式里的,以后要改关键词还是得进规则里修改。
4. 基础方案二:Excel 高级筛选的正确姿势
4.1 为什么常规筛选做不到
Excel 自带的“筛选”按钮,对一列做“文本包含”时,只能填一个关键词。有人会问:“筛选搜索框里不是可以输入多个关键词吗?”
搜索框确实支持输入多个词,但它对关键词之间默认是“并且”逻辑,而且是在当前列范围内搜索。比如你在某一列的搜索框输入“华东 回款”,它找的是同一单元格里既包含“华东”又包含“回款”的记录,并不是把“华东”和“回款”作为两个独立关键词去全表匹配。
4.2 高级筛选的正确用法
高级筛选的优势在于“条件区域”是独立的,可以灵活组合“并且”和“或者”关系。
假设数据在 Sheet1 的 A2:D20,表头分别是“客户名称”“地区”“状态”“备注”。我们要筛选出地区是“华东”的记录,同时备注里包含“回款”。
条件区域设置如下:
在 F1:H3 写:
F1: 地区 G1: 备注 F2: 华东 G2: =ISNUMBER(SEARCH("回款",D2))这里为了表达“备注包含回款”,条件区域的 G2 不能直接写“回款”,而要写成公式=ISNUMBER(SEARCH("回款",D2))。
然后点击“数据”选项卡 -> “高级”,列表区域选择$A$2:$D$20,条件区域选择$F$1:$G$2,勾选“将筛选结果复制到其他位置”,再指定一个空白区域的起始单元格,点击确定即可。
4.3 高级筛选的局限性
高级筛选项其实很强,但在“多个关键词 + 全表范围 + 或逻辑”这个需求面前有两个短板:
- 条件区域的公式规则比较绕,新手容易写错。
- 每次换关键词都要重设条件区域,基本谈不上“一劳永逸”。
所以高级筛选更适合临时性的单列多条件查询,不太适合做长期维护的关键词工具。
5. 进阶方案三:辅助列公式实现动态全表筛选
5.1 计算列思路
用一个辅助列来判断每一行是否包含任意关键词,再基于辅助列做筛选。这样关键词可以维护在固定位置,不需要每次修改公式。
还是以客户表为例。在 E2 写公式:
=IF(SUMPRODUCT(--ISNUMBER(SEARCH({"华东","重要","已回款"},$A2&$B2&$C2&$D2)))>0,"命中","")向下填充到数据最后一行。
5.2 公式逐段拆解
$A2&$B2&$C2&$D2:本行四列拼接为一个长字符串。SEARCH({"华东","重要","已回款"},...:用常量数组一次性查找三个关键词,返回三个结果,要么是数字,要么是#VALUE!错误。--ISNUMBER(...):把“是否找到”转换为 0 或 1。SUMPRODUCT对三个 0/1 结果求和。- 外层
IF:只要和大于 0,就说明至少命中一个关键词。
如果你用的是 Excel 365,也可以用更简单的写法:
=IF(OR(ISNUMBER(SEARCH({"华东","重要","已回款"},$A2&$B2&$C2&$D2))),"命中","")OR函数在 Excel 365 中支持数组运算,老版本则必须使用SUMPRODUCT才能得到正确结果。
5.3 辅助列与自动筛选搭配
操作步骤:
- 在 E2 写好公式并向下填充。
- 选中数据区域,点击“数据”选项卡 -> “筛选”。
- 点击 E 列筛选按钮,只勾选“命中”。
这样就实现了全表范围内的“或”逻辑筛选。
5.4 把关键词维护区独立出来
公式里直接写常量数组,维护起来不够友好。更专业的做法是把关键词放在一个独立区域。
比如在 M1:M3 分别填入三个关键词:
| 单元格 | 内容 |
|---|---|
| M1 | 华东 |
| M2 | 重要 |
| M3 | 已回款 |
然后用绝对引用引用这个区域:
=IF(SUMPRODUCT(--ISNUMBER(SEARCH($M$1:$M$3,$A2&$B2&$C2&$D2)))>0,"命中","")注意:SEARCH的第一个参数如果是区域,需要按Ctrl+Shift+Enter确认数组公式(Excel 365 除外)。老版本里公式输入完成后,公式栏两侧会出现花括号。
以后要改关键词,直接修改 M 列内容,辅助列会自动刷新,这就是“维护一次、长期使用”的雏形。
6. VBA 终极方案:一键完成多关键词筛选与高亮
6.1 为什么还需要 VBA
辅助列方案虽然能动态筛选,但还是需要手动给列填充公式、手动筛选结果。如果要求“一键完成”,并且同时做两件事:
- 给符合条件的数据行加底色。
- 自动隐藏不符合条件的行。
用 VBA 是最合适的选择。
6.2 VBA 代码完整版
先按Alt+F11打开 VBA 编辑器,点击“插入” -> “模块”,把下面的代码复制进去。
Sub MultiKeywordFilter() Dim ws As Worksheet Dim dataRange As Range Dim keywordRange As Range Dim cell As Range Dim kwCell As Range Dim i As Long, j As Long Dim rowData As String Dim hasMatch As Boolean ' 设置工作表,这里以当前活动工作表为例 Set ws = ActiveSheet ' 数据区域:假设数据从 A2 开始,最后一行由 A 列决定 ' 你可以根据实际表结构修改起始列和结束列 Dim lastRow As Long Dim lastCol As Long lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column If lastRow < 2 Then MsgBox "没有找到数据,请检查A列是否有内容", vbExclamation Exit Sub End If Set dataRange = ws.Range(ws.Cells(2, 1), ws.Cells(lastRow, lastCol)) ' 关键词区域:假设关键词存放在 M1 向下连续区域 ' 你可以修改为任意指定区域 Set keywordRange = ws.Range("M1:M10") ' 统计关键词数量 Dim kwCount As Long kwCount = Application.WorksheetFunction.CountA(keywordRange) If kwCount = 0 Then MsgBox "M列没有关键词,请先在M1:M10输入关键词", vbExclamation Exit Sub End If ' 第一步:清除原有底色 dataRange.Interior.ColorIndex = xlNone ' 第二步:显示所有行,避免上次筛选影响本次判断 ws.Rows.Hidden = False ' 第三步:遍历每一行 For i = 1 To dataRange.Rows.Count hasMatch = False ' 拼接当前行所有列的内容 rowData = "" For j = 1 To dataRange.Columns.Count rowData = rowData & "|" & CStr(dataRange.Cells(i, j).Value) Next j ' 遍历关键词列表 For Each kwCell In keywordRange If Trim(CStr(kwCell.Value)) <> "" Then If InStr(1, rowData, Trim(CStr(kwCell.Value)), vbTextCompare) > 0 Then hasMatch = True Exit For End If End If Next kwCell ' 如果命中关键词,整行加底色 If hasMatch Then dataRange.Rows(i).Interior.Color = RGB(255, 255, 0) End If Next i MsgBox "处理完成!命中关键词的行已标记为黄色。", vbInformation End Sub6.3 代码参数说明
代码里有几个地方可以根据实际情况调整:
Set ws = ActiveSheet:当前工作表。如果固定要用某一张表,可以改成Set ws = ThisWorkbook.Worksheets("Sheet1")。lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row:以 A 列最后一行作为数据的最后一行。如果你的数据在 B 列或 C 列开始,需要把数字 1 改掉。lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column:以第 1 行最后一个非空列作为数据最后一列。keywordRange:关键词存放区域,默认是M1:M10。关键词可以只有 3 个,也可以填满 10 个,甚至更多,只需要修改这个范围。InStr(1, rowData, kw, vbTextCompare):不区分大小写判断关键词是否存在于拼接后的文本中。
6.4 一键运行的三种方式
方式一:F5 直接运行
在 VBA 编辑器里,光标放到MultiKeywordFilter过程内部,按 F5 即可运行。
方式二:插入按钮
- 在 Excel 中点击“开发工具” -> “插入” -> “按钮(窗体控件)”。
- 在弹出的对话框里选择
MultiKeywordFilter。 - 把按钮放到表格合适位置,右键按钮可以修改文字,比如改成“一键筛选关键词”。
如果找不到“开发工具”选项卡,需要到“文件” -> “选项” -> “自定义功能区”,在右侧勾选“开发工具”。
方式三:快速访问工具栏
- 点击快速访问工具栏最右侧的下拉箭头,选择“其他命令”。
- 在“从下列位置选择命令”里选“宏”。
- 选中
MultiKeywordFilter,点击“添加”。 - 以后点一下快速访问工具栏里的按钮就能运行。
6.5 如何把“高亮”升级为“筛选”
上面代码只做了高亮,没有隐藏不匹配的行。如果你想一键筛掉不匹配的行,可以在遍历行时增加一个EntireRow.Hidden操作。
把第三步的代码改为:
' 先全部显示 ws.Rows.Hidden = False For i = 1 To dataRange.Rows.Count hasMatch = False rowData = "" For j = 1 To dataRange.Columns.Count rowData = rowData & "|" & CStr(dataRange.Cells(i, j).Value) Next j For Each kwCell In keywordRange If Trim(CStr(kwCell.Value)) <> "" Then If InStr(1, rowData, Trim(CStr(kwCell.Value)), vbTextCompare) > 0 Then hasMatch = True Exit For End If End If Next kwCell ' 未命中的行隐藏 If Not hasMatch Then dataRange.Rows(i).EntireRow.Hidden = True End If Next i这样运行后,只有包含关键词的行会被保留。注意:EntireRow.Hidden = True会把整行隐藏,包括数据区域外的内容。如果你的数据行下方还有其他统计内容,建议先规划好再使用。
6.6 VBA 的安全注意
Excel 默认会禁用带宏的文件。在使用宏之前:
- 将文件另存为“Excel 启用宏的工作簿(.xlsm)”。
- 打开文件时,如果出现黄色安全条,点击“启用内容”。
- 企业环境如果需要长期使用,可以让管理员将文件所在目录加入受信任位置。
7. 常见问题与排查清单
在实际使用过程中,下面几个问题出现频率最高。
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 条件格式只标记了一个单元格,而不是整行 | 公式中行号前少了$ | 公式应写成$A2&$B2&$C2&$D2,并对列绝对引用 |
| 高级筛选结果为空 | 条件区域公式引用相对位置不对 | 检查公式引用的单元格是否是数据第一行 |
辅助列公式返回溢出或#VALUE! | 老版本 Excel 没有按数组公式确认 | 按Ctrl+Shift+Enter重新确认公式 |
| VBA 提示找不到关键字 | 关键词存放在 M 列,但代码里匹配范围不对 | 修改keywordRange,或把关键词移到 M1:M10 |
| 运行 VBA 后没有反应 | 文件未启用宏 | 另存为 .xlsm 并点击“启用内容” |
| VBA 把无关行也隐藏了 | 隐藏的是EntireRow而不是数据单元格 | 确认数据区域内是否还有其他内容 |
| 关键词包含通配符 | SEARCH和InStr对通配符处理不同 | SEARCH支持通配符,InStr按字符精确匹配 |
7.1 排查步骤建议
遇到问题时,按以下顺序检查:
- 先确认关键词区域数据是不是文本格式。如果关键词是从网页或 PDF 复制来的,可能包含不可见空格,用
TRIM清洗。 - 再确认数据区域最后一个非空行是否被 VBA 正确识别。
- 然后检查公式或代码中的引用是否全部正确。
- 最后用
MsgBox在 VBA 里输出中间结果,比如拼接后的rowData,确认拼接文本是否包含了关键词。
8. 工程化建议:把关键词工具做成可维护的系统
8.1 把关键词放到独立配置表
关键词散落在公式或 VBA 代码里,时间一长就会忘。推荐单独建一个“参数配置”工作表。
结构可以这样设计:
| 区域 | 内容 | 说明 |
|---|---|---|
| B2 | 关键字列表 | 每个关键词一行 |
| C2 | 是否启用 | TRUE / FALSE |
| D2 | 匹配列范围 | 比如 A:D,表示全表匹配 |
VBA 读取时,可以把keywordRange改为引用参数配置表:
Set keywordRange = ThisWorkbook.Worksheets("参数配置").Range("B2:B10")这样即使换了业务表,也不需要改代码,只改配置表即可。
8.2 增加“清空标记”按钮
实际使用中,你可能需要反复执行“清除颜色 -> 重新标记”。可以单独写一个清空过程:
Sub ClearHighlight() Dim ws As Worksheet Dim dataRange As Range Dim lastRow As Long Dim lastCol As Long Set ws = ActiveSheet lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column If lastRow >= 2 Then Set dataRange = ws.Range(ws.Cells(2, 1), ws.Cells(lastRow, lastCol)) dataRange.Interior.ColorIndex = xlNone ws.Rows.Hidden = False End If End Sub8.3 生产环境注意事项
虽然 Excel 不是服务器系统,但在实际业务表上操作时,以下几点仍然重要:
- 操作前先备份原文件,避免格式错乱或数据被误隐藏。
- 不要直接在原始报表上跑 VBA,最好复制一份数据到工作副本再处理。
- 如果表格有合并单元格,建议先取消合并,因为 VBA 遍历合并单元格时可能出现非预期行为。
- 如果数据量超过几万行,遍历拼接字符串和
InStr判断的性能会明显下降,可以先限制匹配列范围,或者改用字典+数组的方式优化。
8.4 VBA 性能优化思路
当数据行数较多时,逐单元格读写会拖慢速度。可以先把数据读入数组,在内存中完成匹配,再一次性写入结果。
核心思路如下:
Sub MultiKeywordFilterFast() Dim ws As Worksheet Dim dataArr As Variant Dim keywordArr As Variant Dim lastRow As Long Dim lastCol As Long Dim i As Long, j As Long, k As Long Dim matchRows() As Long Dim matchCount As Long Set ws = ActiveSheet lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column If lastRow < 2 Then Exit Sub ' 一次性把数据读入数组 dataArr = ws.Range(ws.Cells(2, 1), ws.Cells(lastRow, lastCol)).Value ' 读取关键词列表(取前10个非空值) keywordArr = ws.Range("M1:M10").Value ReDim matchRows(1 To lastRow - 1) matchCount = 0 For i = 1 To UBound(dataArr, 1) Dim rowText As String rowText = "" For j = 1 To UBound(dataArr, 2) rowText = rowText & "|" & CStr(dataArr(i, j)) Next j For k = 1 To 10 Dim kw As String kw = Trim(CStr(keywordArr(k, 1))) If kw <> "" Then If InStr(1, rowText, kw, vbTextCompare) > 0 Then matchCount = matchCount + 1 matchRows(matchCount) = i + 1 Exit For End If End If Next k Next i ' 先清除颜色和隐藏状态 ws.Range(ws.Cells(2, 1), ws.Cells(lastRow, lastCol)).Interior.ColorIndex = xlNone ws.Rows.Hidden = False ' 再统一标记 For i = 1 To matchCount ws.Rows(matchRows(i)).Interior.Color = RGB(255, 255, 0) Next i End Sub这个版本大大减少了 Excel 与 VBA 之间的交互次数,数据量较大时性能提升非常明显。
9. 各方案如何选择
没有绝对最好的方案,只有最适合当前场景的方案。我建议按下面这个逻辑来选择。
- 如果你只是临时看一次数据,用条件格式就够了,设置快、不污染原表。
- 如果你是偶尔筛选,且关键词固定,用辅助列公式最稳妥,不需要启用宏。
- 如果你每周甚至每天都要做同样的关键词筛选,建议直接上 VBA,把关键词维护在固定区域,配合按钮一键执行。
- 如果你使用的是新版 Excel 且数据量很大,也可以考虑
FILTER+ISNUMBER(SEARCH(...))的组合,运算效率高于辅助列。
一个实用的 Excel 365 写法示例:
=FILTER(A:D,ISNUMBER(SEARCH("华东",A:A&B:B&C:C&D:D))+ISNUMBER(SEARCH("重要",A:A&B:B&C:C&D:D))+ISNUMBER(SEARCH("已回款",A:A&B:B&C:C&D:D))>0)这个公式直接在空白区域输出所有命中行,但需要 Excel 365 支持动态数组函数。
10. 日常维护关键词工具的三个习惯
任何工具好不好用,很大程度上取决于日常维护习惯。
10.1 关键词统一放在首位
不管用哪种方案,都建议把关键词放在一个醒目且固定的位置。比如每个工作簿都约定 M 列是关键词区,这样换人接手也能快速找到。
10.2 定期备份参数配置
VBA 工程可以导出为.bas文件备份,关键词配置表也可以用单独的模板保存。下次新建业务表时,直接把模板带进去,不用重复写代码。
10.3 测试先行
给正式数据执行 VBA 之前,先复制一个小规模测试数据跑一遍,确认关键词匹配结果符合预期。尤其是新增关键词时,要先检查有没有“误伤”,比如关键词“华东”可能会匹配到“华东大区”,这未必是你想要的。
如果确实需要对完整单元格做精确匹配,可以把InStr判断换成StrComp或者先判断长度再判断内容。
结语
全表同时筛选多个关键词这个需求,看起来只是一个小操作,但真正用起来会发现,手动筛选的重复成本非常高。条件格式适合快速标记,辅助列公式适合动态筛选,VBA 适合高频一键执行。三者之间没有互斥关系,组合使用效果最好。
建议你先从辅助列公式入手,理解SEARCH+SUMPRODUCT的核心逻辑,然后照着 VBA 代码搭建一个属于自己的关键词筛选模板。以后不管来多少批数据,只要把关键词填进指定区域,点一下按钮,结果就会自动呈现出来。