做数据核对这行的,多少都见过这样的公式:=VLOOKUP(E2&F2, IF({1,0}, A:A&B:B, C:C), 2, 0),外面还要套一层大括号,或者按住三个键才敢敲回车。写的人当时多半是"能跑就行",可三个月后接手的人打开单元格一看,光标点在编辑栏里,脑子里只剩一个念头:这玩意儿到底在算什么。我自己就吃过这个亏——一次月度对账,公式是前任留下的,中间某个区域被人插了一行,结果全体错位,硬是查到凌晨。
这篇东西想解决的就是这件事:Excel 多条件匹配,尤其是"两个及以上条件定位唯一一行"这种高频需求,怎么用 XLOOKUP 写得又短又看得懂,以及在写的过程中最容易在哪儿翻车。它不是什么高深技术,但它是绝大多数人每周都要碰一次的操作。适合的人群很明确:经常要在两张表之间搬数据的人、被 IF({1,0}) 和数组公式劝退过的人、以及想把手里那堆祖传公式改造成能交接给别人的样子的人。基础差一点也没关系,我会把每一步拆开讲,包括那些"看起来对、跑起来错"的细节。
1. 一条 IF({1,0}) 公式背后,VLOOKUP 到底在内存里干了什么
1.1 IF({1,0},B:B,A:A) 是怎么"凭空造出一张表"的
要说清楚 XLOOKUP 好在哪,得先把老写法拆开看。VLOOKUP 有个硬性约束:返回值必须在查找列的右边。它只认"从查找列往右数第 N 列",一旦目标列在左边,它就瞎了。为了绕过这个限制,前辈们想出了IF({1,0}, B:B, A:A)这一招。
{1,0}是一个一行两列的数组常量。IF 函数的第一参数正常情况下是个逻辑判断,但如果你塞进去一个数组,它就会返回一个数组:对第一列来说条件为真(1),取B:B;对第二列来说条件为假(0),取A:A。于是内存里就生成了一张两列的虚拟表,第一列是 B,第二列是 A。VLOOKUP 拿 B 列去查,返回"第 2 列",也就是 A 列——反向查找就这么实现了。
这个技巧在当年是很聪明的解法,本质是把"物理表结构"临时改造成"函数想要的结构"。但它有个隐藏代价:这个虚拟表只存在于公式计算的那一瞬间,工作表上看不见、摸不着,你没法用鼠标点开它看长什么样,也没法单独选中它做校验。
1.2 这套老把式的三处硬伤:录入门槛、列序绑定、看不见的中间结果
我把这套写法的毛病归成三类,都是我实实在在踩过的。
第一是录入门槛。在动态数组普及之前,这类公式属于"数组公式",必须用 Ctrl+Shift+Enter 三键录入,编辑栏外面会自动套一对花括号。手敲回车的话,结果要么是 #VALUE!,要么只算出第一行的值然后一路拖下去全是错的。更麻烦的是这个花括号你不能手打,打了也不算数,必须靠快捷键生成。很多新手就是卡在这一步,看到别人公式外面有{},自己手动敲上去,怎么都不对。
第二是列序绑定。虚拟表的列顺序是靠{1,0}的顺序写死的,一旦需求变化——比如原本要返回 C 列,现在要同时返回 C 和 D——你就得把{1,0}改成{1,1,0}之类,再把分支参数重排一遍。这种改动没有任何容错性,改错一个数字,结果就静悄悄地错,而且往往错得很合理,不容易被发现。
第三是调试成本。公式出问题时,你没法直接看到中间数组。只能靠 F9 选中片段求值,而一旦内容超过编辑栏宽度,F9 弹出来的值就被截断了。我遇到过一次,两头数据明明肉眼一致,就是不匹配,最后是靠把拼接结果单独写到辅助列里,用LEN()一量,发现差了两个字符——一个是全角空格,一个是换行符。这种事在 IF({1,0}) 的公式里排查起来格外痛苦,因为你看不到中间产物。
一个经验:凡是"看不见中间结果"的公式结构,长期维护成本都会高一个量级。写的时候省了五分钟,查的时候可能要花两小时。
2. 把多条件压成一把钥匙:XLOOKUP 的拼接式写法
2.1 语法底色:六个参数里真正需要动的只有三个
XLOOKUP 的完整签名是XLOOKUP(查找值, 查找数组, 返回数组, [未找到时], [匹配模式], [搜索模式])。方括号表示可选,实际工作中前三个是必给,第四个极常用,后两个大多数时候保持默认。
拿一个具体场景说。假设有一张"订单明细表",A 列是客户名,B 列是产品型号,C 列是数量,数据在 A2:C500。另有一张"查询表",E 列填客户名,F 列填型号,想在 G 列取出数量。公式写成这样:
=XLOOKUP(E2&"|"&F2, $A$2:$A$500&"|"&$B$2:$B$500, $C$2:$C$500, "未找到")逐个参数看:
- 查找值
E2&"|"&F2:把两个条件用一个分隔符连起来,变成"客户A|型号X"这样一把唯一的钥匙。 - 查找数组
$A$2:$A$500&"|"&$B$2:$B$500:对区域里的每一行做同样的拼接,得到一个和原区域等高的文本数组。 - 返回数组
$C$2:$C$500:高度必须和查找数组一致。 - 未找到时
"未找到":这是 XLOOKUP 相比 VLOOKUP 最贴心的改进之一,不用再套 IFERROR。
这里我特意用了"|"作为分隔符,而不是直接E2&F2。原因很实在:如果不加分隔符,"AB" + "C" 和 "A" + "BC" 拼出来都是 "ABC",两条不同的记录会撞在一起,返回其中一条,另一条被静默吞掉。竖线、波浪号、@这类业务数据里几乎不会出现的符号都行,关键是确保这个符号在你的数据里不自然存在。我一般用"|"或"~~",前者短,后者更不容易撞。
2.2 从单条件到三条件,公式只加一个 &
这套写法的可扩展性非常好。加第三个条件,只是多一段&"|"&的事:
=XLOOKUP(E2&"|"&F2&"|"&G2, $A$2:$A$500&"|"&$B$2:$B$500&"|"&$D$2:$D$500, $C$2:$C$500, "")不需要改结构、不需要记列序、不需要三键,回车就是结果。这一点对交接特别友好——接手的人哪怕不懂数组,也能一眼看懂"哦,是把这几列连起来去比对"。
我在实际项目里还习惯把拼接做成辅助列。比如在明细表右侧加一列"比对键",写入=A2&"|"&B2&"|"&D2,然后公式简化成:
=XLOOKUP(E2&"|"&F2&"|"&G2, $H$2:$H$500, $C$2:$C$500, "")好处有两个:一是查找数组不再是每次重算的表达式,大表下速度明显更快;二是排查时你能直接盯着这一列看,肉眼比对哪一行键值不对。坏处是原表多了一列,得跟业务方打个招呼。我的做法是放在最右侧,列标题写明"系统生成-勿改",并且用灰色填充标记。
2.3 查找数组和返回数组必须"同高"这条铁律
这是新手最容易犯、报错信息又最不友好的一个错。XLOOKUP 要求查找数组和返回数组的行数必须完全一致。如果你的查找数组是$A$2:$A$500&$B$2:$B$500(498 行),返回数组写成了$C$2:$C$501(500 行),Excel 会给出 #VALUE!,提示"数组维度不匹配"或者类似的说法,但它不会告诉你是哪个区域写错了。
我见过更隐蔽的情况:查找数组用了A2:A500,返回数组用了C2:C499,只差一行,公式在某些行上算得出结果,在某些行上返回错误,看起来像是"数据缺失",其实是区域写窄了。这种错误在拖拽填充的时候尤其容易出现,因为手动输入区域时很容易少按一次方向键。
判断方法很简单:选中公式里的区域,看状态栏显示的"计数",两边必须一致。或者临时把区域改成同一高度再逐步调整,别凭感觉。
另外提一句,XLOOKUP 支持整列引用(A:A),也支持交叉区域。整列写起来省事,代价是性能——Excel 现在会做智能裁剪,只计算已使用区域,所以在多数场景下问题不大。但如果表里有几万行带公式的空行,或者你在一张被引用了很多次的工作簿里,整列引用还是会让重算变慢。我的习惯是:临时分析用整列,正式交付用结构化表格引用(比如表1[客户]&表1[型号]),后者能自动跟随数据增减,不用每次改区域。
3. 拼接法之外的第二条路:布尔数组与 LOOKUP(1,0/…) 的老树新花
3.1 (区域=条件1)*(区域=条件2) 得到的是什么
除了拼接,还有一种思路是构造"布尔数组"。写法是:
=XLOOKUP(1, ($A$2:$A$500=E2)*($B$2:$B$500=F2), $C$2:$C$500, "未找到")拆开看:$A$2:$A$500=E2会得到一个 TRUE/FALSE 的数组,$B$2:$B$500=F2同理。两个数组相乘时,TRUE 被当作 1,FALSE 被当作 0,于是得到一串 0 和 1——只有两个条件同时成立的那一行是 1,其余是 0。然后用1去这个数组里查找,命中第一个 1,返回对应位置的 C 列值。
这个思路的优点是不需要拼接,因此天然绕开了"拼接后类型被强行转成文本"带来的各类麻烦。数字就是数字,日期就是日期,比较的是原始值。缺点也很明显:它依赖数组运算,Excel 内部要构造两个和区域等高的布尔数组再做乘法,数据量大的时候比拼接法慢。我的实测经验是,五万行以内差别感知不到,二十万行以上能明显感觉到卡顿,尤其是拖了几百个这种公式的时候。
还有一个坑:如果同一组条件在数据里出现多次,布尔法会返回第一个命中的行(因为它是从前往后找第一个 1)。这既是特性也是陷阱——如果你的表本应该是唯一的,但实际有重复,公式不会报错,只会静悄悄地给你第一条。拼接法同样有这个特性,所以说到底还是得先用COUNTIFS确认一下唯一性。
3.2 拼接法与布尔法的取舍对照表
我把自己判断的标准整理成一张表,日常照着选就行:
| 判断维度 | 拼接法E2&F2 | 布尔法(区域=条件1)*(区域=条件2) |
|---|---|---|
| 可读性 | 高,一眼看懂在连什么 | 中,需要理解数组乘法 |
| 数据类型敏感度 | 高,数字和文本会被统一转成文本比较 | 中,比较的是原始值,但文本型数字仍不等于数值 |
| 大数据量性能 | 较好 | 一般,数组运算量更大 |
| 分隔符撞车的风险 | 有,需要选冷门符号 | 无 |
| 空值处理 | 空单元格拼接后是空串,容易误命中 | 空值不参与等于判断,相对安全 |
| 适用于日期条件 | 需注意,日期拼接后变成序列号 | 可直接比日期 |
| 条件数量多时 | 公式会变长但结构一致 | 公式变长且括号嵌套加深 |
最后一行是我个人的偏好来源:条件到四个以上时,拼接法的公式虽然长,但结构是线性的、好检查;布尔法的括号层级会让人数到眼花。
3.3 没有 XLOOKUP 的版本该怎么写
现实情况是,很多单位的电脑还停在 2019 甚至 2016,根本没有 XLOOKUP 和 FILTER。这时候布尔思路可以嫁接到老函数上,最经典的就是:
=LOOKUP(1, 0/(($A$2:$A$500=E2)*($B$2:$B$500=F2)), $C$2:$C$500)原理是利用0/0会报错、0/1=0这一点:条件不成立的位置变成 #DIV/0!,成立的位置是 0,LOOKUP 在错误值里找 1,会定位到最后一个 0——注意是最后一个,不是第一个。这一点跟 XLOOKUP 的布尔法相反,如果你的数据有重复,两者取到的行可能不一样,这是个很容易被忽略的差异。
再老一点的环境,还可以用:
=INDEX($C$2:$C$500, MATCH(1, ($A$2:$A$500=E2)*($B$2:$B$500=F2), 0))这个是取第一个匹配,逻辑和 XLOOKUP 一致,但需要 Ctrl+Shift+Enter(在旧版本里)。或者用SUMPRODUCT:
=SUMPRODUCT(($A$2:$A$500=E2)*($B$2:$B$500=F2)*$C$2:$C$500)SUMPRODUCT 不用三键,写起来最省事,但它只能返回数值,而且遇到重复行会把所有匹配值加起来。如果 C 列是金额,而你只想取其中一条,用了 SUMPRODUCT 就等于悄悄做了个汇总,结果可能大得离谱。我见过有人拿它查工资,查出来是三个人的合计,还纳闷为什么这个月发了这么多。
4. 报错现场复现:六类翻车和它们的病灶位置
4.1 #N/A 最常见的一种:数字和文本在拼接时"看起来一样"
这是我遇到最多的一类问题。表面上看,两列都是"1001",但一列是数值型,另一列是从系统导出时被存成的文本型(单元格左上角有个绿色小三角,或者用ISTEXT一测是 TRUE)。拼接法会因为&运算把数值也转成文本,所以大多数情况下反而能匹配上——但只要有一边带着格式差异,就崩了。
典型场景:一边是1.10(文本,保留了末尾的零),另一边是数值1.1。拼接后一边是"1.10",另一边是"1.1",字符串比较不相等,直接 #N/A。类似的还有日期:单元格里的日期本质是序列号,&拼接会得到"45678"这样的数字,而另一端如果是手工录入的"2025/01/15"文本,两边永远匹配不上。
处理方法有两个方向。一是统一源头类型:选中整列,用"数据 - 分列"直接点完成,强制重新识别类型;或者用VALUE()/TEXT()显式转换。二是在公式里统一:
=XLOOKUP(TEXT(E2,"@")&"|"&TEXT(F2,"@"), TEXT($A$2:$A$500,"@")&"|"&TEXT($B$2:$B$500,"@"), $C$2:$C$500, "未找到")TEXT(...,"@")的作用是把值按文本格式输出,两边都转一遍,格式差异就抹平了。不过要注意,TEXT对数值的处理会带出显示格式的问题,比如TEXT(1.1,"@")得到"1.1",但TEXT(1.10,"@")如果原单元格是数值 1.1,得到的还是"1.1"。真正解决还是得回到源头统一。
4.2 #VALUE! 与结果错位:区域高度不一致
前面 2.3 提过,这里补一个具体表现。当你看到 #VALUE! 且提示与数组相关,第一反应应该是去数行数。有个快速自检的办法:把公式里的查找数组和返回数组分别复制到一个空白区域,选中看状态栏的计数。如果一个是 498、一个是 500,问题就找到了。
还有一种更阴的情况:区域高度一致,但起始行不一致。比如查找数组从第 2 行开始,返回数组从第 1 行开始。这样算出来的结果会整体偏移一行,看起来"有值",但全是错位的。这类错误不会报任何提示,是最危险的。我的防御手段是永远用同一行起止,写完公式后随机挑三行,手工去源表核对一下值,确认对齐。
4.3 多出来的空格、换行和不可见字符
从系统导出的数据,字符串尾部经常带空格,或者带CHAR(160)(非断行空格,TRIM清不掉它)。拼接之后,"客户A |型号X"和"客户A|型号X"就是两个不同的键。
排查这个我有一套固定动作:先在一个空白单元格写=LEN(E2),再写=LEN(TRIM(E2)),两个数不一致就说明有首尾空格。如果TRIM之后还是长,就试=LEN(SUBSTITUTE(E2,CHAR(160),"")),看是不是非断行空格。清理的时候,公式里套一层:
TRIM(SUBSTITUTE(E2, CHAR(160), " "))两边都要套,查找值和查找数组都不能漏。这一点特别重要——很多人只清理了查找值,忘了清理源区域,结果还是不通。
还有换行符CHAR(10),在单元格里开了"自动换行"之后肉眼几乎看不出来,但拼接时会实打实地插进去一个字符。用CLEAN()可以清掉大部分不可打印字符,配合TRIM一起用比较稳。
4.4 查找值里的 * 和 ? 被当成通配符
XLOOKUP 在默认的精确匹配模式下,查找值里的*(匹配任意多个字符)和?(匹配单个字符)会被当成通配符处理。这跟 VLOOKUP 的行为是一致的,很多人不知道。
后果是:如果你要查的产品编号是A*01,而表里同时存在AB01、AC01,公式可能会命中其中任意一个,返回一个看起来"合理但错误"的结果。这种错误极难发现,因为不报错。
解决办法有两个。一是转义:在*和?前面加~,写成A~*01。二是改用布尔法,布尔法做的是严格等于比较,不受通配符影响:
=XLOOKUP(1, ($A$2:$A$500=E2)*($B$2:$B$500=F2), $C$2:$C$500, "未找到")我现在的习惯是:只要业务数据里可能出现*、?、~这类符号(型号、编码、备注里很常见),一律用布尔法,省得事后排查。
4.5 整列引用、数组公式与卡顿
一个工作簿如果莫名其妙变慢,八成是某个地方藏了大量整列引用的数组公式。$A:$A&$B:$B这种写法,在旧版本里会对整列 104 万行都做拼接运算,哪怕你只有一千行数据。虽然新版 Excel 有智能优化,但优化不是万能的,特别是当公式被复制到几千个单元格时,重算时间会成倍增长。
我的处理原则:
- 正式表格一律限定范围,或者用 Excel 表格(Ctrl+T)后的结构化引用。
- 需要留余量的话,按实际数据量的 1.5 倍左右预留,比如现在 3000 行,就写到 5000 行,别直接上整列。
- 如果公式数量超过几百个,考虑先在源表加辅助列把拼接键算好,公式里直接引用那一列。
顺带说一句计算模式的设置。默认是"自动计算",每改一个单元格全表重算。做大数据量分析时我会临时切成"手动计算"(公式 - 计算选项 - 手动),改完了按 F9 统一算一次,效率差别非常明显。
5. 我的排查链路:从报错到定位具体单元格
5.1 先拆公式,把拼接结果单独落到辅助列
遇到 #N/A,我的第一动作永远不是盯着公式看,而是把中间结果可视化。具体做法:在源表和查询表各加一列临时辅助列,写=A2&"|"&B2,然后拿查询表的键去源表的辅助列里做一次COUNTIF:
=COUNTIF(源表!$H:$H, 查询表!G2)结果是 0 就说明这个键在源表里确实不存在,问题出在数据本身;结果大于 0 但 XLOOKUP 还是 #N/A,那基本可以锁定是类型或者区域对齐的问题。这一步花不了两分钟,但能砍掉一大半的猜测。
5.2 用 ISTEXT / ISNUMBER 做类型体检
确认"键存在但查不到"之后,下一步是查类型。在原表和查询表各写一组:
=ISTEXT(A2) =ISNUMBER(A2) =CODE(LEFT(A2,1))ISTEXT和ISNUMBER判断类型,CODE看首字符的编码——如果两边首字符编码不一样,说明有隐藏字符或者全角半角差异。全角数字123和半角123长得几乎一样,但编码完全不同,拼接后必然对不上。这种情况在从某些系统导出的数据里挺常见的。
5.3 用 F9 分段求值,但别依赖它
F9 选中片段求值是老技巧,管用但有限制:内容一长就被截断,而且数组结果只显示前几个元素。我的用法是只用它做快速否定——比如选中$A$2:$A$500&"|"&$B$2:$B$500按 F9,看前几个值是不是预期格式,如果是"1001|A"这种就对了,如果看到"#VALUE!"或者一堆0,那区域里肯定混了错误值或空值。真正要逐个比对,还是得靠辅助列。
另外提一个容易被忽略的点:源区域里如果混着#N/A之类的错误值,整个拼接数组都会变成错误,XLOOKUP 直接返回错误。这种情况下可以先在辅助列用IFERROR(A2,"")兜一下,把错误值变成空串,虽然不完美,但至少能让公式跑起来,然后再去处理那些错误源头。
6. 三个真实业务形态下的多条件落地
6.1 按"姓名 + 月份"取绩效数据
这是最典型的双条件场景。明细表里 A 列姓名、B 列月份(存成2025-01这样的文本)、C 列绩效分。查询表里 E 列姓名、F 列月份,要在 G 列取分。
=XLOOKUP(E2&"|"&F2, $A$2:$A$2000&"|"&$B$2:$B$2000, $C$2:$C$2000, "无记录")这里有个细节值得说:月份如果一边是日期格式(显示为 2025年1月),一边是文本2025-01,拼接后一个变成序列号"45658",一个是"2025-01",必然不通。我的处理是把两边都统一成TEXT(日期,"yyyy-mm")的形式,公式里显式转换,避免依赖单元格格式。
另外,姓名里可能有重名。这种情况下双条件也不够,得加上部门或者工号。判断标准很简单:拿COUNTIFS数一下,如果某个"姓名+月份"组合的计数大于 1,就说明这个键不唯一,得再加条件。
6.2 按数值区间做等级匹配:match_mode 的用武之地
多条件不一定是"多个字段相等",也可能是"落在某个区间"。比如按销售额定提成档位:0-10 万是 3%,10-30 万是 5%,30 万以上是 8%。这时候用 XLOOKUP 的第五参数:
=XLOOKUP(D2, $A$2:$A$4, $B$2:$B$4, "超范围", -1)-1表示"精确匹配,找不到就取下一个较小的项"。前提是 A 列的档位下限必须升序排列:0、100000、300000。这样 25 万会落在 10 万那一档,取 5%。
这里最常见的错误是区间表没有排序。XLOOKUP 的-1和1模式依赖有序数据,顺序乱了结果会错得很随机。我一般会在区间表旁边加一句备注"必须升序",并且用条件格式在乱序时标红,虽然麻烦,但比事后查错省事。
还有一点:-1模式下如果查找值小于区间表的最小值,会返回 #N/A,所以要给第四参数兜底。上面公式里写了"超范围",实际用的时候最好改成更明确的提示,方便使用者判断是数据问题还是档位问题。
6.3 一次返回多列:溢出与不溢出两种环境
如果返回数组给的是多列区域,比如$C$2:$E$2000,XLOOKUP 会返回一整行。在支持动态数组的环境(365、2021)里,结果会自动向右溢出,你只需要在一个单元格里写公式,右边两格自动填充。这时候如果右边原本有内容,会报#SPILL!,提示"溢出区域被阻挡"。
在不支持动态数组的环境里,同样的公式只会返回第一个值,你需要先选中三个单元格,输入公式后按 Ctrl+Shift+Enter 变成区域数组公式。这两种环境的公式长得一模一样,行为却不同,交接时一定要说清楚,否则接手的人会以为公式坏了。
还有一个技巧:动态数组环境下可以用#引用整个溢出区域,比如G2#,后续做汇总时直接引用这个,数据增减会自动跟着变,不用调整范围。
7. 大表下的写法习惯与长期维护
7.1 结构化引用替代整列,让公式跟着数据走
把源数据区域按 Ctrl+T 转成表格(假设命名为"订单表"),公式就能写成:
=XLOOKUP([@客户]&"|"&[@型号], 订单表[客户]&"|"&订单表[型号], 订单表[数量], "未找到")好处很实在:新增行时,表格自动扩展,公式不用改区域;列名改了,公式里的引用自动跟着改;别人看公式时,订单表[客户]比$A$2:$A$500直观得多。缺点是在老版本里表格的支持不完整,而且表格和普通区域混用时偶尔会有格式继承的怪问题。我的做法是:新做的表一律用表格,老表改造要评估工作量,别为了用表格而大动干戈。
7.2 把重复的拼接做成辅助列或命名公式
如果同一个拼接键要在十几个公式里用到,与其每次都写一遍$A$2:$A$500&"|"&$B$2:$B$500,不如:
- 方案一:加辅助列。在源表加一列算好键值,公式里直接引用。优点是直观、可检查、性能好;缺点是多一列。
- 方案二:定义名称。在"公式 - 名称管理器"里定义一个名字,比如
查找键,引用位置写=订单表[客户]&"|"&订单表[型号]。公式里直接写XLOOKUP(..., 查找键, ...)。优点是不占列;缺点是别人(包括几个月后的自己)打开名称管理器才能看到它是什么,可读性打了折扣。
我倾向方案一,因为能看见的东西才是能维护的东西。多一列的成本,远比"一个看不见的命名公式在半年后无人敢动"低。
7.3 交接给别人的公式该怎么写注释
这一步经常被跳过,但它决定了一个公式是能被沿用还是被推翻重写。我的几个习惯:
- 在表头单元格加批注,写清楚这个公式的用途、依赖哪些列、数据更新时要注意什么。
- 公式里用
LET把中间变量命名出来(365 支持):
=LET( 键, [@客户]&"|"&[@型号], 源键, 订单表[客户]&"|"&订单表[型号], XLOOKUP(键, 源键, 订单表[数量], "未找到") )LET的好处是把一长串公式拆成有名字的步骤,读起来像伪代码。我第一次用LET重写一个三百字符的嵌套公式之后,同事的评价是"终于知道这行在干嘛了"。它的性能通常也更好,因为重复出现的表达式只算一次。
- 别在公式里硬编码业务常量。比如提成比例直接写
0.05,三个月后调政策就得满表找。放到单独的参数区,公式引用参数区单元格。
最后再分享一个我踩过的小坑。有次把一个 XLOOKUP 公式复制到一个新表里,结果全表 #REF!,查了半天发现是原公式里用了LET中的名字,复制到新工作簿后名称定义没跟过来。从那以后我的习惯是:跨工作簿复制的公式,先在目标文件里重新写一遍,别直接粘。慢一点,但省掉一整晚的排查。