【问题标题】:How do I get an Arrayformula to lookup an Arrayformula at autofill?如何让 Arrayformula 在自动填充时查找 Arrayformula?
【发布时间】:2020-09-15 21:12:18
【问题描述】:

所以我正在开发一个签到系统,其中一个人的位置被签入到一张表(GPS 坐标)中,并且可接受的位置列表在另一张表上。它使用边界并测试以查看人在哪个边界内。现在,该过程适用于每个单元格中的单个方程,但当我添加 Arrayformula 时不会自动填充列。因为我需要它是自动的,所以我需要自动填充位置功能才能工作。

我尝试了一些不同的选项,但它们似乎都锁定了 1 个单元格的值或输出错误,或者不自动填充。我假设这是因为我在不同的页面上使用了 2 个不同的数组,但我不知道如何使用或分离 ArrayFormula 以达到我的目的。

//Using Specific Cell Values//

=ARRAYFORMULA(
    IF(B2="",,IF(TEXTJOIN(", ", 1, 
    IF((E2*1>=Locations!D$2:D)*
       (E2*1<=Locations!E$2:E)* 
       (F2*1>=Locations!F$2:F)*
       (F2*1<=Locations!G$2:G), 
          Locations!C$2:C, ))="", "out of range", TEXTJOIN(", ", 1, 
    IF((E2*1>=Locations!D$2:D)*
       (E2*1<=Locations!E$2:E)* 
       (F2*1>=Locations!F$2:F)*
       (F2*1<=Locations!G$2:G), 
           Locations!C$2:C, ))))) 


//Using a definite range...//
 
=ARRAYFORMULA(
    IF(B2:B100="",,IF(TEXTJOIN(", ", 1, 
    IF((E2:E100*1>=Locations!D$2:D)*
       (E2:E100*1<=Locations!E$2:E)* 
       (F2:F100*1>=Locations!F$2:F)*
       (F2:F100*1<=Locations!G$2:G), 
          Locations!C$2:C, ))="", "out of range", TEXTJOIN(", ", 1, 
    IF((E2:E100*1>=Locations!D$2:D)*
       (E2:E100*1<=Locations!E$2:E)* 
       (F2:F100*1>=Locations!F$2:F)*
       (F2:F100*1<Locations!G$2:G), 
           Locations!C$2:C, )))))


//Using Infinite Range//

=ARRAYFORMULA(
    IF(B2:B="",,IF(TEXTJOIN(", ", 1, 
    IF((E2:E*1>=Locations!D$2:D)*
       (E2:E*1<=Locations!E$2:E)* 
       (F2:F*1>=Locations!F$2:F)*
       (F2:F*1<=Locations!G$2:G), 
          Locations!C$2:C, ))="", "out of range", TEXTJOIN(", ", 1, 
    IF((E2:E*1>=Locations!D$2:D)*
       (E2:E*1<=Locations!E$2:E)* 
       (F2:F*1>=Locations!F$2:F)*
       (F2:F*1<Locations!G$2:G), 
           Locations!C$2:C, )))))

也是一个旁注。据我记得,在我创建“IF”函数之前一切正常.

这是工作表的链接。 https://docs.google.com/spreadsheets/d/1OZSDju3hRyGyRfFhHJT2PLQ3DBvcfOAT1ZvNxB-J0DQ/edit?usp=sharing

【问题讨论】:

  • 所以你想要一个 ArrayFormula 来填充主工作表中的位置列,对吧?
  • 您会采用公式脚本混合解决方案吗?我有一种感觉,否则这将是一个非常复杂的公式。
  • 我想出了一些看起来不错的东西(见下文),但我仍在尝试更好地了解 arrayformulas 中的 arrayformulas 是如何工作的,或者不工作......
  • 请记住,根据site guidelines,当答案解决您的问题时,accept 甚至upvote 它也可以让其他人受益。

标签: arrays google-sheets google-sheets-formula array-formulas


【解决方案1】:

好吧,我想出了一些似乎可行的方法。它确实使用了一个辅助列,但可以通过更多的尝试来消除它。

我在您的工作表中添加了一个选项卡 VHCU-GK。生成结果的两个公式在 N1:O1 中。初级公式如下:

=ARRAYFORMULA(IF(VALUE(E2:E)>0,IFERROR((ARRAYFORMULA(IF(VLOOKUP(ARRAYFORMULA(VLOOKUP(--E2:E,SORT({Locations!D2:D11,Locations!C2:C11}),2,1)),{Locations!C2:C11,Locations!E2:E11},2,0)>--E2:E,TRUE,FALSE)))
 *
 (ARRAYFORMULA(IF(VLOOKUP(ARRAYFORMULA(VLOOKUP(--F2:F,SORT({Locations!F2:F11,Locations!C2:C11}),2,1)),{Locations!C2:C11,Locations!G2:G11},2,0)>--F2:F,TRUE,FALSE))),0),""))

我很快就会清理它,并添加一些解释,但它建立在您采用的矩阵方法之上。它只是根据该行的坐标是否落在定义位置的所有四个边界内来返回 true 或 false (1/0)。然后,第二列仅基于一个边界对满足所有四个边界条件的任何行进行查找。我很确定这些可以结合起来,但我想把这个给你,以展示你的问题的一个可能的数组答案。

如果我遗漏了什么,或者有什么问题,请告诉我..

编辑:

我忽略了包含构成此答案一部分的第二个公式 - 它位于样本表的单元格 O1 中。

={"Valid
Location";
ARRAYFORMULA(IF($N$2:$N=1,
    ARRAYFORMULA(IFERROR(VLOOKUP(--$E$2:$E,SORT({Locations!$D$2:$D$11,Locations!$C$2:$C$11}),2,1),"out of range")),
    IF($N$2:$N=0,
      "out of range",
      "")))}

对于成功通过标准测试的每个数据行(这是第一个公式),此公式会进行查找以获取位置名称。如果位置查找失败,则将其标记为“超出范围”。

【讨论】:

  • 不错!我喜欢使用SORT()
  • 谢谢!我想我很幸运尝试了一些内部和外部数组公式 - 老实说,我没想到它会那么好。现在,如果我能把这两个公式合二为一,那真是太令人满意了……
  • 祝你好运!由于对相邻单元的引用,这听起来要复杂得多。另外,为了更好地衡量,我认为最好将两个公式都粘贴到答案中。
  • 它很漂亮。我认为它遵循与原始公式相同的前提。但也许它需要分成不同的列。由于我需要记住一些内置的概念,我将不得不通过并尝试了解它是如何工作的。但这太棒了。完全按照我的需要工作。
【解决方案2】:

如果您对脚本/公式混合方法感到满意,我想出了这个:

  1. 将此脚本添加到您的工作表(工具 > 脚本编辑器)。
function isCollision(x, y, left, right, bottom, top)
{
  return x >= left && x <= right && y >= bottom && y <= top;
}

/**
 * Check if coordinates are in any of the rectangles and return index based on that.
 *
 * @param {Array<Array<number>>} coords
 * @param {Array<Array<number>>} rects
 * 
 * @return Index of Match, or NaN if no match, which can be used for error checks
 * @customfunction
 */

function InBounds(coords, rects)
{
  let results = [];
  
  for (let i = 0; i < coords.length; i++)
  {
    let x, y;
    [x, y] = coords[i];
    
    let match = -1;
    for (let j = 0; j < rects.length; j++)
    {
      let left, right, bottom, top;
      [left, right, bottom, top] = rects[j];
      
      if (isCollision(x, y, left, right, bottom, top))
      {
        match = j;
        break;
      }
    }
    
    results.push(match === -1 ? NaN : match+1);
  }
  
  return results;
}

这让您可以使用InBounds 自定义函数,该函数接受数组作为输入。

  1. 在您的位置单元格中使用此公式:
=ArrayFormula(IFERROR(
    HLOOKUP("LOCATION",Locations!C:C,ArrayFormula(InBounds(--E2:F,Locations!D2:G))+1),
"out of range"))

【讨论】:

    猜你喜欢
    • 2016-07-24
    • 2016-07-11
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    • 2021-08-17
    • 2021-08-15
    • 1970-01-01
    • 2019-05-09
    相关资源
    最近更新 更多