[英]Excel array formula to sum for criteria then sort
寻找一个excel数组公式来对每个“代码”的“权重”求和,并按权重对“代码”进行排序。
| A | B | C | D | E |
|1 | Code | Weight | | Code |TotWeight|
|2 | 444 | 30 | | 444 | 50 |
|3 | 333 | 10 | | 222 | 40 |
|4 | 222 | 10 | | 333 | 40 |
|5 | 444 | 10 | | 555 | 20 |
|6 | 444 | 10 |
|7 | 222 | 30 |
|8 | 333 | 20 |
|9 | 555 | 20 |
|10| 333 | 10 |
Cols A 和 B 是输入,D 和 E 是输出。
虽然这可能最终可以通过复杂且计算密集型的数组公式实现,但出于所有意图和目的,您实际上是在尝试使用聚合 SUM、GROUP BY 和 ORDER BY 子句来完成数据库 SELECT 语句。 就像是,
SELECT code, weight FROM
(SELECT cw.code, Sum(cw.weight) AS weight
FROM tblCodeWeights AS cw
GROUP BY cw.code)
ORDER BY weight DESC, code;
我建议使用 ADODB.Connection 到工作表的 VBA 子程序,它可以产生您想要实现的结果。 下面的代码很冗长,可能会被删减一点,但操作的每个方面都得到处理,应该是不言自明或易于研究的。
Option Explicit
Sub sortedFilteredSums()
Dim cnx As Object, rs As Object
Dim sWS1 As String, sWB As String, sCNX As String, sSQL As String
Dim ws1TBLaddr As String
With Worksheets("Sheet8")
ws1TBLaddr = .Cells(1, 1).CurrentRegion.Address(0, 0)
sWS1 = Worksheets("Sheet8").Name
End With
sWB = ThisWorkbook.FullName
sCNX = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & sWB _
& ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"
Debug.Print sCNX
Set cnx = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cnx.Open sCNX
sSQL = "SELECT [code], [weight] FROM ("
sSQL = sSQL & " SELECT cw.[code], SUM(cw.[weight]) AS [weight]"
sSQL = sSQL & " FROM [" & sWS1 & "$" & ws1TBLaddr & "] cw"
sSQL = sSQL & " GROUP BY cw.code"
sSQL = sSQL & ") ORDER BY [weight] DESC, [code]"
Debug.Print sSQL
'SELECT code, weight FROM
' (SELECT cw.code, Sum(cw.weight) AS weight
' FROM tblCodeWeights AS cw
' GROUP BY cw.code)
'ORDER BY weight DESC, code;
rs.Open sSQL, cnx
With Worksheets("Sheet8")
.Range("D1").Resize(1, 2) = Array("code", "totweight")
.Range("D2").CopyFromRecordset rs
End With
rs.Close: Set rs = Nothing
cnx.Close: Set cnx = Nothing
End Sub
请注意,这不能在尚未保存的工作簿上执行; 例如,不在新的无标题工作簿上。 您的结果应该类似于以下内容。
用于此示例的测试工作簿暂时可从以下位置获得:
正如@Jeeped 所解释的,这个请求非常复杂。 然而,它可以在工作列的帮助下通过公式来实现。
假设您的数据位于A1:B11
标题列C
为Total.Weight
并在C2:C11
输入此公式:
=IF(COUNTIF($A$1:$A2,$A2)>1,"", SUMIF($A$1:$A$11,$A2,$B$1:$B$11))
然后使用位于F2:G11
的预期结果输入以下公式:
在F2:F11
: =IF(EXACT($G2,""),"",INDEX($A$1:$A$11,MATCH($G2,$C$1:$C$11,0)))
在G2:G11
: =IFERROR(LARGE($C$1:$C$11,COUNTA($F$1:$F1)),"")
上述公式适用于问题中提供的数据。
但是,如果代码具有相同的总重量,则需要额外的工作栏。
标题列D
作为Rank
并输入此公式以对总重量进行排名(见图 2):
在D2:D11
:
=IFERROR(RANK.EQ($C2,$C$2:$C$11, 0) +COUNTIF($D$1:$D1,RANK.EQ($C2,$C$2:$C$11, 0)),"")
F2:G11
处的公式应该是这些:
在F2:F11
: =IFERROR(INDEX($A$1:$A$11,MATCH(COUNTA($F$1:$F1),$D$1:$D$11,0)),"")
在G2:G11
: =IF(EXACT($F2,""),"",SUMIF($A$1:$A$11,$F2,$B$1:$B$11))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.