做数据分析或者表格处理的人,几乎都遇到过同一个尴尬场景:一张几千行甚至上万行的明细表,领导突然让你把“华东大区、数码品类、状态为已发货”的订单都筛出来。你打开自动筛选,先选大区,再选品类,然后还要在状态列慢慢勾选。这还算好的,更痛苦的是老板说“把名称里包含手机、平板、耳机、充电器这几个词的全部挑出来”,自动筛选只有一个关键词输入框,你只能筛一次,复制出去,再筛下一个,再复制,来回折腾半小时,最后表格还被搞得一团糟。
这个问题的根源在于,很多人把“筛选”理解成了自动筛选自带的那几个按钮,而自动筛选的本质是单层条件过滤。一旦条件变成“多个关键词、任意命中、跨列组合”,它就力不从心了。实际上,Excel 和 WPS 都提供了能够“一劳永逸”的多关键词筛选方案,既能做到全表匹配,又能保留原始数据,甚至可以一键自动完成。这篇文章就把最常用的三种方法一次讲透,从函数公式到高级筛选,再到 VBA 一键处理,每一种都会说明适用场景和易错点,你可以直接照着抄。
1. 多关键词筛选到底难在哪里
先把这个问题的复杂度拆开看。一张业务表格通常会包含多个维度:客户名称、商品名称、区域、金额、状态、时间。用户说“多关键词筛选”,实际上会对应三种不同的需求,它们的技术难度是完全不一样的。
第一种,也是最常见的需求:某一列中,只要包含多个关键词中的任意一个,就算命中。比如商品名称里包含“手机”或“平板”的行都要留下,这叫“同列多关键词或匹配”。
第二种需求是跨列组合匹配:区域是“华东”并且品类是“数码”,这种多列同时满足的条件,在自动筛选里需要分列多次操作,在高级筛选里则需要把条件放在同一行。
第三种需求是扩展场景:既要同列多个关键词任意命中,又要同时满足另一个列的区间条件。例如“商品名称包含手机或平板,且数量大于 10”。
理解难度在哪里?难在大多数人没有分清“或”和“且”的区别。自动筛选做的隐藏逻辑其实是保留所有“且”条件同时成立的数据行,而你要做的是“或”逻辑时,自动筛选根本没法直接表达。还有很多人建议用 VLOOKUP 模糊匹配来做,但 VLOOKUP 只能返回第一个匹配到的值,并不能把符合条件的所有行都筛出来。所以,多关键词筛选真正的核心不是“筛选”这个动作,而是如何正确构造条件判断逻辑,再把判断结果交给筛选机制。
2. 核心概念:筛选的三种技术路线对比
在动手操作之前,先建立一个整体认知。实现全表多关键词筛选,主流有三条技术路线,各有各的适用场景。
| 技术路线 | 核心机制 | 优势 | 局限 |
|---|---|---|---|
| 高级筛选 | 使用条件区域,同一行条件表示“且”,不同行表示“或” | 原生功能,不写公式,支持通配符,可直接筛选到其他位置 | 条件区域需要单独维护;条件更新后需要重新执行 |
| 函数公式 + 筛选 | 用 SEARCH、ISNUMBER、FILTER 判断关键词并生成动态结果 | 公式结果自动更新,适合做动态报告 | FILTER 函数需要 Excel 365 或新版 WPS,旧版本不兼容 |
| VBA 宏一键筛选 | 用代码遍历数据区域,通过 InStr 判断关键词 | 全自动,可以封装成按钮,适合高频重复场景 | 需要启用宏,对小白有心理门槛 |
需要特别注意“精确匹配”和“模糊匹配”的差别。高级筛选和 SEARCH 函数默认都是模糊包含匹配,也就是单元格里只要出现关键词就算命中。如果你需要完全相等的结果,比如筛选状态列等于“已发货”,那么不能用通配符包含的方式,而应该用=已发货的条件写法,否则会造成误匹配。后面的示例会具体说明。
3. 环境准备与前置条件
这篇文章的三种方法都基于桌面版 Excel 或 WPS 表格操作,不需要安装任何插件。你需要准备的是:
- 操作系统:Windows 或 macOS 均可,但 VBA 宏在 Windows 端体验最好。
- 软件版本:Excel 2016、2019、2021、365 均可运行高级筛选和 VBA 方案;方法二中的 FILTER 函数是动态数组函数,建议使用 Excel 365 或新版 WPS 表格,旧版本 Excel 使用时可以用辅助列 + 自动筛选替代,也能达到类似效果。
- 示例数据:建议先在一张不重要的表上练习,避免误操作覆盖原始数据。
文中演示统一使用下面这张销售明细表作为素材,列结构包括:区域、商品名称、数量、金额、状态。实际操作时,把列名和关键词替换成你自己的业务字段即可。
| 区域 | 商品名称 | 数量 | 金额 | 状态 |
|---|---|---|---|---|
| 华东 | 华为手机 Mate 60 | 5 | 34990 | 已发货 |
| 华南 | 苹果平板 iPad Air | 3 | 14199 | 待发货 |
| 华东 | 索尼耳机 WH-1000XM5 | 8 | 15992 | 已发货 |
| 华北 | 小米充电器 67W | 20 | 2798 | 已发货 |
| 西南 | 联想笔记本 拯救者 | 2 | 15998 | 已取消 |
| 华东 | 华为平板 MatePad | 6 | 11994 | 已发货 |
| 华南 | 三星耳机 Galaxy Buds | 10 | 4990 | 待发货 |
| 华北 | 绿联充电器 20W | 15 | 1498 | 已发货 |
4. 入门方案:Excel 高级筛选,不写公式也能完成多关键词筛选
高级筛选是 Excel 中最被低估的原生功能,要处理“同列多关键词或匹配”和“跨列组合条件”,它都不需要写任何函数。核心思路是把筛选条件预先写到表格的某个空白区域,然后再告诉 Excel 去执行。
4.1 第一步:准备条件区域
高级筛选的第一步是构造条件区域。条件区域必须包含表头,而且表头必须和数据区域的列名完全一致。比如要筛选“商品名称包含手机或平板”的行,先找一个空白位置,比如 H1 单元格开始建条件区域。
H1 单元格输入“商品名称”,H2 输入“=手机”,H3 输入“=平板”。这里有个关键规则:条件写在同一列的不同行,表示“或”的关系。也就是说,商品名称只要命中手机或平板,这行数据就会被筛选出来。
4.2 第二步:执行高级筛选
- 选中数据区域中的任意一个单元格。
- 在 Excel 的“数据”选项卡中,点击“高级”按钮。
- 弹出的高级筛选对话框里,“列表区域”默认显示整个数据表区域,确认即可。
- “条件区域”选择 H1:H3。
- 可以选择“在原有区域显示筛选结果”,也可以选择“将筛选结果复制到其他位置”,后者不会动原始数据。
点击确定后,Excel 就会把所有商品名称含“手机”或“平板”的行筛出来。如果是跨列组合筛选,比如“区域为华东且状态为已发货”,条件区域就应该写成同一行:
| 区域 | 状态 |
|---|---|
| 华东 | 已发货 |
同一行条件是“且”关系,不同行条件是“或”关系,这是高级筛选最重要的记忆点。
4.3 注意事项与实际风险
高级筛选在写入“=手机”这类条件时,看起来很像公式,但它不是标准公式,而是高级筛选专用的条件表达式。手动输入时,单元格里显示的就是=手机,不要在前面加等号以外的内容。如果发现没有筛出任何结果,第一件事就是检查条件区域是否包含表头,第二检查条件表达式是否以=号开头。
高级筛选的另一个优势是支持多列自由组合,比如“华东大区、商品名称含手机或平板、数量大于等于 5”这种复杂条件,只要把同列关键词分行写、不同列条件同行写,就能正确表达。对于普通办公场景,这个方案就已经能解决 90% 的问题了。
5. 进阶方案:FILTER + SEARCH 函数实现动态多关键词筛选
高级筛选虽然好用,但它有一个天然缺点:每次数据更新,或者关键词变化,都要手动重新执行一次。如果领导隔三差五换个关键词池,你会被反复操作烦死。这时候就应该上函数公式方案,让筛选结果自动刷新。
5.1 先理解 FILTER 函数
FILTER 是 Excel 365 和动态数组版本提供的新函数,语法是:
=FILTER(要返回的区域, 条件, 无结果时的值)第二个参数是一个由 TRUE/FALSE 组成的判断数组。返回区域可以包含多列,比如 A2:E9 代表返回整张表的 5 列。理解了这个基础用法,多关键词筛选的核心就变成了如何构造这个 TRUE/FALSE 判断数组。
5.2 用 ISNUMBER + SEARCH 实现关键词包含判断
单独一个关键词的包含判断,可以写成:
ISNUMBER(SEARCH("手机", A2:A9))这个公式的含义是:在 A2:A9 中搜索“手机”,能找到就返回位置数字,找不到就返回 #VALUE! 错误,再用 ISNUMBER 判断是否为数字,从而得到 TRUE 或 FALSE 的结果。之所以用 SEARCH 而不是 FIND,是因为 SEARCH 不区分大小写,更符合人习惯的模糊匹配,而 FIND 区分大小写,适合精确字符匹配场景。
现在要让“手机、平板、耳机、充电器”四个关键词任意一个命中,就需要把它们合并成一个“关键词池”,用数组方式传给 SEARCH:
ISNUMBER(SEARCH({"手机","平板","耳机","充电器"}, A2:A9))注意关键点:SEARCH 的第二个参数是区域,第一个参数是数组常量,这个公式会生成一个二维数组,每个单元格对应每个关键词的判断结果。只要这个二维数组里存在一个 TRUE,就说明该行命中了任意一个关键词。
因为 FILTER 的条件参数需要的是一个一列的逻辑数组,所以需要在外面套一个判断,判断每个单元格是否存在至少一个命中:
=BYROW(ISNUMBER(SEARCH({"手机","平板","耳机","充电器"}, A2:A9)), LAMBDA(row, OR(row)))这个公式稍微复杂,但对于新人来说可以直接复制使用,只需要修改关键词数组和数据区域范围。如果觉得 LAMBDA 难以理解,也可以退一步,用辅助列方式逐个关键词判断,再把结果用 OR 合并,效果是一样的。
5.3 将判断结果接入 FILTER
最终公式如下:
=FILTER(A2:E9, BYROW(ISNUMBER(SEARCH({"手机","平板","耳机","充电器"}, B2:B9)), LAMBDA(row, OR(row))), "无匹配数据")这里我把关键词判断放在商品名称列 B2:B9 上,返回区域是 A2:E9 整行数据。公式输入后,Excel 会自动溢出一个动态数组区域,显示所有符合条件的行。
如果还要同时满足“数量大于等于 5”这个条件,把数量条件用乘法叠加进去,公式变为:
=FILTER(A2:E9, BYROW(ISNUMBER(SEARCH({"手机","平板","耳机","充电器"}, B2:B9)), LAMBDA(row, OR(row))) * (C2:C9>=5), "无匹配数据")因为 TRUE 乘以 TRUE 等于 1,只要有一个条件不成立,结果就是 0,FILTER 会自动过滤掉。
5.4 旧版 Excel 的替代写法
如果你用的是 Excel 2016 或 2019,没有 FILTER 和 BYROW 函数,那么推荐用辅助列方案。先在 F2 输入下面这条数组公式,然后按 Ctrl + Shift + Enter 确认:
=IF(OR(ISNUMBER(SEARCH({"手机","平板","耳机","充电器"}, B2))), "命中", "")下拉填充后,F 列会标注所有命中的行。对这个辅助列启用自动筛选,选择“命中”即可。这种方式虽然没有 FILTER 那么优雅,但兼容性好,旧版本也能用。
5.5 使用表格功能提升公式可维护性
有一件事强烈建议做:把数据区域转换为“表格”,也就是按 Ctrl + T 创建超级表。转换后公式里的区域引用会变成结构化引用,比如 B2:B9 会变成 [商品名称],数据增加时公式可以自动扩展,不需要每次手动改区域范围。具体操作是选中数据区域,按 Ctrl + T,然后勾选“表包含标题”。这时再在旁边的辅助列输入公式,Excel 会自动填充到最后一行,新添加的数据行也会自动继承公式。
6. 专业方案:VBA 宏一键完成多关键词筛选
函数公式虽然动态,但面对“每次筛选关键词经常变、筛选完还要复制到新工作表、甚至要把多个关键词池做成下拉选项”的场景,写 VBA 宏才是最终方案。这个方案的思路是把关键词放在一个指定区域,宏自动读取关键词,然后遍历数据行,用 InStr 判断每行是否命中任意关键词,最后把命中的行复制到目标工作表。
6.1 示例宏代码
这段宏的逻辑是:从“条件设置”工作表的 A1:A10 读取关键词,从“数据源”工作表的 A1:E1000 读取数据,再把所有命中的行复制到“筛选结果”工作表。
Sub MultiKeywordFilter() Dim wsData As Worksheet Dim wsCond As Worksheet Dim wsResult As Worksheet Dim keywords() As String Dim i As Long, j As Long Dim lastRow As Long Dim lastCol As Long Dim matchFlag As Boolean Dim targetRow As Long Dim keywordCount As Long Set wsData = ThisWorkbook.Sheets("数据源") Set wsCond = ThisWorkbook.Sheets("条件设置") Set wsResult = ThisWorkbook.Sheets("筛选结果") keywordCount = Application.WorksheetFunction.CountA(wsCond.Range("A1:A10")) If keywordCount = 0 Then MsgBox "条件设置工作表的 A1:A10 中至少需要一个关键词", vbExclamation, "提示" Exit Sub End If ReDim keywords(1 To keywordCount) For i = 1 To keywordCount keywords(i) = wsCond.Range("A" & i).Value Next i lastRow = wsData.Cells(wsData.Rows.Count, 1).End(xlUp).Row lastCol = wsData.Cells(1, wsData.Columns.Count).End(xlToLeft).Column wsResult.Cells.Clear ' 复制表头 wsData.Range("A1").Resize(1, lastCol).Copy wsResult.Range("A1") targetRow = 2 ' 从第2行开始遍历数据 For i = 2 To lastRow matchFlag = False Dim cellText As String cellText = wsData.Cells(i, 2).Value ' 假设关键词匹配列是B列商品名称 For j = 1 To keywordCount If InStr(1, cellText, keywords(j), vbTextCompare) > 0 Then matchFlag = True Exit For End If Next j If matchFlag Then wsData.Rows(i).Copy wsResult.Rows(targetRow) targetRow = targetRow + 1 End If Next i MsgBox "筛选完成,共找到 " & targetRow - 2 & " 条记录", vbInformation, "完成" End Sub这段代码有几个地方需要根据实际表结构调整:一是关键词读取区域“条件设置!A1:A10”,二是数据区域表名“数据源”、结果表名“筛选结果”,三是匹配列,代码中假设是第 2 列商品名称,如果你的关键词要匹配的是客户名称或者其他列,需要修改wsData.Cells(i, 2)中的列号。
6.2 VBA 宏的使用步骤
- 打开 Excel,按 Alt + F11 进入 VBA 编辑器。
- 在菜单栏点击“插入” -> “模块”,新建一个模块。
- 把上面的代码粘贴到代码窗口中。
- 回到 Excel,在工作簿中创建三个工作表,分别命名为“数据源”“条件设置”“筛选结果”。
- 在“数据源”表中放入原始数据,“条件设置”表的 A1 开始输入关键词,一个单元格一个关键词。
- 按 Alt + F8,选择 MultiKeywordFilter,点击运行。
运行结束后,“筛选结果”表会生成表头和所有命中的行。这段宏还有优化的空间,比如把关键词匹配从 B 列改成多列匹配,或者在遍历前用数组一次性读取数据加快速度,但对于几万行的数据来说,当前写法足够日常使用。
7. 运行结果与效果验证方法
无论使用哪种方案,筛选完成后都必须验证结果是否正确。这不是可选项,而是避免交付错误数据的关键步骤。
验证方法一:数量核对。在原始数据中,手动用自动筛选分别搜索每个关键词,记录每个关键词独立命中的行数,再和有交集的行做对比,确保最终结果的行数合理。如果使用 VBA 宏,弹窗会直接提示“共找到 X 条记录”,你可以把这个数字和高级筛选结果对比。
验证方法二:抽查关键行。在结果表中抽查几条边界数据,尤其注意那些包含多个关键词的复杂名称,比如“华为手机 Mate 60”同时包含“手机”,也应该被筛出来。还要检查状态为“已取消”的行是否被保留,如果不希望保留,就要在条件中增加状态列的条件。
验证方法三:关键词池有效性。把所有关键词清空后再测试,确认高级筛选是否报错、FILTER 公式是否返回“无匹配数据”、VBA 宏是否弹出提示。这个测试可以避免业务人员误操作导致“筛选结果空白”的假象。
一个非常容易犯的错误是:关键词中有空格。比如你输入的是“手机 ”和“手机”,看起来差不多,但 InStr 匹配时会把带空格的关键词当作不同的文本,造成漏匹配。建议在 VBA 宏中加入 Trim 函数去除关键词首尾空格,函数公式方案中同样可以用 TRIM 包裹关键词。
8. 常见问题与排查思路
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 高级筛选结果为空 | 条件区域表头和数据表头不一致 | 检查条件区域表头是否包含不可见空格或别名 | 重新输入完全一致的列名,或用复制粘贴方式填入表头 |
| 高级筛选自动把结果覆盖到原始区域 | 选择了“在原有区域显示筛选结果” | 检查对话框设置 | 改选“将筛选结果复制到其他位置”,并指定一个空白目标区域 |
| FILTER 公式返回 #CALC! 错误 | 没有匹配的行,且没有设置无结果时的值 | 检查第三个参数 | 在公式末尾补充“无匹配数据”,避免错误显示 |
| BYROW 公式在部分 Excel 版本不可用 | 旧版本不支持动态数组函数 | 查看版本信息 | 改用辅助列 + OR 的方式,或者使用高级筛选 |
| VBA 宏提示下标越界 | 工作表名称不存在 | 检查工作簿是否有“数据源”“条件设置”“筛选结果”三个工作表 | 统一工作表名称后重试 |
| 宏筛选出的结果比预期少 | 关键词匹配列不是目标列 | 检查代码中Cells(i, 2)的列号 | 修改为实际匹配的列号,比如 A 列是 1,C 列是 3 |
| 关键词包含英文但大小写不一致 | SEARCH 和 InStr 默认行为不同 | 确认是否区分大小写 | 函数方案用 SEARCH 不区分大小写,VBA 用 vbTextCompare 参数保证不区分 |
真实业务中最容易出问题的是第一条:条件区域的表头和数据表头“看着一致,实际不一致”。常见的原因是列名有空格、全角半角差异,或者手工输入时把“商品名称”写成了“商品 名称”。高级筛选对表头匹配的要求非常严格,遇到筛选结果异常时请第一时间检查表头。
9. 最佳实践与工程建议
9.1 把关键词参数化,不要写死在公式里
函数公式方案中,如果关键词直接写在公式里,每次换关键词都要编辑公式,容易出错,也不利于他人维护。更推荐的做法是把关键词预先写在空白单元格区域,然后公式引用这个区域。对于 FILTER 方案,可以把关键词区域定义成名称,比如定义名称关键词池引用某个区域,然后在 SEARCH 中直接使用关键词池。这样业务人员只需要维护关键词列表,不需要动公式。
9.2 建立条件区域模板,形成标准操作流程
高级筛选的条件区域建议固定放在某个工作表或者某个固定区域,比如 A1 下偏移 3 列的位置,并给条件区域加上边框和底色,防止其他人误删。同时把条件区域设计成通用模板:一行放“且”条件,下面预留几行放“或”条件。这样即使换一个同事来操作,也能按模板完成添加条件。
9.3 使用表格和动态引用降低维护成本
无论用哪种方案,都建议把数据源转换成表格(Ctrl + T)。这样做有三个好处:一是区域引用自动扩展;二是辅助列公式自动填充;三是高级筛选的“列表区域”在选择时会自动识别整个表格。数据量大时,还可以通过表格的“表设计”选项卡的“调整表格大小”功能快速修改范围。
9.4 大数据量时的性能优化
当数据量达到十万行以上,VBA 遍历单元格的方式会明显变慢。优化的方向是把数据一次性读入数组,循环判断后再写回结果区域,而不是逐行复制。函数公式方案中,FILTER 和 BYROW 在十万行以内通常没有问题,但如果你有几十万行数据,建议先在原始数据上执行高级筛选,或者用 Power Query 做条件过滤,而不是在单元格里堆公式。
9.5 安全与备份意识
在 VBA 宏运行前,尤其是第一次在新环境下运行,先备份一份原始数据。宏的Cells.Clear会清空筛选结果表的内容,如果目标区域设置错误,可能误清空数据。建议在代码中把目标表固定为“筛选结果”,并设置一个提示机制。生产环境中使用宏,还需要注意启用宏的工作簿在打开时会弹出安全警告,需要信任来源后才能运行。
10. 总结与后续学习方向
多关键词筛选不是一个简单的按钮功能,它背后是查询逻辑中“或与且”的条件组合能力。高级筛选适合一次性快速出结果;FILTER + SEARCH 函数方案适合需要动态更新的报表;VBA 宏适合高频、重复、需要自动化的流程。三者结合使用,基本能覆盖 95% 以上的表格多条件筛选场景。
如果这篇文章对你有帮助,可以收藏备用。下一步建议你拿着自己的真实表格,分别用三种方法跑一遍,重点练习条件区域的“同行且、不同行或”规则,以及 FILTER 公式中的 BYROW 组合。真正理解了这两点,以后再遇到“多条件、多关键词、模糊匹配”的筛选需求,你就能直接判断用哪个方案最合适,而不用再手动一个个复制粘贴了。