具有浮动条件的 COUNTIFS 匹配列中的下一个值
COUNTIFS with floating criteria matching the next value in a column
我有以下包含四个 列的示例数据 Class, ID、类型和代码:
Class ID Type Code
Class1 ID1 Code1
Class1 ID1 Type1
Class1 ID1 Type2
Class1 ID1
Class1 ID1 Code1
Class1 ID1
Class1 ID1 Type1
Class1 ID1 Code1
Class1 ID1 Type2
Class1 ID1
Class1 ID1 Code1
Class1 ID1
Class1 ID1 Type2
Class1 ID1 Type1
Class1 ID1 Code1
Class1 ID1 Type2
Class1 ID1 Type2
Class1 ID1 Type2
我有以下公式:
=COUNTIFS($A:$A;"Class1";$B:$B;"ID1";$D:$D;"code1")
BUT 我想实现一个带有附加条件的 countifs
公式:
仅计算那些 code1
在 TYPE 列中下一次出现的 type1
所以我会有:
通过在公式中保留上述条件并添加附加条件:
code1 的 count
与 type1 作为下一个出现将是 2。类似地,code1 的 count
和 type2 作为 TYPE column
中的下一个出现将是 3.
编辑:
实际上我知道如何使用以下方法找到我的第 n 个匹配项:
SMALL(IF($C:$C="type1";ROW($C:$C);"");1)
但我不知道如何合并这两个公式。
Acually,我已经可以找到我的 code1
,然后根据其单元格引用在下面的前一列 一行 中找到我的 type1
,但并不总是在下面一行,有时是两行或三行或更多。
=OFFSET(INDEX($D:$D;MATCH(1;(D:D="code1")*(A:A="class1");0);1);1;-1;1;1)
我感觉跟sumproduct
和offset
或者index/match
有关系,但是我找不到办法。
**P.S。 ** 我也尝试了以下,但仍然没有结果:
=MMULT(($A:$A="Class1")*($B:$B="ID1")*($D:$D="code1");N(OFFSET(INDEX($D:$D;MATCH(1;(D:D="code1")*(A:A="class1");0);1);1;-1;1;1)="type1"))
更新
因为实现这个似乎有点问题,我添加这个更新是为了看看我们如何使用 UDF 实现这个?
我不是 Excel 的专家,但我认为您可以使用 INDEX() 解决此问题。
- http://www.randomwok.com/excel/how-to-use-index-match/
- https://support.office.com/en-us/article/INDEX-function-b61bc266-fe02-4852-aad9-77bf8ca3c036
- http://www.techonthenet.com/excel/formulas/index_function.php
或者如果你进入Range.FindNext方法
https://msdn.microsoft.com/en-us/library/office/ff196143.aspx
希望对您有所帮助。
编辑:抱歉。我错了。但是学到了很多。
过于复杂的数组公式会快速消耗计算资源,寻找偏移范围内的第一个非空白条目属于此类。有时,引入一个 辅助列 并提供获得有利结果所需的部分信息会更容易。
在右侧未使用的列中,在第 2 行中使用此标准公式。
=IF(LEN($D2), INDEX($C2:$C9, MATCH("*", $C2:$C9, 0)), "")
如果您需要更多行,请编辑 999 结束行。如果你有更少的,它可以单独留下。作为标准公式,这是正常输入的。根据需要填写以捕获所有 returns.
MATCH("*", $C2:$C9, 0)
也可以是 MATCH("Type*", $C2:$C9, 0)
是否需要更具体的查找。
现在您可以使用常规的(高效的)COUNTIFS function 来实现您的结果。
附录: UDF 替代方案
UDF 的代码是:
Function udf_CountIf_Next_Item(rR1 As Range, sS1 As String, _
rR2 As Range, sS2 As String, rR3 As Range, sS3 As String, _
rR4 As Range, sS4 As String, Optional sS5 As String = "")
Dim rw As Long, rws As Long, n As Long
With Intersect(rR1.Parent.UsedRange, rR1)
rws = .Rows.Count
End With
For rw = 1 To rws
If LCase(rR1(rw).Value2) = LCase(sS1) Then
If LCase(rR2(rw).Value2) = LCase(sS2) Then
If LCase(rR3(rw).Value2) = LCase(sS3) Then
If Not IsError(Application.Match(sS5 & Chr(42), rR4(rw).Resize(999, 1), 0)) Then
If LCase(Application.Index(rR4(rw).Resize(999, 1), _
Application.Match(sS5 & Chr(42), rR4(rw).Resize(999, 1), 0))) = LCase(sS4) Then
n = n + 1
End If
End If
End If
End If
End If
Next rw
udf_CountIf_Next_Item = n
End Function
syntax:
udf_CountIf_Next_Item(<1st column>, <1st criteria>, <2nd column>, <2nd criteria>, <3rd column>, <3rd criteria>, <special floating column>, <4th criteria>, [optional]<partial floating criteria>)
上述示例图片J7中的公式为:
=udf_CountIf_Next_Item($A:$A, $F7,$B:$B, $G7,$D:$D, $I7,$C:$C, $H7, "Type")
完整的列引用应该不是问题,因为 UDF 会将它们截断到工作表的 UsedRange 属性 的边界。 A2:A99 等部分列引用仍然可以使用。
我有以下包含四个 列的示例数据 Class, ID、类型和代码:
Class ID Type Code
Class1 ID1 Code1
Class1 ID1 Type1
Class1 ID1 Type2
Class1 ID1
Class1 ID1 Code1
Class1 ID1
Class1 ID1 Type1
Class1 ID1 Code1
Class1 ID1 Type2
Class1 ID1
Class1 ID1 Code1
Class1 ID1
Class1 ID1 Type2
Class1 ID1 Type1
Class1 ID1 Code1
Class1 ID1 Type2
Class1 ID1 Type2
Class1 ID1 Type2
我有以下公式:
=COUNTIFS($A:$A;"Class1";$B:$B;"ID1";$D:$D;"code1")
BUT 我想实现一个带有附加条件的 countifs
公式:
仅计算那些 code1
在 TYPE 列中下一次出现的 type1
所以我会有:
通过在公式中保留上述条件并添加附加条件:
code1 的 count
与 type1 作为下一个出现将是 2。类似地,code1 的 count
和 type2 作为 TYPE column
中的下一个出现将是 3.
编辑: 实际上我知道如何使用以下方法找到我的第 n 个匹配项:
SMALL(IF($C:$C="type1";ROW($C:$C);"");1)
但我不知道如何合并这两个公式。
Acually,我已经可以找到我的 code1
,然后根据其单元格引用在下面的前一列 一行 中找到我的 type1
,但并不总是在下面一行,有时是两行或三行或更多。
=OFFSET(INDEX($D:$D;MATCH(1;(D:D="code1")*(A:A="class1");0);1);1;-1;1;1)
我感觉跟sumproduct
和offset
或者index/match
有关系,但是我找不到办法。
**P.S。 ** 我也尝试了以下,但仍然没有结果:
=MMULT(($A:$A="Class1")*($B:$B="ID1")*($D:$D="code1");N(OFFSET(INDEX($D:$D;MATCH(1;(D:D="code1")*(A:A="class1");0);1);1;-1;1;1)="type1"))
更新
因为实现这个似乎有点问题,我添加这个更新是为了看看我们如何使用 UDF 实现这个?
我不是 Excel 的专家,但我认为您可以使用 INDEX() 解决此问题。
- http://www.randomwok.com/excel/how-to-use-index-match/
- https://support.office.com/en-us/article/INDEX-function-b61bc266-fe02-4852-aad9-77bf8ca3c036
- http://www.techonthenet.com/excel/formulas/index_function.php
或者如果你进入Range.FindNext方法
https://msdn.microsoft.com/en-us/library/office/ff196143.aspx
希望对您有所帮助。
编辑:抱歉。我错了。但是学到了很多。
过于复杂的数组公式会快速消耗计算资源,寻找偏移范围内的第一个非空白条目属于此类。有时,引入一个 辅助列 并提供获得有利结果所需的部分信息会更容易。
在右侧未使用的列中,在第 2 行中使用此标准公式。
=IF(LEN($D2), INDEX($C2:$C9, MATCH("*", $C2:$C9, 0)), "")
如果您需要更多行,请编辑 999 结束行。如果你有更少的,它可以单独留下。作为标准公式,这是正常输入的。根据需要填写以捕获所有 returns.
MATCH("*", $C2:$C9, 0)
也可以是 MATCH("Type*", $C2:$C9, 0)
是否需要更具体的查找。
现在您可以使用常规的(高效的)COUNTIFS function 来实现您的结果。
附录: UDF 替代方案
UDF 的代码是:
Function udf_CountIf_Next_Item(rR1 As Range, sS1 As String, _
rR2 As Range, sS2 As String, rR3 As Range, sS3 As String, _
rR4 As Range, sS4 As String, Optional sS5 As String = "")
Dim rw As Long, rws As Long, n As Long
With Intersect(rR1.Parent.UsedRange, rR1)
rws = .Rows.Count
End With
For rw = 1 To rws
If LCase(rR1(rw).Value2) = LCase(sS1) Then
If LCase(rR2(rw).Value2) = LCase(sS2) Then
If LCase(rR3(rw).Value2) = LCase(sS3) Then
If Not IsError(Application.Match(sS5 & Chr(42), rR4(rw).Resize(999, 1), 0)) Then
If LCase(Application.Index(rR4(rw).Resize(999, 1), _
Application.Match(sS5 & Chr(42), rR4(rw).Resize(999, 1), 0))) = LCase(sS4) Then
n = n + 1
End If
End If
End If
End If
End If
Next rw
udf_CountIf_Next_Item = n
End Function
syntax:
udf_CountIf_Next_Item(<1st column>, <1st criteria>, <2nd column>, <2nd criteria>, <3rd column>, <3rd criteria>, <special floating column>, <4th criteria>, [optional]<partial floating criteria>)
上述示例图片J7中的公式为:
=udf_CountIf_Next_Item($A:$A, $F7,$B:$B, $G7,$D:$D, $I7,$C:$C, $H7, "Type")
完整的列引用应该不是问题,因为 UDF 会将它们截断到工作表的 UsedRange 属性 的边界。 A2:A99 等部分列引用仍然可以使用。