Excel数组公式对条件求和,然后排序

Excel数组公式对条件求和,然后排序,excel,array-formulas,Excel,Array Formulas,寻找excel数组公式来计算每个“代码”的“权重”之和,并按权重顺序对“代码”进行排序 | A | B | C | D | E | |1 | Code | Weight | | Code |TotWeight| |2 | 444 | 30 | | 444 | 50 | |3 | 333 | 10 | | 222 | 40 | |4 |

寻找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   |

列A和B是输入,D和E是输出。

虽然这最终可能通过复杂且计算密集的数组公式实现,但出于所有目的,您实际上是在尝试使用聚合和、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
请注意,这不能在尚未保存的工作簿上执行;e、 g.不在新的无标题工作簿上。您的结果应该与以下类似

本示例中使用的测试工作簿暂时可从以下网站获得:


正如@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(精确($G2,“”),索引($A$1:$A$11,匹配($G2,$C$1:$C$11,0))

G2:G11
=IFERROR(大($C$1:$C$11,COUNTA($F$1:$F1)),“”)

图1

上述公式适用于问题中提供的数据

但是,如果存在总重量相同的代码,则需要额外的工作列

标题栏
D
Rank
,并输入此公式对总重量进行排序(见图2):

D2:D11
中:

=IFERROR(等级相等($C2,$C$2:$C$11,0)
+COUNTIF($D$1:$D1,RANK.EQ($C2,$C$2:$C$11,0)),”)

F2:G11处的公式应为:

F2:F11
=IFERROR(索引($A$1:$A$11,匹配(COUNTA($F$1:$F1),$D$1:$D$11,0)),“”)中,

G2:G11
=IF(精确($F2,“”)”),SUMIF($A$1:$A$11,$F2,$B$1:$B$11))


图2

谢谢。我想要一个不使用VBA的解决方案。