数组 CountIf 替换 - Count(Match())
Array CountIf Substitute - Count(Match())
核心问题
如何尽可能高效地(在性能方面)在一个范围内执行重复的 CountIf()
s?
细节问题
范围到数组
由于每个 read/write 到电子表格都会导致 VBA 代码变慢,因此建议尽可能少地这样做。通常,如果某人重复 reading/writing 到一个范围,他或她应该先将该范围保存到一个数组,对数组执行操作,然后在必要时对电子表格进行最后的读取或写入。
示例值和代码
如何在上面的A2:A11
范围内使用perform 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!
错误。必须找到替代品。
解决方案 - 计数(匹配())
我们正在寻找的解决方案是:
Application.Count(Application.Match(SavedArray(), Array([lookup_value]), 0))
什么?这是如何运作的?
---
通常 return 行号的函数如何与数组配对并计算到 return 正确答案?如何计算行号?
机制说明
非常感谢@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:
Each match will either return a number or an error. The Count()
function counts numbers, not errors. So you get a count of whether any of the values in A1:A11
match 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
参考
---
Question
Example:
myarray = array("First","Second","Second","Third","Fourth")
then what would the countif(myarray,"second")
syntax be? (the result
should equal 2 counts)
回答
Try also:
MsgBox Application.Count(Application.Match(myArray, Array("Second"), 0))
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
核心问题
如何尽可能高效地(在性能方面)在一个范围内执行重复的 CountIf()
s?
细节问题
范围到数组
由于每个 read/write 到电子表格都会导致 VBA 代码变慢,因此建议尽可能少地这样做。通常,如果某人重复 reading/writing 到一个范围,他或她应该先将该范围保存到一个数组,对数组执行操作,然后在必要时对电子表格进行最后的读取或写入。
示例值和代码
如何在上面的A2:A11
范围内使用perform 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!
错误。必须找到替代品。
解决方案 - 计数(匹配())
我们正在寻找的解决方案是:
Application.Count(Application.Match(SavedArray(), Array([lookup_value]), 0))
什么?这是如何运作的? --- 通常 return 行号的函数如何与数组配对并计算到 return 正确答案?如何计算行号?
机制说明
非常感谢@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:
Each match will either return a number or an error. The
Count()
function counts numbers, not errors. So you get a count of whether any of the values inA1:A11
matchLoop1
.
最终代码和值
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
参考 ---
Question
Example:
myarray = array("First","Second","Second","Third","Fourth")
then what would the
countif(myarray,"second")
syntax be? (the result should equal 2 counts)回答
Try also:
MsgBox Application.Count(Application.Match(myArray, Array("Second"), 0))
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