【问题标题】:Formula to Compare Values from Changing List比较更改列表中的值的公式
【发布时间】:2021-09-16 02:29:38
【问题描述】:

您好,我有一个如下项目列表 - 在 Sample 1 列中,蓝色(我猜是父级)后跟红色(子级),Acct 1 中的帐号应该都与前面的相同该部分中的蓝色(直到下一个蓝色与另一个帐号一起列出)。

在下面的示例中,需要标记/识别第 3 条和第 7 条记录。有没有简单的方法可以用公式做到这一点?我有大约 10 万个包含此信息的订单项。非常感谢!!

Sample 1    Acct
Blue        1234
Red         1234
Red         2458
Red         1234
Blue        5768
Red         5768
Red         2589
Red         5768

【问题讨论】:

  • 父母总是字面意义上的“蓝色”,孩子们总是“红色”,还是可以改变?您使用什么版本的 Excel?
  • 可以变化和 Office 365
  • 为了澄清在 Sample 1 列下只给出了两个选项,所以可以是黄色或绿色或 In 或 Out 等...
  • 我认为这是可行的,也许可以使用 xlookup 和条件格式,但必须考虑如何处理一些特殊情况,例如 (a) 没有孩子 (b) 一个孩子 (c) 两个孩子,两者都不同...不幸的是,直到明天晚些时候才会出现,但有空时会看看。

标签: excel formula


【解决方案1】:

这是我的建议。它在 A 列中的当前单元格之前和之后查找第一个在两个方向上都不匹配的单元格,然后获取这些单元格之间的范围。如果 B 列中与当前账户不匹配的单元格至少与当前范围内与当前账户匹配的单元格一样多,则假定当前单元格是错误的(在有两个孩子和他们的孩子的情况下) acct 不匹配,那么它们都会被标记)。

=LET(range,INDEX(A:A,XMATCH(TRUE,A$1:A2<>A2,0,-1)+ROW(A$1)):INDEX(B:B,XMATCH(TRUE,A2:A$10<>A2,0)+ROW()-2),
sample,INDEX(range,0,1),
acct,INDEX(range,0,2),
equal,COUNTIF(acct,B2),
unequal,COUNTIF(acct,"<>"&B2),
unequal>=equal)

不幸的是,这个公式在条件格式中不起作用,所以它意味着将它放在一个单独的列中,向下拖动它并过滤 TRUE 值。

我将看看修改公式以在 CF 中工作。

这在 CF 中有效,但速度很慢 - 需要删除整列范围。

=LET(start,XMATCH(TRUE,A$1:A2<>A2,0,-1)+ROW(A$1),end,XMATCH(TRUE,A2:A$10<>A2,0)+ROW()-2,
sample,FILTER(A:A,(ROW(A:A)>=start)*(ROW(A:A)<=end)),
acct,FILTER(B:B,(ROW(B:B)>=start)*(ROW(B:B)<=end)),
equal,SUM(--(acct=B2)),
unequal,SUM(--(acct<>B2)),
unequal>=equal)

我觉得还可以

=LET(start,XMATCH(TRUE,A$1:A2<>A2,0,-1)+1,end,XMATCH(TRUE,A2:A$10<>A2,0)+ROW()-ROW(A$1)-1,
seq,SEQUENCE(ROWS(A$1:A$10)),
sample,FILTER(A$1:A$10,(seq>=start)*(seq<=end)),
acct,FILTER(B$1:B$10,(seq>=start)*(seq<=end)),
equal,SUM(--(acct=B2)),
unequal,SUM(--(acct<>B2)),
unequal>=equal)


如果我误解了整个事情,并且对于整个样本 1,父母和孩子实际上被标记为蓝色或红色,那么您只需要条件格式:

=AND(A2="Red",B2<>XLOOKUP("Blue",A$1:A2,B$1:B2,,0,-1))

这会用增加的计数标记每个块

=IF(A2="Blue",C1+1,C1)

【讨论】:

  • 哦,天哪……好吧,我试试这个。我在进一步思考并想知道,如果相反(为了简化一点),是否有一个公式,在“红色”的每次更改后,它都会添加一个数值。例如,在我的示例数据“Sample”列中,第一个 Blue 将是 1,并且 Blue 之后的所有“Red's”也将被标记为 1,直到下一个 Blue 出现,然后那个连同它下面的所有 Red's 将被标记为 2,依此类推……有公式吗?
  • 是的,我想是的。来晚了,明天去看看。
  • 太好了 - 谢谢!我尝试复制公式,但收到一条不适用的错误消息......想知道我做错了什么......
  • 不知道!可以发截图吗?在回答您的另一个问题时,试试这个,只是一个简单的下拉公式,随着样本列中的每个交替变化而增加:=QUOTIENT(SUM(--(A$1:A1A$2:A2))-1 ,2)+1 从 A2 开始
  • 也许更好的方法,因为每个父母在它之前和之后都应该有一些不是父母的东西,所以 =IF(AND(A2A1,A2A3),O1+1,O1 ) [我恰好在 O 列工作]。但这不适用于只有一个孩子的情况。
【解决方案2】:

使用一次计算整个列的溢出公式更有效。

我截取了屏幕截图来解释公式,但只需要在单元格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
)

【讨论】:

    猜你喜欢
    • 2014-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多