【问题标题】:Array CountIf Substitute - Count(Match())数组 CountIf 替换 - Count(Match())
【发布时间】:2021-01-31 07:47:57
【问题描述】:

核心问题

如何尽可能高效地(从性能方面)在一个范围内重复执行CountIf()s?


详细问题

范围到数组

由于对电子表格的每次读/写都会导致 VBA 代码变慢,因此建议尽可能少地这样做。通常情况下,如果有人重复读/写某个范围,他或她应该首先将该范围保存到一个数组中,对数组执行操作,然后在必要时对电子表格进行最后的读取或写入。


示例值和代码

如何在上面的A2:A11 范围内使用执行CountIf()s 来计算每个值的计数并将它们写入D2:D7?我希望下面的代码可以工作:

Sub M1ArrayCount()

Dim arrNumbers() As Variant
Dim Long1 As Long
Dim Loop1 As Long

arrNumbers() = ThisWorkbook.Sheets(1).Range("A2:A11").Value

With ThisWorkbook.Sheets(1)
    For Loop1 = 1 To 6
        .Cells(Loop1 + 1, 4).Value = Application.CountIf(arrNumbers(), Loop1)
    Next Loop1
End With

End Sub

CountIf() 不适用于数组

但是,因为Application.CountIf() 仅适用于范围而不适用于数组,所以D2:D7 在运行上述代码后都会显示#VALUE! 错误。必须找到替代品。

【问题讨论】:

  • 这个问题的答案将取决于您的数据集有多大。 “要测试的范围”有多少行,“值”有多少行?
  • 确实如此 - 我打算为大型数据集提供此答案,但没有具体说明。我自己的数据集是 90,000 行。

标签: arrays excel vba countif


【解决方案1】:

解决方案 - 计数(匹配())

我们正在寻找的解决方案是:

Application.Count(Application.Match(SavedArray(), Array([lookup_value]), 0))


什么?这是如何运作的? --- 通常返回行号的函数如何与数组和计数配对以返回正确答案?你如何计算行号?

力学解释

非常感谢@Jeeped,下面是它的工作原理:

Match(lookup value, lookup array, 0) 的一个未记录的功能是,如果您将数组作为查找值,它会将Match() 您输入的数组中的每个值与查找数组对应。因此,对于上面的示例,对于Loop = 1,它将变为:

{match(A2, Array("1"), 0),match(A3, Array("1"), 0), ... match(A11, Array("1"), 0)}

然后,根据@Jeeped:

每次匹配都会返回一个数字或一个错误。 Count() 函数计算数字,而不是错误。因此,您可以计算A1:A11 中的任何值是否与Loop1 匹配。

最终代码和价值观

Sub M1ArrayCount()

Dim arrNumbers() As Variant
Dim Long1 As Long
Dim Loop1 As Long

arrNumbers() = ThisWorkbook.Sheets(1).Range("A2:A11").Value

With ThisWorkbook.Sheets(1)
    For Loop1 = 1 To 6
        .Cells(Loop1 + 1, 4).Value = Application.Count(Application.Match(arrNumbers(), Array(Loop1), 0))
    Next Loop1
End With

End Sub


参考 --- This comment

This answer

问题

例子:

myarray = array("First","Second","Second","Third","Fourth")

那么countif(myarray,"second") 语法是什么? (结果 应该等于 2 个计数)

回答

也可以试试:

MsgBox Application.Count(Application.Match(myArray, Array("Second"), 0))

This chat

【讨论】:

  • chat.stackoverflow.com/transcript/message/30485994#30485994 同样来自@Jeeped:“我终于找到了一些时间来更彻底地对该方法进行基准测试,并且我发现了一个限制。向后使用参数将数组作为lookup_value限制为255元素。这使得在大数据块中用作基于数组的替换来计数是令人望而却步的。"
  • 不错;偶然发现了你有趣的方法+1)
  • 漂亮的解决方案。如果出现错误,请确保您使用的是 Application.Matchnot Application.WorksheetFunction.Match。前者不起作用,因为我在这里发现了不匹配的 VBA 错误:stackoverflow.com/a/27302888/12418842
【解决方案2】:
Dim rowin as integer 'this is a counter for the row index
For rowin = 2 To Sheets("Sheet1").UsedRange.Rows.Count
Sheets("Sheet1").Range("D" & rowin).Value = WorksheetFunction.CountIf(Range("A:A"), Range("C" & rowin))
Next

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-29
    • 1970-01-01
    • 2020-01-15
    • 1970-01-01
    相关资源
    最近更新 更多