基于复杂的团队规则,在Excel中排名前十

我有一个类似于以下格式的Excel电子表格…

| NAME | CLUB | STATUS | SCORE | | Fred | a | Gent | 145 | | Bert | a | Gent | 150 | | Harry | a | Gent | 195 | | Jim | a | Gent | 150 | | Clare | a | Lady | 99 | | Simon | a | Junior | 130 | | John | b | Junior | 130 | : : | Henry | z | Gent | 200 | 

我需要把这个表格转换成“十佳”队伍的名单。 规则是

  • 每个队的得分是从该俱乐部的四名成员的总和。
  • 这些总数应该是最好的四个分数,除了…
    • 每个小组必须由至less一名less年或女士组成

例如,在上面的表格中,俱乐部A的得分是625 而不是 640,因为你会得到哈利(190),伯特(150),吉姆(150)和西蒙(130)的分数。 你不能把弗雷德(145)的分数,因为这只会给你男性。

我的问题是,这可以很容易做到一系列的Excel公式,还是我需要诉诸使用更多的程序?

理想情况下,解决scheme需要在团队select中自动化,我不想为每个团队创build单独的手工制作公式。 我也不一定有一个整齐有序的俱乐部成员名单。 虽然我可能可以通过额外的计算表来生成列表。

 Public Function TopTen(Club As String, Scores As Range) Dim i As Long Dim vaScores As Variant Dim bLady As Boolean Dim lCnt As Long Dim lTotal As Long vaScores = FilterOnClub(Scores.Value, Club) vaScores = SortOnScore(vaScores) For i = LBound(vaScores, 2) To UBound(vaScores, 2) If lCnt = 3 And Not bLady Then If vaScores(3, i) <> "Gent" Then lTotal = lTotal + vaScores(4, i) bLady = True lCnt = lCnt + 1 End If Else lTotal = lTotal + vaScores(4, i) lCnt = lCnt + 1 If vaScores(3, i) <> "Gent" Then bLady = True End If If lCnt = 4 Then Exit For Next i TopTen = lTotal End Function Private Function FilterOnClub(vaScores As Variant, sClub As String) As Variant Dim i As Long, j As Long Dim aTemp() As Variant For i = LBound(vaScores, 1) To UBound(vaScores, 1) If vaScores(i, 2) = sClub Then j = j + 1 ReDim Preserve aTemp(1 To 4, 1 To j) aTemp(1, j) = vaScores(i, 1) aTemp(2, j) = vaScores(i, 2) aTemp(3, j) = vaScores(i, 3) aTemp(4, j) = vaScores(i, 4) End If Next i FilterOnClub = aTemp End Function Private Function SortOnScore(vaScores As Variant) As Variant Dim i As Long, j As Long, k As Long Dim aTemp(1 To 4) As Variant For i = 1 To UBound(vaScores, 2) - 1 For j = i To UBound(vaScores, 2) If vaScores(4, i) < vaScores(4, j) Then For k = 1 To 4 aTemp(k) = vaScores(k, j) vaScores(k, j) = vaScores(k, i) vaScores(k, i) = aTemp(k) Next k End If Next j Next i SortOnScore = vaScores End Function 

使用as =TopTen(H2,$B$2:$E$30)其中H2包含俱乐部信件。

这可以很容易地做成一系列的Excel公式

简短的回答,是的。 (根据你的“简单”的定义)。

长答案…

(我认为这是有效的)

这是我的(简短)testing数据:

 ABCD 1 NAME CLUB STATUS SCORE 2 Kevin a Gent 145 3 Lyle a Gent 150 4 Martin a Gent 195 5 Norm a Gent 150 6 Oonagh a Lady 100 7 Arthur b Gent 200 8 Brian b Gent 210 9 Charlie b Gent 190 10 Donald b Gent 220 11 Eddie b Junior 150 12 Quentin c Gent 145 13 Ryan c Gent 150 14 Sheila c Lady 195 15 Trevor c Gent 150 16 Ursula c Junior 200 

现在,如果我正确地理解了这些规则,我们希望得到最好的四个分数,但是如果一个女士或一个初中的最高分不是最好的四分,那么我们使用这个分数而不是第四个分数。 我已经重申了一些,因为可能会变得明显的原因…

好。 arrays公式来拯救! (我希望)

a队的最高得分应该是

 {=LARGE(IF(B2:B16="a",D2:D16,0),1)} 

其中{}表示使用Control-Shift-Enter创build的公式input公式的数组公式。 排名前四的是类似的创造。 对于女士/青less年,我们需要更多的复杂性。 以夫人,我们需要这个:

 {=LARGE(IF($B$2:$B$16=$J3,IF($C$2:$C$16="Lady",$D$2:$D$16,0),0),1)} 

less年可以安全地留下来作为学生的锻炼,我希望。

我现在正在看一张桌子,下面是俱乐部“a”的布局

 JKLMNOP 1 Club 1 2 3 4 Lady Junior 2 a 195 150 150 145 100 0 

俱乐部得分应该是前三名的“任何人”得分加上最好的女士或青less年, 如果他们还没有进入前四

所以在第二季度我把这个:

 =SUM(K2:M2)+MIN(MAX(O2,P2),N2) 

MAX(O2,P2)告诉我最好的女士或青less年的成绩,必须包括在内。 如果它高于第四高的球队得分,那么它已经在列表中,我们只是排在前四名。 否则,我们用最好的女士/小辈取代第四高分。

现在我们可以用一个公式来完成所有的工作,将这些部分代入最终公式:

 {=LARGE(IF($B$2:$B$16=$J3,$D$2:$D$16,0),1)+ LARGE(IF($B$2:$B$16=$J3,$D$2:$D$16,0),2)+ LARGE(IF($B$2:$B$16=$J3,$D$2:$D$16,0),3)+ MIN(LARGE(IF($B$2:$B$16=$J3,$D$2:$D$16,0),4), MAX(LARGE(IF($B$2:$B$18=$J3,IF($C$2:$C$18="Lady",$D$2:$D$18,0),0),1), LARGE(IF($B$2:$B$18=$J3,IF($C$2:$C$18="Junior",$D$2:$D$18,0),0),1)))} 

但我不推荐它…

所以对于上面的数据,我最终得到这个:

 Anyone Lady Junior Club 1 2 3 4 1 1 Total a 195 150 150 145 100 0 595 b 220 210 200 190 0 150 780 c 200 195 150 150 195 200 695 

大鼠。 在我感到兴奋的时候,我忘了提到这一点

  • 分数列表可以以任何顺序
  • 你可以通过RANK()获得俱乐部排名
  • 然后,您可以使用MATCH()和INDEX()将前10个拉到另一个表中
 ABCDEFGH 1 club Sc Rank UniqRk Pos Club Score 2 third-equal#1 80 3 79.999980 1 1 best 100 3 second 90 2 89.999970 2 2 second 90 4 third-equal#2 80 3 79.999960 3 3 third-equal#1 80 5 best 100 1 99.999950 4 3 third-equal#2 80 6 worst 70 5 69.999940 5 5 worst 70 

A栏和B栏是我们的计算得分,E栏是决赛桌上输出俱乐部的顺序。 其他公式如下:

 C: =RANK(B2,$B$2:$B$6) # what it says, with ties both getting the lower number D: =B2-ROW()*0.00001 # score, modified slightly to ensure uniqueness F: =SMALL($C$2:$C$6,E2) # first output column, ranks including ties G: =INDEX($A$2:$A$6,MATCH(LARGE($D$2:$D$6,E2),$D$2:$D$6,0)) # club name for position, using the modified score in D H: =INDEX($B$2:$B$6,MATCH(LARGE($D$2:$D$6,E2),$D$2:$D$6,0)) # as G, but indexes into scores 

我所做的是跛脚,但它的工作原理。

只要创build一个新的列,然后插入这个公式=If(a1=N,b1,0)其中A1是标准列, N是标准,而B1是在试图从中获得大的列。 然后,我只是在另一列做大公式。

有时候我会喜欢,而不是推出一个N ,我会把它说成$C$1 ,然后把那个单元格中的标准拼出来。

完美的答案是让微软添加一个大largeifs (请阅读这个微软)

在VBA中编写解决scheme将是我的首选,特别是如果规则有可能变得更加复杂。

使用数据透视表,它将充当您拥有的数据的数据库查询。 枢轴,使团队沿着列和团队成员沿着他们的状态types穿过数据透视表。 我不知道2003年,但Excel 2007让你然后sorting,所以最高分数出现在左侧。 那么你的第一笔总和可以简单地拿出每个队的前三个分数。 但是,要获得最后一个人的总和,您必须确定您是否可以使用第四个分数,或者是否必须使用初级或女士types的最大值。 这可以使用一个复杂的暴力公式来完成,就像这样:

如果(位置1的types是小辈或女士或者… 2或3 …)则使用位置4否则如果位置5是小辈或女士则使用5否则如果p 6是…等等。

我不认为这是可以完成的,除非表以某种方式sorting。 Excel的大部分查找function都需要有序列表。 这当然可以用VBAfunction来完成。