问题描述
因此,我正在使用一个签到系统,将一个人的位置签到一张纸(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(",)))))
//Using a definite range...//
=ARRAYFORMULA(
IF(B2:B100="",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),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),)))))
//Using Infinite Range//
=ARRAYFORMULA(
IF(B2:B="",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),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),)))))
还有一个注意事项。据我所知,如果我创建了“ IF”函数以保持单元格为空(如果B单元格为空)(在该行中没有条目),那么一切都很好,否则,“ Locations”列和Arrayformula会将NA填充为无穷大
这是工作表的链接。 https://docs.google.com/spreadsheets/d/1OZSDju3hRyGyRfFhHJT2PLQ3DBvcfOAT1ZvNxB-J0DQ/edit?usp=sharing
解决方法
好吧,我想出了一些可行的方法。它确实使用了一个辅助列,但是可以通过增加一些操作来消除。
我已经在工作表中添加了一个标签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},0)>--E2:E,TRUE,FALSE)))
*
(ARRAYFORMULA(IF(VLOOKUP(ARRAYFORMULA(VLOOKUP(--F2:F,SORT({Locations!F2:F11,Locations!G2:G11},0)>--F2:F,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}),1),"out of range")),IF($N$2:$N=0,"out of range","")))}
对于成功通过条件测试的每个数据行,此公式都会进行查找以获取位置名称,这是第一个公式。如果位置查找失败,则将其标记为“超出范围”。
,如果您对脚本/公式混合方法没问题,我想出了这一点:
- 将此脚本添加到工作表中(工具>脚本编辑器)。
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,top;
[left,top] = rects[j];
if (isCollision(x,top))
{
match = j;
break;
}
}
results.push(match === -1 ? NaN : match+1);
}
return results;
}
这使您可以使用InBounds
自定义函数,该函数接受数组作为输入。
- 在您的位置单元格中使用以下公式:
=ArrayFormula(IFERROR(
HLOOKUP("LOCATION",Locations!C:C,ArrayFormula(InBounds(--E2:F,Locations!D2:G))+1),"out of range"))