複雑なチームルールに基づいた Excel でのトップ 10 の順序付け
-
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 |
この表を「トップ 10」チームのリストに変換する必要があります。ルールは次のとおりです
- 各チームのスコアは、そのクラブの 4 人のメンバーの合計から計算されます。
- これらの合計は、以下を除く上位 4 つのスコアである必要があります。
- 各チームは少なくとも 1 人のジュニアまたはレディースで構成されなければなりません
たとえば、上の表では、クラブ A のチーム スコアは 625 になります。 ない ハリー (190)、バート (150)、ジム (150)、サイモン (130) のスコアを計算すると、640 になります。フレッドのスコア (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
さて、ルールを正しく理解していれば、ベスト 4 のスコアが必要になります。ただし、女性またはジュニアのいずれかの最高スコアがベスト 4 に含まれていない場合は、4 番目に高いスコアの代わりにそれを使用します。理由が明らかになる可能性があるため、多少再説明しました...
わかりました。配列数式が役に立ちます!(願っています)
チームaの最高得点は次のとおりです
{=LARGE(IF(B2:B16="a",D2:D16,0),1)}
ここで、{} は、Ctrl+Shift+Enter を使用して数式を入力することによって作成された配列数式を示します。上位 4 つも同様に作成されます。Lady/Junior ビットについては、もう少し複雑にする必要があります。Lady を例にとると、次のものが必要です。
{=LARGE(IF($B$2:$B$16=$J3,IF($C$2:$C$16="Lady",$D$2:$D$16,0),0),1)}
ジュニアが生徒の練習として安全に残されることを願っています。
今、クラブ「a」の次のレイアウトを持つテーブルを見ています。
J K L M N O P
1 Club 1 2 3 4 Lady Junior
2 a 195 150 150 145 100 0
クラブのスコアは、「誰でも」の上位 3 つのスコアに、最も優秀な女性またはジュニアのスコアを加えたものである必要があります。 まだトップ4に入っていない場合.
そこで、第 2 四半期にこれを入れます。
=SUM(K2:M2)+MIN(MAX(O2,P2),N2)
MAX(O2,P2) は、最高のレディまたはジュニアのスコアを教えてくれます。これを含める必要があります。4番目に高いチームスコアより高ければ、すでにリストに入っており、トップ4を獲得するだけです。それ以外の場合は、4 番目に高いスコアを最高の女性/ジュニアのスコアに置き換えます。
最終的な式に各部分を代入することで、すべてを 1 つの式で実行できるようになりました。
{=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 件を別のテーブルに取り込むことができます。
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
(マイクロソフトのこの記事をお読みください)
特にルールがより複雑になる可能性がある場合は、VBA でソリューションを作成することが第一の選択肢になります。
所有するデータに対するデータベース クエリとして機能するピボット テーブルを使用します。ピボットすると、チームが列の下に移動し、チーム メンバーがステータス タイプとともにピボット テーブル全体に表示されます。2003 についてはわかりませんが、Excel 2007 では、最高スコアが左側に表示されるように並べ替えることができます。その後、最初の合計は各チームの最初の 3 つのスコアを単純に取得することができます。ただし、最後の人の合計を取得するには、4 番目のスコアを使用できるかどうか、またはジュニアまたはレディ タイプの最大値を使用する必要があるかどうかを判断する必要があります。これは、次のような複雑で強引な式を使用して実行できます。
if (役職の種類 1 が後輩か女性か...2つか3つ...) 次に、位置 5 がジュニアまたは女性の場合は位置 4 を使用し、それ以外の場合は p 6 の場合は 5 を使用します...等々。
何らかの形で表を整理しないとこれはできないと思います。Excel の検索関数のほとんどには、順序付きリストが必要です。これは確かに VBA 関数を使用して実行できます。