TLDR 和自我指导 - Here's the example workbook。
是的,有一种方法可以在 pre-office 2016 中加入数组。我知道上面的 ImaginaryHuman 已经回答了这个问题,但我有另一种方法,它返回一个数组,并且更容易阅读(恕我直言)。我将分解公式的演变,以便您找到适合您的用例的公式。我以粗体突出显示了用例,以便您可以快速找到您的用例。我知道这很冗长,但我是那种喜欢知道解决方案如何运作的人,所以我会尽量给你同样的礼貌。
公式依赖于嵌套的IF 语句和INDEX/CHOOSE 结构。它适用于范围、命名范围,甚至表格列。我的所有示例都显示了四个范围,因此三个 IF 语句,但如果您关心那么多嵌套的 IF 语句,这可以串成(我认为)64 个范围。
对于这些示例,数据范围为 A3:B6、A9:B11、A14:B19 和 A22:B32。生成的数组公式放在E3:E26 范围内,并以Ctrl+Shift+Enter 结尾,使其成为数组公式。您的数据可以随心所欲 - 您不受这些范围的限制 - 只需适当地替换您的范围。
如果您的数据在连续范围内:
=IF(ROW()-ROW(E3)<ROWS(A3:A6),INDEX(A3:B6,ROW()-ROW(E3)+1,COLUMN()-COLUMN(E3)+1),
IF(ROW()-ROW(E3)<ROWS(A3:A6)+ROWS(A9:A11),INDEX(A9:B11,ROW()-ROW(E3)-ROWS(A9:A11),COLUMN()-COLUMN(E3)+1),
IF(ROW()-ROW(E3)<ROWS(A3:A6)+ROWS(A9:A11)+ROWS(A14:A19),INDEX(A14:B19,ROW()-ROW(E3)-ROWS(A3:A6)-ROWS(A9:A11)+1,COLUMN()-COLUMN(E3)+1),
INDEX(A22:B32,ROW()-ROW(E3)-ROWS(A3:A6)-ROWS(A9:A11)-ROWS(A14:A19)+1,COLUMN()-COLUMN(E3)+1))))
它是如何工作的:
-
IF 语句通过从单元格E3 的输出范围顶部减去当前行并将其与@987654336 的第一个输入范围中的单元格数进行比较,确保我们在第一个范围内@。
- INDEX 语句从
A3:B6 的第一个输入范围中选择一个项目,给定从单元格E3 计算的行和列偏移量。
- 如果该行不在第一个范围内,则继续执行下一个
IF 语句,该语句重复该过程,但将数组的当前行与前两个范围的长度进行比较。对任何进一步嵌套的 IF 语句重复该过程。
如果您的数据不在连续范围内,您需要一列显示数据最初来自哪个范围,或两者兼有:
=IF(ROW()-ROW(E3)<ROWS(A3:A6),INDEX(CHOOSE({1,2,3},{1},A3:A6,B3:B6),ROW()-ROW(E3)+1,COLUMN()-COLUMN(E3)+1),
IF(ROW()-ROW(E3)<ROWS(A3:A6)+ROWS(A9:A11),INDEX(CHOOSE({1,2,3},{2},A9:A11,B9:B11),ROW()-ROW(E3)-ROWS(A3:A6)+1,COLUMN()-COLUMN(E3)+1),
IF(ROW()-ROW(E3)<ROWS(A3:A6)+ROWS(A9:A11)+ROWS(A14:A19),INDEX(CHOOSE({1,2,3},{3},A14:A19,B14:B19),ROW()-ROW(E3)-ROWS(A3:A6)-ROWS(A9:A11)+1,COLUMN()-COLUMN(E3)+1),
INDEX(CHOOSE({1,2,3},{4},A22:A32,B22:B32),ROW()-ROW(E3)-ROWS(A3:A6)-ROWS(A9:A11)-ROWS(A14:A19)+1,COLUMN()-COLUMN(E3)+1))))
它是如何工作的:
-
IF 和 INDEX 语句的所有原则与上述相同。
- 添加了
CHOOSE 语句,它允许您选择不连续的数据列或静态数组,其中包含您想要的每个范围的任何标识符。在这种情况下,我选择了数字 (1,2,3,4)。
-
CHOOSE 语句可以包含任意数量的列 - 只需将第一个参数更改为 {1,2,3,4} 即可获得四列,并将第四列添加为最后一个参数。对任何后续列执行相同操作(即 {1,2,3,4,5} 并将第五列添加为最后一个参数。
如果您有水平数据而不是垂直数据,您可以使用TRANSPOSE 使前面的示例工作。只需将 TRANSPOSE 函数嵌套在 CHOOSE 函数中,如下所示:
CHOOSE({1,2,3},{1},TRANSPOSE(A3:C3),TRANSPOSE(A4:C4)
您可以使用命名范围或表格显着清理公式。此示例建立在前一个示例的基础上,允许数据不在连续范围内,并提供了一个标识符列,显示数据的来源:
=IF(ROW()-ROW(E3)<ROWS(Table1),INDEX(CHOOSE({1,2,3},{1},Table1[Column1],Table1[Column2]),ROW()-ROW(E3)+1,COLUMN()-COLUMN(E3)+1),
IF(ROW()-ROW(E3)<ROWS(Table1)+ROWS(Table2),INDEX(CHOOSE({1,2,3},{2},Table2[Column1],Table2[Column2]),ROW()-ROW(E3)-ROWS(Table1)+1,COLUMN()-COLUMN(E3)+1),
IF(ROW()-ROW(E3)<ROWS(Table1)+ROWS(Table2)+ROWS(Table3),INDEX(CHOOSE({1,2,3},{3},Table3[Column1],Table3[Column2]),ROW()-ROW(E3)-ROWS(Table1)-ROWS(Table2)+1,COLUMN()-COLUMN(E3)+1),
INDEX(CHOOSE({1,2,3},{4},Table4[Column1],Table4[Column2]),ROW()-ROW(E3)-ROWS(Table1)-ROWS(Table2)-ROWS(Table3)+1,COLUMN()-COLUMN(E3)+1))))
如果这还不够,您可以通过创建一些命名值来进行更多内务处理以提高可读性。可以做的第一件事是定义我们从哪一行开始从每个表中获取数据。对于此示例,我将它们命名为 Table2_UL、Table3_UL 和 Table4_UL。他们在名称管理器中的代码公式如下所示:
-
Table2_UL: =ROWS(Table1)
-
Table3_UL: =Table2_UL+ROWS(Table2)
-
Table4_UL: =Table3_UL+ROWS(Table3)
如您所见,每个都建立在最后一个之上,因此其输出是动态的。我们现在有了一个更易读的公式:
=IF(ROW()-ROW(E3)<Table2_UL,INDEX(CHOOSE({1,2,3},{1},Table1[Column1],Table1[Column2]),ROW()-ROW(E3)+1,COLUMN()-COLUMN(E3)+1),
IF(ROW()-ROW(E3)<Table3_UL,INDEX(CHOOSE({1,2,3},{2},Table2[Column1],Table2[Column2]),ROW()-ROW(E3)-Table2_UL+1,COLUMN()-COLUMN(E3)+1),
IF(ROW()-ROW(E3)<Table4_UL,INDEX(CHOOSE({1,2,3},{3},Table3[Column1],Table3[Column2]),ROW()-ROW(E3)-Table3_UL+1,COLUMN()-COLUMN(E3)+1),
INDEX(CHOOSE({1,2,3},{4},Table4[Column1],Table4[Column2]),ROW()-ROW(E3)-Table4_UL+1,COLUMN()-COLUMN(E3)+1))))
但这对我来说还不够。我想摆脱所有对ROW() 和COLUMN() 的讨厌引用。我们可以通过在名称管理器中定义另外两个值来跟踪我们当前的行和列来做到这一点:
-
Output_CC: =COLUMN()-COLUMN(Sheet1!E3)+1
-
Output_CR: =ROW()-ROW(Sheet1!E3)+1
最后,我们有了接近人类可读的东西:
=IF(Output_CR-1<Table2_UL,INDEX(CHOOSE({1,2,3},{1},Table1[Column1],Table1[Column2]),Output_CR,Output_CC),
IF(Output_CR-1<Table3_UL,INDEX(CHOOSE({1,2,3},{2},Table2[Column1],Table2[Column2]),Output_CR-Table2_UL,Output_CC),
IF(Output_CR-1<Table4_UL,INDEX(CHOOSE({1,2,3},{3},Table3[Column1],Table3[Column2]),Output_CR-Table3_UL,Output_CC),
INDEX(CHOOSE({1,2,3},{4},Table4[Column1],Table4[Column2]),Output_CR-Table4_UL,Output_CC))))
如果我们真的想一路走下去,我们也可以将 CHOOSE 语句转换为命名值。只需对名称管理器中的每个输入表执行以下操作,确保为每个输入表指定一个唯一名称:
Table1_IN:=CHOOSE({1,2,3},{1},Table1[Column1],Table1[Column2])
现在我们可以很容易地阅读公式:
=IF(Output_CR-1<Table2_UL,INDEX(Table1_IN,Output_CR,Output_CC),
IF(Output_CR-1<Table3_UL,INDEX(Table2_IN,Output_CR-Table2_UL,Output_CC),
IF(Output_CR-1<Table4_UL,INDEX(Table3_IN,Output_CR-Table3_UL,Output_CC),
INDEX(Table4_IN,Output_CR-Table4_UL,Output_CC))))
同样,这还不够,因为您无法打开过滤器并对数组 A-Z 进行排序。您收到错误“您无法更改数组的一部分”。不过,有一个解决方法!它需要一个帮助列并复制您的输出。它可以复制到普通的旧范围或表格中。要允许您对数据进行排序和过滤,请在数组输出左侧创建一个辅助列,在本例中,从 D3 开始。如果您的数据不需要排序(如所有文本列),请创建静态编号(1、2、3、4 等)。在此示例中,列 G 包含要排名的数字。如果确实需要排名,请在D3中输入以下公式并向下拖动:
=RANK.EQ(G3,G$3:G$26,0)+COUNTIF(G$3:G3,G3)-1
如果您需要升序排名,请将最后一个参数更改为 1。如果您的数据被排名,那么您现在有一个乱序排名,或者如果没有排名,则它旁边有一个静态数字的不可排序数组。现在我们将数据复制到一个范围或表格中。在I 列中,从I3 开始,创建与数据集一样长的静态编号(即1、2、3、4)。现在在单元格J3 的右侧输入引用源数组中数据的VLOOKUP:
=VLOOKUP($I3,$D$3:$G$26,COLUMNS($I$3:J3),FALSE)
向下拖动公式,然后向右拖动。您现在可以像正常范围一样对数据进行排序和过滤。