wsf.CountIfs数组Debacle - VBA Excel

时间:2013-11-08 18:23:48

标签: arrays excel vba excel-vba

我面临一个我无法解释的奇怪问题。

我正在使用Worksheet函数和CountIfs公式,我也使用Sumproduct来使用Arrays。

但是,每当我尝试使用定义为数组的2个不同变量时,我得到的结果都不正确。

让我解释一下,

当我使用时:

Dim lastrow As Long
Dim wsf
lastrow = Sheet2.Cells(Sheet2.Rows.Count, "M").End(xlUp).Row
Set wsf = Application.WorksheetFunction
Doctors = Array("Peter","Sam","Henry")
Emergency = Array("Y","N")

a1 = Application.WorksheetFunction.SumProduct(wsf.CountIfs(Sheet2.Range("P2:P" & lastrow), Doctors, Sheet2.Range("M2:M" & lastrow), Emergency))

我得到了a1的错误结果。

然而,当我尝试:

a1 = Application.WorksheetFunction.SumProduct(wsf.CountIfs(Sheet2.Range("P2:P" & lastrow), Doctors, Sheet2.Range("M2:M" & lastrow), "Y"))

b1 = Application.WorksheetFunction.SumProduct(wsf.CountIfs(Sheet2.Range("P2:P" & lastrow), Doctors, Sheet2.Range("M2:M" & lastrow), "N"))

Final = a1 + b1

或者

a1 = Application.WorksheetFunction.SumProduct(wsf.CountIfs(Sheet2.Range("P2:P" & lastrow), "Peter", Sheet2.Range("M2:M" & lastrow), Emergency))

b1 = Application.WorksheetFunction.SumProduct(wsf.CountIfs(Sheet2.Range("P2:P" & lastrow), "Sam", Sheet2.Range("M2:M" & lastrow), Emergency))

c1 = Application.WorksheetFunction.SumProduct(wsf.CountIfs(Sheet2.Range("P2:P" & lastrow), "Henry", Sheet2.Range("M2:M" & lastrow), Emergency))

Final = a1 + b1 + c1

我得到了最终的正确结果。

有没有办法让第一个公式起作用,或者vba根本不允许多个变量作为数组在单个countifs函数中用作标准。

我想也许我应该宣布医生和紧急变量但到目前为止没有运气。

有什么建议吗?

3 个答案:

答案 0 :(得分:0)

除非2个标准中的项目数相同,否则您的公式将无效。 (在这种情况下,你需要例如Y N和Z来匹配医生的数量) 我建议UDF可能是最简单的解决方案。

答案 1 :(得分:0)

我不认为在DoctorsEmergency中拥有相同数量的项目可以解决问题 - 如果您在紧急情况下添加了“Z”,例如您只会获得一个计数3种组合中,Peter / Y,Sam / N和Henry / Z不是所需的3 * 3 = 9种组合。

我的公式比VBA好,所以我不知道这是否是最佳解决方案,但你可以转置其中一个数组(无论它们是否大小相同)然后给你所有组合(在你的例子中3 * 2 = 6),即改为

a1 = Application.WorksheetFunction.SumProduct(wsf.CountIfs(Sheet2.Range("P2:P" & lastrow), Doctors, Sheet2.Range("M2:M" & lastrow), wsf.Transpose(Emergency)))

如果将此作为工作表函数编写,则可以执行此操作:

=SUMPRODUCT(COUNTIFS(Sheet2!P2:P100,{"Peter","Sam","Henry"},Sheet2!M2:M100,{"Y";"N"}))

请注意,我没有使用TRANSPOSE,我只是在{“Y”;“N”}中使用了一个分号分隔符,它有效地将它“转置”为“行”到“列” - 我不知道你是否可以通过在VBA中以不同方式定义数组来实现这一点.......

答案 2 :(得分:0)

您可以在VBA中使用数组而不是函数:

Option Explicit
Option Compare Text
Sub MediCount()
'
    Dim lastrow As Long
    Dim Doctors As Variant
    Dim Emergency As Variant
    Dim Profession As Variant
    Dim vData As Variant
    Dim Ct As Long
    Dim jDoc As Long
    Dim jEmr As Long
    Dim jPro As Long
    Dim j As Long
    '
    lastrow = Sheet1.Cells(Sheet1.Rows.Count, "M").End(xlUp).Row
    Doctors = Array("Peter", "Sam", "Harry")
    Emergency = Array("Y", "N")
    Profession = Array("Teacher", "Accountant", "Plumber", "Artist")
    ' assume emergency in M, Profession in N, Doctors in O, start row=2
    vData = Sheet1.Range("M2").Resize(lastrow, 3).Value2
    For j = LBound(vData) To UBound(vData)
        For jDoc = LBound(Doctors) To UBound(Doctors)
            If vData(j, 3) = Doctors(jDoc) Then
                For jEmr = LBound(Emergency) To UBound(Emergency)
                    If vData(j, 1) = Emergency(jEmr) Then
                        For jPro = LBound(Profession) To UBound(Profession)
                            If vData(j, 2) = Profession(jPro) Then
                                Ct = Ct + 1
                            End If
                        Next jPro
                    End If
                Next jEmr
            End If
        Next jDoc
    Next j
    MsgBox Ct
End Sub

(或者您可以使用我的SpeedTools ACOUNTIFS函数=ACOUNTIFS(0,$M$2:$O$50,1,1,$H$2:$H$5,2,$I$2:$I$5,3,$G$2:$G$5)

但那是一个商业Excel插件)