Excel - 跨多个工作表/同一列使用COUNTIF / COUNTIFS

时间:2014-02-20 20:59:09

标签: excel excel-vba vba

我正在尝试" COUNT"跨越多个工作表的第I列(在本例中)中的某个对象的编号。第I列中的值是公式的结果(如果重要的话)。到目前为止,我有:

=COUNTIF('Page M904'!I:I,A13)+COUNTIF('Page M905'!I:I,A13)+COUNTIF('Page M906'!I:I,A13)

哪个有效,但我要翻阅20个页面。我想避免使用页面长的公式。

我试过了

=COUNTIFS('Page M904:Page M906'!I:I,A13)=COUNTIF('Page M904:Page M906'!I:I,A13)

但会产生#VALUE

我认为

=COUNTIFS('Page M904'!I:I,A14,'Page M905'!I:I,A14,'Page M906'!I:I,A14)

是对COUNTIFS的误用,因为当它应该为35时我会0

我试图避免在此应用程序中使用VBA。但如果必须如此,则必须是:)提前感谢您的时间和帮助。

4 个答案:

答案 0 :(得分:11)

这可以通过以下技术在没有VBA的情况下解决。

在这个例子中,我正在计算工作表A:APage M904Page M905 Page M906范围内的所有三分(3)。

列出单个连续范围内的所有工作表名称,如下例所示。此处列在D3:D5范围内。

enter image description here

然后通过在单元格B2中使用查找值,可以使用以下公式在单元格B4中找到结果:

=SUMPRODUCT(COUNTIF(INDIRECT("'"&D3:D5&"'!A:A"), B2))

答案 1 :(得分:4)

  

我试图避免使用VBA。 但如果必须,则必须:)

您可以使用非常简单的UDF:

Function myCountIf(rng As Range, criteria) As Long
    Dim ws As Worksheet

    For Each ws In ThisWorkbook.Worksheets
        myCountIf = myCountIf + WorksheetFunction.CountIf(ws.Range(rng.Address), criteria)
    Next ws
End Function

并将其称为:=myCountIf(I:I,A13)


P.S。如果您要排除某些工作表,可以添加If声明:

Function myCountIf(rng As Range, criteria) As Long
    Dim ws As Worksheet

    For Each ws In ThisWorkbook.Worksheets
        If ws.name <> "Sheet1" And ws.name <> "Sheet2" Then
            myCountIf = myCountIf + WorksheetFunction.CountIf(ws.Range(rng.Address), criteria)
        End If
    Next ws
End Function

<强> UPD:

  

我有四个&#34;参考&#34;我需要从扫描/搜索中排除的工作表。它们目前是工作簿中的最后四个

Function myCountIf(rng As Range, criteria) As Long
    Dim i As Integer

    For i = 1 To ThisWorkbook.Worksheets.Count - 4
        myCountIf = myCountIf + WorksheetFunction.CountIf(ThisWorkbook.Worksheets(i).Range(rng.Address), criteria)
    Next i
End Function

答案 2 :(得分:2)

我的第一篇文章...... UDF我很快就编译了。 用法: 正常选择3D范围,并将其括在下面的引号中......

= CountIf3D(&#34;&#39; StartSheet:蝴蝶页&#39; G16:G878&#34 ;;&#34;标准&#34)

建议相邻的床单以避免意外结果。

Public Function CountIf3D(SheetstoCount As String, CriteriaToUse As Variant)

     Dim sStarSheet As String, sEndSheet As String, sAddress As String
     Dim lColonPos As Long, lExclaPos As Long, cnt As Long

    lColonPos = InStr(SheetstoCount, ":") 'Finding ':' separating sheets
    lExclaPos = InStr(SheetstoCount, "!") 'Finding '!' separating address from the sheets

    sStarSheet = Mid(SheetstoCount, 2, lColonPos - 2) 'Getting first sheet's name
    sEndSheet = Mid(SheetstoCount, lColonPos + 1, lExclaPos - lColonPos - 2) 'Getting last sheet's name

    sAddress = Mid(SheetstoCount, lExclaPos + 1, Len(SheetstoCount) - lExclaPos) 'Getting address

        cnt = 0
   For i = Sheets(sStarSheet).Index To Sheets(sEndSheet).Index
        cnt = cnt + Application.CountIf(Sheets(i).Range(sAddress), CriteriaToUse)
   Next

   CountIf3D = cnt

End Function

答案 3 :(得分:0)

我一直想做同样的事情,但是我有一个变通方法,即使用频率和索引函数似乎不太复杂。我使用此功能的这一部分,是对多张纸进行平均,而排除了所有0。

=(FREQUENCY(Start:End!B1,-0.000001)+INDEX(FREQUENCY(Start:End!B1,0),2))