0

我想使用数组公式从多个条件返回一个值数组。我设法制作了一个工作公式,但没有数组公式,由于工作表中的填充冲突,女巫很烦人。

这是单子

注意:从这个初始线程开发的当前解决方案

4

1 回答 1

0

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)))

我将尝试解释我的思维过程,以便您将来能够进行更改或制作类似的公式,以供其他人参考。

基本解释

我注意到一些可以帮助我们为这个问题制定公式的东西:

  1. Fprod表格中,您有供应商和物种的列表以及周。
  2. 每个批次只有一个列表。
  3. 您的语言环境不允许在公式中使用逗号。\必须改为使用

该公式的基本思想是获取定义列的字符串。它基本上是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:HFprod

它们作为列连接。要查看它是如何工作的,请尝试={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 ito jinclusive。例如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您会看到它表示偏移量(# 周减一)。

就像我之前指出的那样,我们需要这三列,但我们需要确保它不会崩溃。为此,我们希望将默认值设置为-1if 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。拆分会将值拆分为一行。这意味着我们需要转置(参见维基百科文章)。所以我们应该再次转置,拆分和转置。所以让我们添加TRANSPOSESPLIT

=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种情况:

  1. 找不到物种和供应商Fprod
  2. 批次不存在
  3. 该列为空

对于第一个,我们可以简单地将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 公式。

参考

于 2021-02-22T10:51:38.433 回答