Question

J'ai une feuille de calcul Excel dans un format similaire au suivant...

| 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   |

Je dois convertir ce tableau en une liste des équipes « Top Ten ».Les règles sont

  • Le score de chaque équipe est tiré de la somme de quatre membres de ce club.
  • Ces totaux doivent correspondre aux quatre meilleurs scores, sauf...
    • Chaque équipe doit être composée d'au moins un Junior ou un Lady

Par exemple, dans le tableau ci-dessus, le score de l'équipe du club A serait de 625. pas 640 comme vous prendriez les scores de Harry (190), Bert (150), Jim (150) et Simon (130).Vous ne pouviez pas prendre le score de Fred (145), car cela vous donnerait uniquement des hommes.

Ma question est la suivante : cela peut-il être fait facilement sous la forme d'une série de formules Excel, ou dois-je recourir à quelque chose de plus procédural ?

Idéalement, la solution doit être automatique dans la sélection des équipes, je ne veux pas avoir à créer une formule artisanale distincte pour chaque équipe.Je n’aurai pas non plus nécessairement une liste bien ordonnée des membres de chaque club.Même si je pourrais probablement générer la liste via une feuille de calcul supplémentaire.

Était-ce utile?

La solution

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

Utilisé comme =TopTen(H2,$B$2:$E$30)H2 contient la lettre du club.

Autres conseils

Cela peut-il être fait facilement comme une série de formules Excel

Réponse courte, OUI.(Selon votre définition de « facilement »).

Longue réponse...

(JE pense cela marche)

Voici mes (brèves) données de test :


    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

Maintenant, si j'ai bien compris les règles, nous voulons les quatre meilleurs scores, sauf que si le score le plus élevé d'une dame ou d'un junior ne fait pas partie des quatre meilleurs, nous l'utilisons au lieu du quatrième.Je l'ai quelque peu reformulé, pour des raisons qui peuvent devenir évidentes...

D'ACCORD.Les formules matricielles à la rescousse !(J'espère)

Le score le plus élevé de l'équipe A devrait être

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

où le {} indique une formule matricielle créée en utilisant Control-Shift-Enter pour saisir la formule.Les quatre premiers sont créés de la même manière.Pour le bit Lady/Junior, il nous faut un peu plus de complexité.En prenant la Dame, nous avons besoin de ceci :

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

J'espère que Junior peut être laissé en toute sécurité comme exercice pour l'élève.

Je regarde maintenant une table avec la disposition suivante pour le club "a"


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

Le score du club doit être constitué des trois meilleurs scores « n'importe qui » ​​plus le meilleur score féminin ou junior. s'ils ne sont pas déjà dans le top quatre.

Donc au T2 je mets ceci :

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

MAX(O2,P2) m'indique le meilleur score féminin ou junior, qui doit être inclus.S'il est supérieur au quatrième score d'équipe le plus élevé, alors il est déjà dans la liste et nous prenons simplement les quatre premiers.Sinon, nous remplaçons le quatrième score le plus élevé par le meilleur score dame/junior.

Maintenant, nous pourrions tout faire en une seule formule, en remplaçant les parties dans la formule finale :

{=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)))}

Mais je ne le recommande pas...

Donc pour les données ci-dessus, j'obtiens ceci :


            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       

Les rats.Dans mon enthousiasme à l'idée (je pense) de faire la partie la plus difficile du travail, j'ai oublié de mentionner que

  • La liste des scores peut être dans n'importe quel ordre
  • Vous pouvez obtenir le classement des clubs avec RANK()
  • Vous pouvez ensuite extraire le top 10 dans une autre table en utilisant MATCH() et 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   

Les colonnes A et B sont nos scores calculés, la colonne E est l'ordre dans lequel les clubs figureront dans le tableau final.Les autres formules sont les suivantes :

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

Ce que je fais est nul, mais ça marche.

Créez simplement une nouvelle colonne puis insérez cette formule =If(a1=N,b1,0)A1 est la colonne des critères, N est un critère et B1 se trouve dans la colonne à partir de laquelle vous essayez d'obtenir le plus grand.Ensuite, je fais juste la grande formule dans une autre colonne.

Parfois, je suis très fantaisiste et au lieu de déployer un N, je vais lui faire dire $C$1, puis épelez les critères dans cette cellule.

La réponse parfaite serait que Microsoft ajoute un largeifs (veuillez lire ceci Microsoft)

Écrire une solution en VBA serait mon premier choix, surtout si les règles risquent de devenir plus complexes.

Utilisez un tableau croisé dynamique qui agira comme une requête de base de données sur les données dont vous disposez.Pivotez pour que les équipes descendent dans les colonnes et que les membres de l'équipe ainsi que leur type de statut traversent le tableau croisé dynamique.Je ne suis pas sûr pour 2003, mais Excel 2007 vous permet ensuite de trier afin que les scores les plus élevés apparaissent à gauche.Ensuite, votre première somme peut simplement prendre les trois premiers scores de chaque équipe.Cependant pour obtenir la somme des dernières personnes, vous devez déterminer si vous pouvez utiliser le 4ème score, ou si vous devez utiliser le maximum des types junior ou Lady.Cela pourrait être fait en utilisant une formule complexe et brutale comme celle-ci :

si (type de poste 1 est une junior ou une dame ou...2 ou 3...) puis utilisez la position 4 sinon si la position 5 est une junior ou une dame puis utilisez 5 sinon si p 6 est ...et ainsi de suite.

Je ne pense pas que cela puisse être fait à moins que le tableau ne soit trié d'une manière ou d'une autre.La plupart des fonctions de recherche d'Excel nécessitent des listes ordonnées.Cela pourrait certainement être fait avec une fonction VBA.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top