COUNTIFS VLOOKUP返回一个值?

时间:2015-11-29 22:11:26

标签: excel vlookup countif

我被困在一个公式上。基本上我想要做的是根据从另一张纸上提取的数据,计算特定值在一张纸上出现的次数。

E.g。我有三张床单。一张工作表包含一个作业列表和一个与客户端关联的代码。第二张表有客户端列表和客户端的详细信息。第三张是我的结果表。

我想计算每家公司的How Heards。例如,在下面的表1中,Apple有3个客户。如果我们使用客户代码ID并转到表2,我们可以看到它将共有2个在线和0个Facebook。此结果显示在工作表3上。结果表。

第1页示例

Sheet1

第2页示例

Sheet 2

工作表3示例(我希望结果从计算中看起来如何)

enter image description here

2 个答案:

答案 0 :(得分:2)

为了真正为这个问题提供合适的答案,这里有一些VBA代码允许工作簿创建与自身的ADO连接并使用SELECT,DISTINCT,WHERE,INNER JOIN,GROUP BY和ORDER生成报告BY条款。

Sub Inner_Join()
    Dim cnx As Object, rs As Object
    Dim sWS1 As String, sWS2 As String, sWB As String, sCNX As String, sSQL As String
    Dim ws1TBLaddr As String, ws2TBLaddr As String

    'Collect some string literals that will be used to build SQL
    ws1TBLaddr = Worksheets("Sheet1").Cells(1, 1).CurrentRegion.Address(0, 0)
    sWS1 = Worksheets("Sheet1").Name
    ws2TBLaddr = Worksheets("Sheet2").Cells(1, 1).CurrentRegion.Address(0, 0)
    sWS2 = Worksheets("Sheet2").Name
    sWB = ThisWorkbook.FullName

    'Build the connection string
    'The first is for 64-bit Office; the second is more universal
    sCNX = "Provider=Microsoft.Jet.OLEDB.12.0;Data Source=" & sWB _
        & ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"
    sCNX = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & sWB _
        & ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"
    'Debug.Print sCNX

    'Create the necessary ADO objects
    Set cnx = CreateObject("ADODB.Connection")  'late binding; for early binding add
    Set rs = CreateObject("ADODB.Recordset")    'Microsoft AxtiveX Data Objects 6.1 library

    'Open the connection to itself
    cnx.Open sCNX

    With Worksheets("Sheet3")
        'Clear the reporting area
        .Cells(1, 1).CurrentRegion.ClearContents

        'get [Business Name] list from Sheet1
        sSQL = "SELECT DISTINCT w1.[Business Name]"
        sSQL = sSQL & " FROM [" & sWS1 & "$" & ws1TBLaddr & "] w1"
        sSQL = sSQL & " ORDER BY w1.[Business Name]"
        'Debug.Print sSQL

        'Populate Sheet3!A:A
        rs.Open sSQL, cnx
        Do While Not rs.EOF
            'Debug.Print rs.Fields("Business Name")
            .Cells(.Rows.Count, 1).End(xlUp).Offset(1, 0) = rs.Fields("Business Name")
            rs.MoveNext
        Loop
        rs.Close

        'get [How Heard] list from Sheet2
        sSQL = "SELECT DISTINCT w2.[How Heard]"
        sSQL = sSQL & " FROM [" & sWS2 & "$" & ws2TBLaddr & "] w2"
        sSQL = sSQL & " WHERE w2.[How Heard] NOT LIKE 'None'"
        sSQL = sSQL & " ORDER BY w2.[How Heard]"
        'Debug.Print sSQL

        'Populate Sheet3!1:1
        rs.Open sSQL, cnx
        Do While Not rs.EOF
            'Debug.Print rs.Fields("How Heard")
            .Cells(1, .Columns.Count).End(xlToLeft).Offset(0, 1) = rs.Fields("How Heard")
            rs.MoveNext
        Loop
        rs.Close

        'start by seeding zeroes for all
        With .Cells(1, 1).CurrentRegion
            With .Resize(.Rows.Count - 1, .Columns.Count - 1).Offset(1, 1)
                .Cells = 0
            End With
        End With

        'get the counts for the [Business Name]×[How Heard] combinations
        sSQL = "SELECT  COUNT(w1.[Business Name]), w1.[Business Name], w2.[How Heard]"
        sSQL = sSQL & " FROM [" & sWS1 & "$" & ws1TBLaddr & "] w1"
        sSQL = sSQL & " INNER JOIN [" & sWS2 & "$" & ws2TBLaddr & "] w2 ON w1.[Client Code] = w2.[Client Code]"
        sSQL = sSQL & " WHERE w2.[How Heard] <> 'None'"
        sSQL = sSQL & " GROUP BY w1.[Business Name], w2.[How Heard]"
        'Debug.Print sSQL

        'Populate Sheet3 data matrix area
        rs.Open sSQL, cnx
        With .Cells(1, 1).CurrentRegion
            Do While Not rs.EOF
                'Debug.Print rs.Fields(0) & ":" & rs.Fields(1) & ":" & rs.Fields(2)
                .Cells(Application.Match(rs.Fields(1), .Columns(1), 0), _
                       Application.Match(rs.Fields(2), .Rows(1), 0)) = rs.Fields(0)
                rs.MoveNext
            Loop
        End With
        rs.Close
    End With

Final_Cleanup:
    Set rs = Nothing
    cnx.Close: Set cnx = Nothing

End Sub

结果应类似于以下内容。

ADO_Inner_Join_XL

答案 1 :(得分:2)

好的,所以我对@Jeeped的回答印象非常深刻 我的答案不像使用任意SQL那样灵活,但它没有使用VBA,所以它在某些情况下也可能有用。

基本上我的回答是:

  • 从Sheet1创建一个数组,其中包含每个匹配单元格的客户端代码
    (或非匹配单元格的0)

    X = ((Sheet1!$B$2:$B$1000=$A2)*Sheet1!$A$2:$A$1000)
    
  • 从Sheet2创建一个数组,其中包含每个匹配单元格的客户端代码
    (或非匹配单元格的0)

    Y = ((Sheet2!$B$2:$B$2000=B$1)*Sheet2!$A$2:$A$2000)
    
  • 比较两个数组中的每个单元格,其中第一个数组的值不是&lt; t 0 0

    Z = (X<>0)*(X=TRANSPOSE(Y))
    
  • 然后总结匹配数量:

    =SUM(Z)
    

因此,Sheet3!B2的最终公式为:

=SUM((((Sheet1!$B$2:$B$1000=$A2)*Sheet1!$A$2:$A$1000)<>0)*(((Sheet1!$B$2:$B$1000=$A2)*Sheet1!$A$2:$A$1000)=TRANSPOSE(((Sheet2!$B$2:$B$2000=B$1)*Sheet2!$A$2:$A$2000))))

这是一个数组公式,因此您需要按Control-Shift-Enter而不是Enter。然后你需要将它从B2复制到C2,B3等等。

显然,您必须将1000更改为大于Sheet1上的最大rwo,将2000更改为大于Sheet2上最大行的内容。