10 лучших заказов в Excel на основе сложных командных правил - PullRequest
3 голосов
/ 12 сентября 2008

У меня есть таблица 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   |

Мне нужно преобразовать эту таблицу в список команд «Десятки». Правила

  • Каждый результат команды берется из суммы четырех членов этого клуба.
  • Эти итоги должны быть из лучших четырех оценок, кроме ...
    • Каждая команда должна состоять как минимум из одного юниора или леди

Например, в приведенной выше таблице счет команды для клуба А будет 625 , а не 640, так как вы наберете очки для Гарри (190), Берта (150), Джима (150) и Саймона. (130). Вы не могли взять счет Фреда (145), так как это дало бы вам только гентский доход.

У меня вопрос: можно ли сделать это легко в виде серии формул Excel или мне нужно прибегнуть к использованию чего-то более процедурного?

В идеале решение должно быть автоматическим при выборе команд, я не хочу создавать отдельную формулу для каждой команды. У меня также не обязательно будет аккуратно упорядоченный список членов каждого клуба. Хотя я мог бы, вероятно, сгенерировать список с помощью дополнительного расчетного листа.

Ответы [ 6 ]

2 голосов
/ 15 сентября 2008

это можно легко сделать как серию Формула Excel

Краткий ответ, ДА. (В зависимости от вашего определения «легко»).

Длинный ответ ...

думаю это работает)

Вот мои (краткие) данные испытаний:


    A          B    C        D
 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

Теперь, если я правильно понял правила, мы хотим получить лучшие четыре балла, за исключением того, что, если наивысшая оценка, полученная девушкой или юниором, не входит в лучшие четыре, мы используем ее вместо четвертого наивысшего. Я переформулировал это несколько раз по причинам, которые могут стать очевидными ...

OK. Массив формул на помощь! (Надеюсь)

Наивысшая оценка команды А должна составлять

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

где {} указывает формулу массива, созданную с помощью Control-Shift-Enter для ввода формулы. Лучшие четыре созданы аналогично. Для Леди / Джуниора нам нужно немного больше сложности. Взяв Леди, нам нужно это:

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

Я надеюсь, что младшего можно спокойно оставить в качестве упражнения для ученика.

Я сейчас смотрю на стол со следующей раскладкой для клуба "а"


     J    K      L      M      N      O      P
 1 Club    1      2      3      4   Lady  Junior
 2 a     195    150    150    145    100      0

Клубный счет должен быть в тройке лучших "кто угодно" плюс лучшая дама или юниор , если они еще не вошли в первую четверку .

Итак, во втором квартале я помещаю это:

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

MAX (O2, P2) говорит мне лучшую женскую или младшую оценку, которая должна быть включена. Если он выше, чем четвертый результат команды, он уже в списке, и мы просто берем четверку лучших. В противном случае мы заменяем четвертый по величине балл на лучшую женскую / младшую.

Теперь мы можем сделать все это в одной формуле, подставив части в окончательную формулу:

{=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 ()
  • Затем вы можете вытянуть первые 10 в другую таблицу, используя MATCH () и INDEX ()

    A               B       C       D           E       F       G               H    
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
2 голосов
/ 13 сентября 2008
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

Используется как =TopTen(H2,$B$2:$E$30), где H2 содержит клубное письмо.

1 голос
/ 14 сентября 2011

То, что я делаю, хромает, но это работает.

Просто создайте новый столбец и вставьте эту формулу =If(a1=N,b1,0), где A1 - столбец критериев, N - критерии, а B1 - в столбце, из которого вы пытаетесь получить большое значение. Тогда я просто делаю большую формулу в другом столбце.

Иногда мне все кажется, и вместо того, чтобы выкатить N, я заставлю его сказать $C$1, а затем изложу критерии в этой клетке.

Идеальный ответ: Microsoft добавит largeifs (пожалуйста, прочтите это Microsoft)

0 голосов
/ 12 сентября 2008

Я не думаю, что это можно сделать, если таблица не отсортирована каким-либо образом. Большинство функций поиска в Excel требуют упорядоченных списков. Это, безусловно, можно сделать с помощью функции VBA.

0 голосов
/ 12 сентября 2008

Написание решения в VBA будет моим первым выбором, особенно если правила могут стать более сложными.

0 голосов
/ 12 сентября 2008

Используйте сводную таблицу, которая будет выступать в качестве запроса базы данных к имеющимся у вас данным. Поворачивайте так, чтобы команды шли вниз по столбцам, а члены команды вместе с их типом статуса проходили по сводной таблице. Я не уверен в 2003 году, но Excel 2007 позволяет вам сортировать, так что самые высокие баллы отображаются слева. Тогда ваша первая сумма может просто взять первые три результата для каждой команды. Однако, чтобы получить сумму последнего человека, вы должны определить, можете ли вы использовать 4-й счет или использовать максимум типов юниоров или леди. Это можно сделать, используя сложную формулу грубой силы, примерно так:

если (тип позиции 1 - юниор или леди или ... 2 или 3 ...), тогда используйте позицию 4, если позиция 5 - младший или леди, затем используйте 5 еще, если p 6 - ... и т. д.

...