質問

次のような形式の 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 関数を使用して実行できます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top