使用一次计算整个列的溢出公式更有效。
我截取了屏幕截图来解释公式,但只需要在单元格C2 中设置一个公式即可。
这是创建溢出列的未优化公式。它会创建一堆与您的数据高度相同的数组,并对它们进行操作以找到不正确的帐户。
=LET(
MultiLevelID, A2:A9,
Account, B2:B9,
sParent, "Blue",
sChild, "Red",
ArrayIndex, SEQUENCE(ROWS(MultiLevelID)),
ArrayBoolParent, ISNUMBER(XMATCH(MultiLevelID, sParent)),
ArrayParentIndex, IF(ArrayBoolParent=TRUE,ArrayIndex,0),
ArrayAllIndexes, XLOOKUP(ArrayIndex,ArrayParentIndex,ArrayParentIndex,,-1),
ArrayCorrectAccount, XLOOKUP(ArrayAllIndexes,ArrayIndex,Account),
ArrayBoolIncorrect, IF(Account=ArrayCorrectAccount,FALSE,TRUE),
ArrayBoolIncorrect
)
ArrayIndex 是一个数组,从 1 开始并不断向上计数数据的高度。 SEQUENCE 正是为了这个目的。它将用作“行”参考。请注意,这些是相对于所选数据的行,而不是实际的 Excel 行号。
ArrayBoolParent 是一个数组,TRUE 代表每个父母,FALSE 代表每个孩子。 XMATCH 正在搜索父名称,如果找到则返回索引,如果没有则返回错误。 ISNUMBER 如果找到则输出TRUE,如果没有则输出FALSE。使用XMATCH 可以搜索多个条件。例如,如果 "Light Blue" 也是父级,您可以将 sParent 设置为 `{"Blue", "Light Blue"}。
ArrayParentIndex 是一个数组,索引为每个父级,每个子级为 0。我正在使用IF 的一个有趣的应用程序来执行此操作。当IF 被赋予一个数组作为条件时,它会为数组中的每个项目执行IF 语句。当返回值也是一个数组时,它返回与条件相关的项而不是整个数组。
ArrayCorrectedIndexes 是一个数组,其中所有子项的索引都指向其父项。与IF 类似,使用带有XLOOKUP 的数组分别对数组中的所有项目执行搜索。我还使用了XLOOKUP 的高级功能之一,它表示如果找不到值,则返回下一个最大值。这意味着当我搜索索引 2 时,它什么也没找到并返回下一个最小值 1。
ArrayCorrectAccount 是一个数组,父帐户自动分配给每个子帐户。为了清楚起见,我使用了XLOOKUP,但您也可以使用INDEX(Account,ArrayCorrectedIndexes)。
ArrayBoolIncorrect 是一个数组,如果帐户正确则返回 FALSE,否则返回 TRUE。
如果您正在寻找需要修复的摘要,请仅返回不正确的索引:
FirstRow, MIN(ROW(MultiLevelID)) - 1,
FILTER(ArrayIndex + FirstRow, ArrayBoolIncorrect <> FALSE)
最后,如果你想要一个动态表来总结错误,使用这个:
=LET(
MultiLevelID, A2:A9,
Account, B2:B9,
sParent, "Blue",
sChild, "Red",
FirstRow, MIN(ROW(MultiLevelID)) - 1,
ArrayIndex, SEQUENCE(ROWS(MultiLevelID)),
ArrayBoolParent, ISNUMBER(XMATCH(MultiLevelID, sParent)),
ArrayParentIndex, IF(ArrayBoolParent=TRUE,ArrayIndex,0),
ArrayCorrectedIndexes, XLOOKUP(ArrayIndex,ArrayParentIndex,ArrayParentIndex,,-1),
ArrayCorrectAccount, XLOOKUP(ArrayCorrectedIndexes,ArrayIndex,Account),
ArrayBoolIncorrect, IF(Account=ArrayCorrectAccount,FALSE,TRUE),
ArrayInccorrectIndexes, FILTER(ArrayIndex, ArrayBoolIncorrect <> FALSE),
ArrayInccorrectRows, ArrayInccorrectIndexes + FirstRow,
Categories, ArrayInccorrectIndexes,
Body_Instance, SEQUENCE(ROWS(Categories)),
Body_Parent, INDEX(MultiLevelID,INDEX(ArrayCorrectedIndexes, Categories)),
Body_Child, INDEX(MultiLevelID, Categories),
Body_IncorrectAcct, INDEX(Account, Categories),
Body_CorrectAcct, INDEX(ArrayCorrectAccount, Categories),
Body_IncorrectRows, ArrayInccorrectRows,
Total_Rows, COUNT(Categories),
Array_Seq, {1,2,3,4,5,6},
Array_Header, CHOOSE( Array_Seq, "Instance", "Row Location", "Parent", "Child", "Correct Acct", "Incorrect Acct", ),
Array_Body, CHOOSE( Array_Seq, Body_Instance, Body_IncorrectRows, Body_Parent, Body_Child, Body_CorrectAcct, Body_IncorrectAcct, ),
Array_Total, CHOOSE( Array_Seq, "", "", "", "", "Count", Total_Rows),
Range1,Array_Header,
Range2,Array_Body,
Range3,Array_Total,
Rows1,ROWS(Range1), Rows2,ROWS(Range2), Rows3,ROWS(Range3), Cols1,COLUMNS(Range1),
RowIndex, SEQUENCE(Rows1 + Rows2 + Rows3), ColIndex,SEQUENCE(1, Cols1),
RangeTable,IF(
RowIndex<=Rows1,
INDEX(Range1,RowIndex,ColIndex),
IF(RowIndex<=Rows1+Rows2,
INDEX(Range2,RowIndex-Rows1,ColIndex),
INDEX(Range3,RowIndex-Rows1-Rows2,ColIndex)
)),
Return, RangeTable,
Return
)