还在为一次筛选就要手动复制、粘贴、删重复值而烦躁吗?Excel 自 2018 年起引入的动态数组,改变了公式"一个单元格只出一个值"的老规矩:在左上角按下一次回车,结果会自动铺满一整片区域。FILTER、UNIQUE、SORT 这三个函数,正是让表格从"死数据"变成"活报表"的关键。
先搞懂"溢出":动态数组到底改了什么
要理解这三个函数,得先接受一个新概念:公式可以返回一整片结果,而不只是一个值。
从 Ctrl+Shift+Enter 到直接回车
在动态数组出现之前,想用一个公式算出多个结果,得用"旧版数组公式"(也叫 CSE 公式):先框选出结果要占用的整个区域,再按 Ctrl+Shift+Enter 确认,公式两边会自动补上大括号。它的毛病是结果大小写死,源数据一增一减,输出区域不会跟着变。
动态数组把这套繁琐流程删掉了:你只在左上角那一个单元格里写公式,按普通回车确认,Excel 会自己在相邻单元格里铺开结果,并随数据变化自动伸缩。旧版 CSE 公式出于兼容性仍被支持,但微软官方已不建议在新工作中继续使用。
一个公式,铺满一片区域
看个最直观的例子。假设 D2 到 D11 是一列待排序的数据,你把公式写在 F2:
=SORT(D2:D11, 1, -1)按下回车后,F2 到 F11 这十个单元格会一起填上降序排列的结果。你只写了一次公式,其余九个单元格是"溢出"出来的。
溢出区域里,只有左上角能改
公式溢出后,点选溢出区域里的任意一个单元格,Excel 会在整片区域外围画上醒目边框。这时要留意一条规矩:只有区域左上角那个单元格可以编辑。你选中区域内的其他格子,公式栏里确实会显示公式,但它是"幻影",改不了。要改公式,永远回到左上角那一格。
溢出范围运算符
既然结果是一片区域,引用它的时候就不必再估算大小。在原始单元格引用后面加一个 #,就代表整个溢出范围。比如 F2 是上面那个 SORT 公式,那么:
=SUM(F2#)就能把整片溢出区域加起来。数据增加一行,F2# 的范围自动变大,求和结果跟着更新,不用改公式。
隐式交集运算符 @
和溢出相对的是"只取一个值"。当公式原本会返回多个值、你偏偏只想要当前行那个时,可以在数组前面加 @,让 Excel 做隐式交集运算:
=@B3:B5 * @C2:E2这样只会算出当前单元格对应的那一个结果,不会向四周溢出。这个符号在把动态数组公式塞进表格结构时特别常用。
三个主力函数,逐个拆解
搞懂了溢出,再回头看函数,就会觉得顺理成章。
UNIQUE:把重复值一次清掉
UNIQUE 的作用是返回一组数据里的唯一值,也就是去重。
=UNIQUE(array, [by_col], [exactly_once])三个参数的含义如下。
| 参数 | 是否必填 | 作用 |
|---|---|---|
| array | 必填 | 要去重的区域或数组 |
| by_col | 可选 | TRUE 按列比较去重,省略或 FALSE 则按行比较 |
| exactly_once | 可选 | TRUE 只返回恰好出现一次的值,省略则返回所有不同值 |
最常见的用法是从一长串流水里拎出不重复的名单。假设 A2 到 A1000 是不断新增的客户名:
=UNIQUE(A2:A1000)源数据里新加一个客户,这个列表末尾就自动多一行,不需要手动维护。如果只想看"只来过一次"的客户,用第三个参数:
=UNIQUE(A2:A1000, FALSE, TRUE)注意第二个参数不能省,要用逗号占位,因为第三个参数才是要用的那个。
FILTER:按条件把行挑出来
FILTER 用一套判定条件把符合的记录整行返回,效果相当于一个会自己更新的筛选器。
=FILTER(array, include, [if_empty])include 这一项必须是一个与 array 高度(或宽度)一致的逻辑数组,说白了就是写一段能算出 TRUE 和 FALSE 的判断。
只筛一个条件很简单,比如挑出华东区的订单:
=FILTER(A2:D1000, D2:D1000="华东")多个条件靠运算符拼接:乘号表示"并且",加号表示"或者"。
=FILTER(A2:D1000, (D2:D1000="华东")*(E2:E1000>10000), "没有符合条件的订单")第三个参数是兜底:万一一条都没筛出来,让它显示一句话,而不是抛出错误。这一点很重要——Excel 目前不支持空数组,FILTER 什么都不返回时会给一个 #CALC! 错误,加上第三个参数就能避免。
SORT:按自己的列排
SORT 会把区域按其中某一列重新排列,并且不改动原始数据的顺序。
=SORT(array, [sort_index], [sort_order], [by_col])sort_index 是"按第几列排",sort_order 填 1 表示升序、-1 表示降序。想生成一份销售额从高到低的排行榜:
=SORT(A2:D1000, 4, -1)这里第 4 列是销售额。原始表顺序一动不动,你拿到的是一份实时联动的新报表。要提醒一句:别把区域预设得太大,否则末尾那些空行也会被当成数据卷进排序,反而多出一些空记录。
SORTBY:按另一个区域排
SORTBY 比 SORT 更灵活的地方在于,排序依据可以来自数据区之外的另一个区域或数组。
=SORTBY(array, by_array1, [sort_order1], ...)比如想让订单按"部门对照表"里的既定顺序显示,而不是按字母顺序:
=SORTBY(A2:D1000, 部门对照表!E2:E1000, 1)两个区域的行数必须一致,否则会报错。需要多级排序就继续往后加参数对,先按谁、再按谁,一路写下去即可。
组合拳:让表格真正"活"起来
单个函数已经够省事,真正体现价值的是把它们串成一条流水线。
筛选之后排序,再取前几名
业务里最常见的一句需求是"看华东区销售额最高的前五单"。过去的做法是筛选、复制、排序、剪切,数据一更新全白干。现在拆成三步叠起来:
=TAKE(SORT(FILTER(A2:D1000, D2:D1000="华东"), 4, -1), 5)读法从里往外:FILTER 先筛出华东区的记录,SORT 按第 4 列销售额降序排好,TAKE 取最前面 5 行。TAKE 的参数填正数取前 N 行,填负数取后 N 行。整套结果仍然动态,源数据一改,前五名自动换人。
去重之后自动汇总
做客户汇总表时,"去重"和"求和"两步可以连成一体:
=SORT(HSTACK(UNIQUE(A2:A1000), SUMIF(A2:A1000, UNIQUE(A2:A1000), C2:C1000)), 2, -1)UNIQUE 先挑出不重复的客户名,SUMIF 用同一份客户名单逐个算出销售额合计,HSTACK 把两列并排放好,最后 SORT 按合计降序排。整个表会随源数据自动生长,新客户进来就自动多一行。
跨表合并再去重
多个工作表结构相同时,先合并再处理:
=UNIQUE(VSTACK(一月!A2:A100, 二月!A2:A100, 三月!A2:A100))VSTACK 把三个区域的名单垂直堆成一列,UNIQUE 再去重。前提是各区域的列数要一致,工作表名里含数字或特殊字符时,记得用单引号包起来。
生成器函数:SEQUENCE 与 RANDARRAY
除了解析已有数据,动态数组还能凭空生成数据。
SEQUENCE:生成序列
=SEQUENCE(rows, [columns], [start], [step])四个参数分别控制行数、列数、起始值、步长。生成 1 到 100 的序号:
=SEQUENCE(100)生成更聪明的动态序号,让编号永远跟着数据行数走、删行也不断号:
=SEQUENCE(COUNTA(B2:B1000))生成日期序列时记得把结果单元格格式设成日期,否则会显示成一串数字。
RANDARRAY:生成随机数组
=RANDARRAY([rows], [columns], [min], [max], [whole_number])要做随机排序,把它当排序依据交给 SORTBY 即可:
=SORTBY(A2:A21, RANDARRAY(20))每次表格重算,顺序都会重新打乱,抽签、随机排班都能用。
你的 Excel 用得上吗
这类函数有明确的版本门槛,动手前先确认,能省下不少白折腾。
| Excel 版本 | 是否支持动态数组函数 |
|---|---|
| Excel 2016 | 不支持 |
| Excel 2019 | 不支持 |
| Excel 2021 | 支持 |
| Excel 2024 | 支持 |
| Microsoft 365 订阅版 | 支持,且持续更新 |
| 新版 WPS 表格 | 部分支持 |
微软这次一并推出的首批六个函数是 FILTER、SORT、SORTBY、UNIQUE、SEQUENCE 和 RANDARRAY,此后又陆续加入了 TEXTSPLIT、TOCOL、TOROW、WRAPROWS、WRAPCOLS、TAKE、DROP、EXPAND、CHOOSECOLS、CHOOSEROWS、HSTACK、VSTACK 等一批同族函数,构成了相当完整的一套工具箱。
想知道自己机器上是什么版本,可以在 Excel 里点"文件"→"账户"→"关于 Excel"。按微软公布的更新记录,Microsoft 365 应用版当前频道已在 2026 年 10 月 6 日更新到版本 2609(内部版本 20430.20146),对应的月度企业频道为版本 2608(内部版本 20326.20142,2026 年 9 月 8 日发布)。完整清单可以查 Microsoft 365 应用版的更新历史记录。
还有个土办法可以快速自测:随便找个空单元格输入 =UNIQUE(1),回车后显示 1 就说明支持,显示 #NAME? 就说明版本不够。
报错急救:两类错误占九成
动态数组的报错名目不多,认准两个就够用。
SPILL! 溢出被挡住了
这是最常见的一类,原因基本逃不出下面几种。
- 溢出区域不是空的:公式结果要铺开的位置已有内容。选中带错误的单元格,会看到一圈虚线框出预期范围,把里面的内容挪走或删掉即可。
- 整列引用撑爆了网格:像
=VLOOKUP(A:A,A:C,2,FALSE)这种写法,在动态数组里会去查找整列的 1048576 个值,结果一路顶到工作表边缘。解决办法是只引用你真正关心的范围,比如改成 A2:A7。 - 大小不稳定:公式里用了 RAND、RANDBETWEEN、RANDARRAY 这类易变函数,数组大小在计算过程中反复变动,Excel 干脆判为错误。典型例子就是
=SEQUENCE(RANDBETWEEN(1,1000))。 - 溢出到了合并单元格上:合并单元格无法承接溢出,取消合并或把公式挪开即可。
- 写在了表格里:这一点单独拎出来说,见下一节。
CALC! 计算引擎遇到了它不支持的情形
- 空数组:FILTER 一条都没筛出来。给第三个参数填个提示文字或 0 就能化解。
- 嵌套数组:数组里套数组,Excel 算不了。比如
=MUNIT({1,2})就不行。 - 范围数组:数组里只允许放数字、文本、错误值、逻辑值,不能放区域引用。
=OFFSET(A1,0,0,{2,3})会报错,改成=OFFSET(A1,0,0,2,3)就正常。
更多细节可以对照微软官方的说明:如何更正 #溢出! 错误 与 How to correct a #CALC! error。
边界在哪:它替代不了什么
动态数组很强,但也有几条硬边界,提前知道能少踩坑。
- Excel 表格不支持溢出。用 Ctrl+T 转出来的"超级表"里放不下动态数组公式,会直接报 #SPILL!。做法是把公式放在表格外的普通区域;如果数据在表内,可以用结构化引用去引用它,这样增删行时公式范围会自动调整。
- 溢出结果是一个整体。你不能给结果里的某一行单独点升序、降序按钮,也不能删掉结果区域的某一格。要排序,就用 SORT;要挑行,就用 TAKE、DROP 或 FILTER。
- 跨工作簿支持有限。动态数组的联动只在源工作簿和目标工作簿同时打开时才成立;一旦关掉源工作簿,重新刷新时链接的动态数组公式会返回 #REF!。
- 发给旧版本同事会失效。对方用 Excel 2019 或更早版本打开,函数不识别,只会看到错误值。共享文件前最好确认一下协作方的版本。
- 数据量极大时先换思路。几十万行级别的处理,把数据交给 Power Query 或数据透视表关系模型会更稳,别指望单条公式硬扛。
顺带说一句,公式逻辑一复杂,可读性就容易崩。这时可以用 LET 把中间结果定义成变量名,只算一次、重复引用,既提升性能也让公式好读得多。
结语
动态数组带来的改变,本质上不是多了几个函数,而是把"一个单元格一个值"的旧框架换成了"一个公式一片结果"。当你不再需要为每一列写一遍公式、不再需要手动维护辅助列和填充区域时,表格才真正从静态的记录本,变成了会自己更新的报表。FILTER 负责挑,UNIQUE 负责去重,SORT 负责排序,三个函数各司其职又互相嵌套——这套组合用熟了,你会发现过去那些重复劳动,其实早就该被一行公式替代。