COUNTIFS VLOOKUP返回一个值?

我坚持一个公式。 基本上我想要做的是根据从另一张表中拉出的数据来计算特定值出现在一张纸上的次数。

比如我有三张床单。 一张纸有一份工作清单和一个与客户相关的代码。 第二张纸上有客户的名单和客户的详细资料。 第三张是我的结果表。

我想要统计每个公司的How Heards。 例如,在下面的表1中,苹果有3个客户。 如果我们使用客户端代码ID并转到表2,我们可以看到它将共有2个在线和0个Facebook。 这个结果显示在第3页。结果表。

表1的例子

工作表Sheet1

工作表2示例

工作表2

工作表3示例(我希望结果看起来像计算)

在这里输入图像说明

为了实际上为这个问题提供一个合适的答案,下面是一些VBA代码,它允许工作簿创build一个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

好吧,我对@Jeeped的答案留下了深刻的印象。我的答案不像使用任意SQL那样灵活,但它不使用VBA,因此在某些情况下也可能有用。

所以我的答案基本上:

  • 从Sheet1创build一个包含每个匹配单元的客户端代码的数组
    (或者0表示不匹配的单元格)

     X = ((Sheet1!$B$2:$B$1000=$A2)*Sheet1!$A$2:$A$1000) 
  • 从Sheet2创build一个包含每个匹配单元的客户端代码的数组
    (或者0表示不匹配的单元格)

     Y = ((Sheet2!$B$2:$B$2000=B$1)*Sheet2!$A$2:$A$2000) 
  • 比较两个数组中第一个数组的值不是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上最大的那个大一些。