我试图回答另一个问题,当我意识到我不知道如何输入一个由不同数组组成的数组作为
INDEX()
或MATCH()
函数的输入参数时。
背景:
正如你们中有些人所知,您可以在 Excel 工作表中的某个位置找到一个值,并使用
INDEX(MATCH(...))
技巧来查找相邻的单元格。
简单的例子:
身份证 | 价值 |
---|---|
a | 1 |
b | 5 |
最大值对应的“Id”可查为:
=OFFSET(INDEX(B2:B3,MATCH(MAX(B2:B3),B2:B3)),,-1)
这相对容易,但是当查找数组分布在多个列上时,这似乎不起作用:
身份证 | 价值 | 垃圾 | 身份证 | 价值 |
---|---|---|---|---|
a | 1 | x | c | 2 |
b | 5 | x | d | 7 |
查找数组不再是
B2:B3
,而是B2:B3,E2:E3
。MAX()
函数,但是当将其填充到 INDEX()
和 MATCH()
函数时,Excel 似乎认为我正在填写两个输入参数,B2:B3
和 E2:E3
(因为中间有逗号)。
所以我需要一个函数,我们称之为
TREAT_AS_ONE_ARRAY()
,这样我就可以使用我的公式:
=OFFSET(
INDEX(
TREAT_AS_ONE_ARRAY(B2:B3,E2:E3),
MATCH(MAX(B2:B3,E2:E3),
TREAT_AS_ONE_ARRAY(B2:B3,E2:E3)
)
),,-1)
有这样的功能吗?
简短的回答是“是”,在 Office 365 中,您可以使用 VSTACK 来“视为一个数组”。不过,在我们开始之前,让我们先澄清一些事情......
首先,没有必要将 OFFSET 与 INDEX 和 MATCH 一起使用。 INDEX 函数中的 array 参数应被视为 return_array,它可以与 MATCH 函数中使用的 lookup_array 不同。
其次,MATCH 函数中可选的 [match_type] 参数应设置为 0(完全匹配)以确保返回第一个匹配项。如果省略,默认设置为 1(小于),乍一看似乎可行,但如果 lookup_array 未按升序排序,或者存在多个匹配项,则可能会产生意外结果。
因此,以下公式更适合上面显示的第一个“简单示例”:
=INDEX(A2:A3, MATCH(MAX(B2:B3), B2:B3, 0))
第三,MATCH函数只接受一维数组(垂直或水平),而INDEX函数完全能够接受二维数组。此外,在使用辅助语法时,INDEX 还将接受由多个区域组成的范围引用:
=INDEX(reference, row_num, [column_num], [area_num])
要对多个区域使用范围引用,必须将其括在括号中。例如:
=INDEX((A2:A3, D2:D3), row_num, [column_num], [area_num])
可选的 [area_num] 参数确定从 reference 返回哪个区域。在上面的示例中,1将从
A2:A3
返回相应的值,2将从D2:D3
返回相应的值。
最后,虽然 MATCH 函数只接受一维数组,但它完全能够处理跨多个列的多个条件。其通用公式结构如下:
// using multiple AND conditions:
=MATCH(1, (range1=value1)*(range2=value2), 0)
// using multiple OR conditions:
=MATCH(1, --(((range1=value1)+(range2=value2))>0), 0)
牢记这些概念,严格使用 INDEX 和 MATCH 的组合绝对可以达到接近预期结果的效果。
示例数据: |身份证 |价值|垃圾|身份证 |价值| | --| -----| -------- | --| -----| |一个 | 1 | x| d | 2 | |乙| 5 | y |电子| 7 | | c | 7 | z | f | 3 |
为了简单起见,我们将把这个过程分为几个步骤:
(1) 在单元格
B7
中,返回上面示例数据中显示的两个“值”列中的最大值:
=MAX(B2:B4, E2:E4)
(2) 在单元格
B8
中,返回在第一个“值”列或第二个“值”列中找到的第一个匹配项的行号,其中该值等于最大值:
=MATCH(1, --(((B2:B4=B7)+(E2:E4=B7))>0), 0)
(3) 在单元格
B9
中,返回找到第一个匹配项的区域编号:
=MATCH(B7, INDEX((B2:B4, E2:E4), B8, , {1,2}), 0)
(4) 在单元格
B10
中,从“Id”列返回相应的值:
=INDEX((A2:A4, D2:D4), B8, , B9)
结果:
注意: 对于旧版本的 Excel,请务必在上述步骤 2 至 4 中使用 Ctrl+Shift+Enter。
使用 Office 365,还可以使用 LET 函数简化此方法:
=LET(
maxVal, MAX(B2:B4, E2:E4),
rowNum, MATCH(1, --(((B2:B4=maxVal)+(E2:E4=maxVal))>0), 0),
areaNum, MATCH(maxVal, INDEX((B2:B4, E2:E4), rowNum, , {1,2}), 0),
INDEX((A2:A4, D2:D4), rowNum, , areaNum))
正如本答案开头所述,如果您有 Office 365,VSTACK 可以用作您问题的直接解决方案:
=INDEX(VSTACK(A2:A4, D2:D4),
MATCH(MAX(B2:B4, E2:E4), VSTACK(B2:B4, E2:E4), 0))
VSTACK 结果:
如您所见,当存在多个匹配项时,这两种方法完全有可能产生两种不同的结果;然而,两个结果都是正确的。多区域范围引用方法在同时搜索
both“Value”列时返回找到的第一个匹配项 (
E3=7
),而 VSTACK 方法通过首先搜索整个 first 来返回找到的第一个匹配项 (
B4=7
) “值”列,然后是整个第二个“值”列。