还在为一次筛选就要手动复制、粘贴、删重复值而烦躁吗?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 负责排序,三个函数各司其职又互相嵌套——这套组合用熟了,你会发现过去那些重复劳动,其实早就该被一行公式替代。

发表评论

验证码图片,点击可更换