我想使用数组公式从多个条件返回一个值数组。我设法制作了一个工作公式,但没有数组公式,由于工作表中的填充冲突,女巫很烦人。
1 回答
TL;博士
使用这个公式:
=ARRAYFORMULA(TRANSPOSE(SPLIT(TRANSPOSE(IF((F$1:$1&F$2:$2&F$3:$3&F$4:$4)<>"";IFERROR(REPT(";";IFERROR(VLOOKUP(F$4:$4;{$B$5:$B\ARRAYFORMULA(ROW(A5:A)-5)};2;FALSE);-1)+IFERROR(VLOOKUP(F$4:$4;{$C$5:$C\ARRAYFORMULA(ROW(A5:A)-5)};2;FALSE);-1)+IFERROR(VLOOKUP(F$4:$4;{$D$5:$D\ARRAYFORMULA(ROW(A5:A)-5)};2;FALSE);-1)+2);"#Batch? ")&IFERROR(VLOOKUP(F$1:$1&"-----"&F$2:$2;{ARRAYFORMULA(IF(LEN(Fprod!$H$2:$H);Fprod!$F$2:$F&"-----"&Fprod!$G$2:$G;))\Fprod!$H$2:$H};2;FALSE);"#Species/supplier?");";"));";";TRUE;FALSE)))
我将尝试解释我的思维过程,以便您将来能够进行更改或制作类似的公式,以供其他人参考。
基本解释
我注意到一些可以帮助我们为这个问题制定公式的东西:
- 在
Fprod
表格中,您有供应商和物种的列表以及周。 - 每个批次只有一个列表。
- 您的语言环境不允许在公式中使用逗号。
\
必须改为使用
该公式的基本思想是获取定义列的字符串。它基本上是Fprod
用分号填充的值来垂直移动它。之后,我们要将其转换为列(类似于在另一个问题中的使用方式)。例如,如果CNC
+ shiitake
(batch 2101
) 从第 4 周开始,我们想要实现;;;1;2;3;4;5;6
,然后变为:
2101 |
---|
<empty> |
<empty> |
<empty> |
1 |
2 |
3 |
4 |
5 |
6 |
第 1 步:获取供应商物种的规格
有了供应商和物种,我们希望能过上几周Fprod
(即有CNC
+shiitake
灵魂给我们1;2;3;4;5;6
)。
为此,我们将使用VLOOKUP来获取本周的正确列表。问题是我们需要检查 2 列。所以诀窍是将两列与中间的一些字符(例如-----
)连接起来,以防止意外的冲突。所以在 F 列上工作:
=VLOOKUP(
F$1&"-----"&F$2;
{ARRAYFORMULA(IF(LEN(Fprod!$H$2:$H); Fprod!$F$2:$F&"-----"&Fprod!$G$2:$G;)) \ Fprod!$H$2:$H};
2;
FALSE
)
让我们打开包装,因为已经有很多东西了。
让我们从第二个参数开始,因为它是最复杂的一个。它的作用是创建一个表(二维数组),其中第一列是<supplier>-----<species>
上的每个条目Fprod
,第二列是我们想要的值。要制作第一列,我们可以使用ARRAYFORMULA 逐行添加两列:
=ARRAYFORMULA(Fprod!$F$2:$F & "-----" & Fprod!$G$2:$G)
第二列是简单H2:H
的Fprod
。
它们作为列连接。要查看它是如何工作的,请尝试={1\2}
(通常是,
因为\
需要您的语言环境)。这将产生类似于以下的结果:
1 | 2 |
---|---|
CNC-----香菇 | 1;2;3;4;5;6 |
欧元-----香菇 | 1;2;3;4;5;6;7;8;9;10;11;12;13;14 |
欧洲-----pleurote | 1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16;17;18;19;20;21;22 |
香菇-----香菇 | 1;2;3;4;5;6;7;8;9;10;11;12;13;14 |
Moser-----姬松茸 | 1;2;3;4;5;6 |
----- | |
----- |
如您所见,我们也在生成空条目。要忽略它们,我们将检查该行的 H 列是否为空:
=ARRAYFORMULA(IF(LEN(Fprod!$H$2:$H); Fprod!$F$2:$F&"-----"&Fprod!$G$2:$G;))
现在我们可以简单地使用VLOOKUP来获取第二列中的值。我们搜索的值与第一列的格式相同。在这种情况下,我们将使用 F 列并在稍后进行概括。如果将此添加到 F 列,您应该会看到1;2;3;4;5;6
出现。
注意最后一个参数很重要,因为数据未排序,将其设置为 true 或不设置(默认为 true)会导致问题。
第 2 步:生成填充
要生成填充,我们需要使用一些VLOOKUP来检测值在哪一行。我们需要其中 3 个用于每一列。这个想法是,在第一列中,您具有需要查找的值(批次),而在第二列中,您具有所需的填充数。看起来像:
={$B$5:$B\ARRAYFORMULA(ROW(A5:A)-5)}
$B$5:$B
只是从第 5 行开始的 B 列。ARRAYFORMULA(ROW(A5:A)-5)
是一个技巧:
ARRAYFORMULA(ROW(Ai:Aj))
将返回一个计数列表 from i
to j
inclusive。例如ARRAYFORMULA(ROW(A5:A6))
将返回
结果 |
---|
5 |
6 |
在这种情况下,我们需要结果与另一个表具有相同的大小,因此我们不得不ARRAYFORMULA(ROW(A5:A))
这样做。因为值太大,所以我们需要减去 5,得到ARRAYFORMULA(ROW(A5:A)-5)
.
将它们加入一个表中,您可以在哪里查找:
=VLOOKUP(F$4; {$B$5:$B\ARRAYFORMULA(ROW(A5:A)-5)}; 2; FALSE)
这与之前所做的非常相似。如果您将其添加到其中,F5
您会看到它表示偏移量(# 周减一)。
就像我之前指出的那样,我们需要这三列,但我们需要确保它不会崩溃。为此,我们希望将默认值设置为-1
if not in the column。使用IFERROR很简单。
=IFERROR(VLOOKUP(F$4; {$B$5:$B\ARRAYFORMULA(ROW(A5:A)-5)}; 2; FALSE); -1)
我们不能使用MAX来加入它们,因为它不能与ARRAYFORMULA一起使用,因为 if 可以使用范围。正因为如此,我们需要发挥创造力,所以我添加了它们。这意味着有 2-1
和值;所以加 2 来补偿它:
=IFERROR(VLOOKUP(F$4; {$B$5:$B\ARRAYFORMULA(ROW(A5:A)-5)}; 2; FALSE); -1) +
IFERROR(VLOOKUP(F$4; {$C$5:$C\ARRAYFORMULA(ROW(A5:A)-5)}; 2; FALSE); -1) +
IFERROR(VLOOKUP(F$4; {$D$5:$D\ARRAYFORMULA(ROW(A5:A)-5)}; 2; FALSE); -1) +
2
现在我们只需要使用REPT重复;
我们需要的次数:
=REPT(
";";
IFERROR(VLOOKUP(F$4; {$B$5:$B\ARRAYFORMULA(ROW(A5:A)-5)}; 2; FALSE); -1) +
IFERROR(VLOOKUP(F$4; {$C$5:$C\ARRAYFORMULA(ROW(A5:A)-5)}; 2; FALSE); -1) +
IFERROR(VLOOKUP(F$4; {$D$5:$D\ARRAYFORMULA(ROW(A5:A)-5)}; 2; FALSE); -1) +
2
)
第 3 步:加入他们
您可以像加入常规字符串一样简单地加入它们。请注意,填充首先出现
=REPT(
";";
IFERROR(VLOOKUP(F$4; {$B$5:$B\ARRAYFORMULA(ROW(A5:A)-5)}; 2; FALSE); -1) +
IFERROR(VLOOKUP(F$4; {$C$5:$C\ARRAYFORMULA(ROW(A5:A)-5)}; 2; FALSE); -1) +
IFERROR(VLOOKUP(F$4; {$D$5:$D\ARRAYFORMULA(ROW(A5:A)-5)}; 2; FALSE); -1) +
2
)&
VLOOKUP(
F$1&"-----"&F$2;
{ARRAYFORMULA(IF(LEN(Fprod!$H$2:$H); Fprod!$F$2:$F&"-----"&Fprod!$G$2:$G;)) \ Fprod!$H$2:$H};
2;
FALSE
)
第 4 步:一个公式中的所有列
现在是将公式应用于所有列的好时机。基本上,在你有 column 的地方F
,现在我们将在该行上以F
. 例如,F4
将成为F4:4
.
=ARRAYFORMULA(
REPT(
";";
IFERROR(VLOOKUP(F$4:$4; {$B$5:$B\ARRAYFORMULA(ROW(A5:A)-5)}; 2; FALSE); -1) +
IFERROR(VLOOKUP(F$4:$4; {$C$5:$C\ARRAYFORMULA(ROW(A5:A)-5)}; 2; FALSE); -1) +
IFERROR(VLOOKUP(F$4:$4; {$D$5:$D\ARRAYFORMULA(ROW(A5:A)-5)}; 2; FALSE); -1) +
2
)&
VLOOKUP(
F$1:$1&"-----"&F$2:$2;
{ARRAYFORMULA(Fprod!$F$2:$F&"-----"&Fprod!$G$2:$G) \ Fprod!$H$2:$H};
2;
FALSE
)
)
请注意,如果您稍后在电子表格中有数据,它会给您一个错误。您可以删除它或设置最大列。
另请注意,如果该列没有正确的数据,它会给我们一个错误。我们稍后会解决这个问题。
第 5 步:拆分为列
要将表示拆分为列,我们需要使用SPLIT。拆分会将值拆分为一行。这意味着我们需要转置(参见维基百科文章)。所以我们应该再次转置,拆分和转置。所以让我们添加TRANSPOSE和SPLIT:
=ARRAYFORMULA(
TRANSPOSE(
SPLIT(
TRANSPOSE(
REPT(
";";
IFERROR(VLOOKUP(F$4:$4; {$B$5:$B\ARRAYFORMULA(ROW(A5:A)-5)}; 2; FALSE); -1) +
IFERROR(VLOOKUP(F$4:$4; {$C$5:$C\ARRAYFORMULA(ROW(A5:A)-5)}; 2; FALSE); -1) +
IFERROR(VLOOKUP(F$4:$4; {$D$5:$D\ARRAYFORMULA(ROW(A5:A)-5)}; 2; FALSE); -1) +
2
)&
VLOOKUP(
F$1:$1&"-----"&F$2:$2;
{ARRAYFORMULA(Fprod!$F$2:$F&"-----"&Fprod!$G$2:$G) \ Fprod!$H$2:$H};
2;
FALSE
)
);
";";
TRUE;
FALSE
)
)
)
第 6 步:处理错误
我们可以处理3种情况:
- 找不到物种和供应商
Fprod
- 批次不存在
- 该列为空
对于第一个,我们可以简单地将IFERROR添加到查找中,添加默认消息。第二个我们可以添加一个IFERROR包装REPT,因为它会在数字为负数时(未找到时)抛出错误。对于最后一个,我们需要使用带有值“;”的IF 失败时(SPLIT要求字符串不为空)。
将所有这些添加到我们的最终结果中:
=ARRAYFORMULA(
TRANSPOSE(
SPLIT(
TRANSPOSE(
IF(
(F$1:$1&F$2:$2&F$3:$3&F$4:$4)<>"";
IFERROR(
REPT(
";";
IFERROR(VLOOKUP(F$4:$4; {$B$5:$B\ARRAYFORMULA(ROW(A5:A)-5)}; 2; FALSE); -1) +
IFERROR(VLOOKUP(F$4:$4; {$C$5:$C\ARRAYFORMULA(ROW(A5:A)-5)}; 2; FALSE); -1) +
IFERROR(VLOOKUP(F$4:$4; {$D$5:$D\ARRAYFORMULA(ROW(A5:A)-5)}; 2; FALSE); -1) +
2
);
"#Batch? "
)&
IFERROR(
VLOOKUP(
F$1:$1&"-----"&F$2:$2;
{ARRAYFORMULA(IF(LEN(Fprod!$H$2:$H); Fprod!$F$2:$F&"-----"&Fprod!$G$2:$G;)) \ Fprod!$H$2:$H};
2;
FALSE
);
"#Species/supplier?"
);
";"
)
);
";";
TRUE;
FALSE
)
)
)
如果您删除任何不必要的空白,您将获得 TL;DR 公式。