VBA中CountIfs用数组仅返回首个匹配结果,如何嵌入Transpose?
解决VBA中CountIfs仅返回数组首个匹配项的问题
我来帮你搞定这个问题!你遇到的核心问题是:Excel的CountIfs函数本身不支持直接将数组作为"或"条件来匹配所有元素,当你直接传入EuropeArray时,它只会默认使用数组的第一个元素(也就是France)进行计数,这就是为什么结果只返回France的匹配数量。
下面给你几种可行的解决方案,你可以根据自己的习惯选择:
方案一:用SUMPRODUCT结合MATCH实现多值计数
这种方法不需要循环,利用Excel的数组运算特性,效率较高,适合处理大数据量:
Sub YTDRoutes() Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Dim EuropeArray As Variant EuropeArray = Array("France", "Egypt", "Belgium", "Greece", "Italy", "Lithuania", "Netherlands", "Norway", "Poland", "Portugal", "Spain", "Turkey", "United Kingdom") ' 用SUMPRODUCT替代CountIfs,实现多值匹配计数 Worksheets("T Slide").Cells(9, 5) = Application.SUMPRODUCT( _ '-- 转换布尔值为1/0:Ak列等于指定值 --(Worksheets("RIMPORT").Range("Ak1:Ak25000") = Worksheets("T Slide").Cells(4, 2).Value), _ '-- 转换布尔值为1/0:Am列的值在EuropeArray数组中 --ISNUMBER(MATCH(Worksheets("RIMPORT").Range("Am1:Am25000"), EuropeArray, 0)), _ '-- 转换布尔值为1/0:Ap列大于等于起始日期 --(Worksheets("RIMPORT").Range("ap1:Ap25000") >= CLng(Worksheets("T Slide").Cells(1, 5).Value)), _ '-- 转换布尔值为1/0:Ap列小于等于结束日期 --(Worksheets("RIMPORT").Range("ap1:Ap25000") <= CLng(Worksheets("T Slide").Cells(2, 5).Value)) _ ) ' 恢复Excel的默认设置 Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic End Sub
代码说明:
--的作用是把TRUE/FALSE的布尔值转换成1/0,这样SUMPRODUCT可以对符合所有条件的行进行求和(所有条件都满足时,111*1=1,否则为0)MATCH(..., EuropeArray, 0)会检查Am列的值是否存在于数组中,ISNUMBER则把匹配结果转成布尔值,实现"或"逻辑的多值匹配
方案二:循环遍历数组累加计数
这种方法更直观,容易理解和调试,适合初学者:
Sub YTDRoutes() Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Dim EuropeArray As Variant EuropeArray = Array("France", "Egypt", "Belgium", "Greece", "Italy", "Lithuania", "Netherlands", "Norway", "Poland", "Portugal", "Spain", "Turkey", "United Kingdom") Dim totalCount As Long Dim country As Variant totalCount = 0 ' 遍历数组中的每个国家,分别计数后累加 For Each country In EuropeArray totalCount = totalCount + Application.CountIfs( _ Worksheets("RIMPORT").Range("Ak1:Ak25000"), Worksheets("T Slide").Cells(4, 2).Value, _ Worksheets("RIMPORT").Range("Am1:Am25000"), country, _ Worksheets("RIMPORT").Range("ap1:Ap25000"), ">=" & CLng(Worksheets("T Slide").Cells(1, 5).Value), _ Worksheets("RIMPORT").Range("ap1:Ap25000"), "<=" & CLng(Worksheets("T Slide").Cells(2, 5).Value) _ ) Next country ' 把总计数赋值到目标单元格 Worksheets("T Slide").Cells(9, 5) = totalCount ' 恢复Excel的默认设置 Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic End Sub
代码说明:
- 我们初始化一个
totalCount变量来存储总计数 - 遍历
EuropeArray中的每个国家,用CountIfs单独统计每个国家的符合条件数量,然后累加到totalCount中 - 最后把累加后的结果赋值给目标单元格
方案三:用Evaluate执行数组公式
这种方法模拟Excel单元格中的数组公式写法,适合喜欢用公式逻辑的场景:
Sub YTDRoutes() Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Dim EuropeArray As Variant EuropeArray = Array("France", "Egypt", "Belgium", "Greece", "Italy", "Lithuania", "Netherlands", "Norway", "Poland", "Portugal", "Spain", "Turkey", "United Kingdom") ' 把数组转成公式需要的字符串格式,再用Evaluate执行 Dim arrayStr As String arrayStr = """" & Join(EuropeArray, """,""") & """" Worksheets("T Slide").Cells(9, 5) = Application.Evaluate( _ "SUMPRODUCT((RIMPORT!Ak1:Ak25000='T Slide'!B4)*(ISNUMBER(MATCH(RIMPORT!Am1:Am25000,{" & arrayStr & "},0))*(RIMPORT!Ap1:Ap25000>='T Slide'!E1)*(RIMPORT!Ap1:Ap25000<='T Slide'!E2))" _ ) ' 恢复Excel的默认设置 Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic End Sub
代码说明:
Join(EuropeArray, """,""")把数组元素拼接成带引号的字符串,比如"France","Egypt",...Evaluate会把拼接好的字符串作为Excel公式执行,得到最终的计数结果
内容的提问来源于stack exchange,提问作者MarkusVerarcus
相关产品推荐
相关产品推荐

