[英]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.