Десять лучших заказов в Excel на основе сложных командных правил
-
09-06-2019 - |
Вопрос
У меня есть таблица 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, или мне придется прибегнуть к чему-то более процедурному?
В идеале решение должно быть автоматическим при выборе команды, я не хочу создавать отдельную формулу, созданную вручную для каждой команды.У меня также не обязательно будет четко упорядоченный список членов каждого клуба.Хотя я, вероятно, мог бы составить список с помощью дополнительного листа расчетов.
Решение
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
содержит клубное письмо.
Другие советы
Можно ли это сделать легко как серия формулы 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
Теперь, если я правильно понял правила, нам нужны четыре лучших результата, за исключением того, что если наивысший балл женщины или юниора не входит в четверку лучших, мы используем его вместо четвертого по величине результата.Я несколько переформулировал это по причинам, которые могут стать очевидными...
ХОРОШО.Формулы массива вам в помощь!(Я надеюсь)
Наивысший балл команды А должен быть
{=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 лучших в другую таблицу, используя ПОИСКПОЗ() и ИНДЕКС().
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
То, что я делаю, отстойно, но это работает.
Просто создайте новый столбец и вставьте эту формулу =If(a1=N,b1,0)
где A1
столбец критериев, N
это критерии и B1
находится в столбце, из которого вы пытаетесь получить большое значение.Затем я просто выполняю большую формулу в другом столбце.
Иногда мне приходит в голову всякая фантазия, и вместо того, чтобы выкатить N
, я заставлю это сказать $C$1
, затем укажите критерии в этой ячейке.
Идеальным ответом было бы, чтобы Microsoft добавила largeifs
(пожалуйста, прочитайте это Microsoft)
Написание решения на VBA было бы моим первым выбором, особенно если правила могут усложниться.
Используйте сводную таблицу, которая будет выполнять функцию запроса к базе данных по имеющимся у вас данным.Поверните так, чтобы команды двигались вниз по столбцам, а члены команды вместе со своим типом статуса перемещались по сводной таблице.Я не уверен насчет 2003 года, но Excel 2007 позволяет выполнить сортировку таким образом, чтобы самые высокие баллы отображались слева.Тогда ваша первая сумма может просто состоять из первых трех очков каждой команды.Однако, чтобы получить сумму последнего человека, вам необходимо определить, можете ли вы использовать 4-й балл или вам нужно использовать максимум юниоров или леди.Это можно сделать, используя сложную и грубую формулу, примерно такую:
если (тип позиции 1 - юниор или дама или...2 или 3...) затем используйте позицию 4, иначе, если позиция 5 — юниор или леди, тогда используйте 5, иначе, если позиция 6 — ...и так далее.
Я не думаю, что это можно сделать, если таблица не отсортирована каким-либо образом.Большинству функций поиска Excel требуются упорядоченные списки.Это, безусловно, можно сделать с помощью функции VBA.