簡體   English   中英

Excel數組公式對條件求和然后排序

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

請注意,這不能在尚未保存的工作簿上執行; 例如,不在新的無標題工作簿上。 您的結果應該類似於以下內容。

sum_group_order

用於此示例的測試工作簿暫時可從以下位置獲得:

ADO Select Sum Group By.xlsb

正如@Jeeped 所解釋的,這個請求非常復雜。 然而,它可以在工作列的幫助下通過公式來實現。

假設您的數據位於A1:B11

標題列CTotal.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)),"")

圖。1 圖。1

上述公式適用於問題中提供的數據。

但是,如果代碼具有相同的總重量,則需要額外的工作欄。

標題列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))

在此處輸入圖片說明 圖2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM