scan和xlookup
浅谈出口账务和excel函数
这张图片展示的是使用 SCAN 函数 替代之前的 REDUCE 函数,来实现同样的“一对多查找”目标。
这个公式的出现,非常完美地解答了您上一问中“为什么只显示最后一行”的疑惑。下面为您详细分析这张图里的新公式及其背后的逻辑:
=SCAN("", A2:A4, LAMBDA(x, y, XLOOKUP(y, B2:B8, C2:D8, "")))
这里的函数结构与之前几乎完全一样,唯一的、也是最关键的改变是:将 REDUCE 换成了 SCAN。
· A2:A4:要依次查找的条件数组(a1, a2, a3)。
· LAMBDA(x, y, ...):自定义的循环规则。x 是累加器,y 是当前遍历到的值。
· XLOOKUP(y, B2:B8, C2:D8, ""):查找并返回对应的多列数据。
2. SCAN 与 REDUCE 的本质区别(为什么这张图只显示了第一列?)
· REDUCE(归纳):它的特点是将每一步的结果“累积”成一个最终结果。如果没有显式的 VSTACK,且环境支持不当,它可能会像您之前遇到的那样,只返回最终状态的单一结果(如最后一行)。
· SCAN(扫描):它的特点是保留每一次循环的中间结果。它会对数组中的每一个值执行计算,并把每一步的结果都存下来,最后输出一个与输入数组长度相同的数组。
图片中的 E 列(黄色框选)最终只输出了一列数据:{1; 2; 5}。而 F 列(蓝色框选)是空白的。
原本 XLOOKUP 返回的是两列数据(C列和D列,即 {1, 8}, {2, 9}, {5, 12})。
这是因为 SCAN 的输出形状是被严格限制的。当 LAMBDA 返回一个多列数组(如 {1, 8})时,SCAN 为了保持输出数组的维度与输入数组(A2:A4,单列)一致,它会丢弃多余的行或列,只取每个结果的第一列(或第一行)作为最终输出。因此,它自动截取了 1, 2, 5,而丢掉了 8, 9, 12。
· 第一次循环:x = "",y = a1。XLOOKUP 返回 {1, 8}。SCAN 记录下这一步的结果:取第一列 1。
· 第二次循环:x = 1(上一步的结果),y = a2。XLOOKUP 返回 {2, 9}。SCAN 记录下:取第一列 2。
· 第三次循环:x = 2,y = a3。XLOOKUP 返回 {5, 12}。SCAN 记录下:取第一列 5。
· 最终输出:SCAN 将这三个记录组合起来,输出垂直数组 {1; 2; 5}。
图片上方的文字写的是“XLOOKUP和scan多对多查找”。这非常准确,因为 SCAN 确实是这里的主角。
REDUCE 将多个结果“聚合成一个”或通过 VSTACK 强行堆叠成一个大数组。 如果没加 VSTACK,容易只显示最后一步的覆盖结果。加了 VSTACK 能显示所有行列。
SCAN 需要保留每一步过程,输出与源数组等长的数组。 会自动截断多列结果,
这张图展示的是 SCAN 函数在“多对多查找”中的典型应用。它完美解决了“不覆盖”的问题,但由于 SCAN 自身的特性,它无法同时返回多列(横向)的数据。如果您需要返回图中的两列(C和D列的数据),还是建议使用上一张图中加上 VSTACK 的 REDUCE 公式。