Domanda

Ho un foglio di calcolo Excel in un formato simile al seguente...

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

Devo convertire questa tabella in un elenco delle squadre "Top Ten".Le regole sono

  • Il punteggio di ogni squadra viene preso dalla somma di quattro membri di quel club.
  • Questi totali dovrebbero corrispondere ai migliori quattro punteggi, tranne...
    • Ogni squadra dovrà essere composta da almeno un Junior o Lady

Ad esempio, nella tabella sopra il punteggio della squadra per il club A sarebbe 625 non 640 come prenderesti i punteggi di Harry(190), Bert(150), Jim(150) e Simon(130).Non potresti prendere il punteggio di Fred (145) perché ti darebbe solo Gents.

La mia domanda è: è possibile farlo facilmente con una serie di formule Excel o dovrò ricorrere a qualcosa di più procedurale?

Idealmente la soluzione deve essere automatica nelle selezioni della squadra, non voglio dover creare formule separate e realizzate a mano per ogni squadra.Inoltre, non avrò necessariamente un elenco ben ordinato dei membri di ciascun club.Anche se probabilmente potrei generare l'elenco tramite un foglio di calcolo aggiuntivo.

È stato utile?

Soluzione

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

Usare come =TopTen(H2,$B$2:$E$30) Dove H2 contiene la lettera del club.

Altri suggerimenti

Questo può essere fatto facilmente come una serie di formula Excel

Risposta breve, SI.(A seconda della tua definizione di "facilmente").

Risposta lunga...

(IO pensare funziona)

Ecco i miei (brevi) dati di 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

Ora, se ho capito bene le regole, vogliamo i migliori quattro punteggi, tranne che se il punteggio più alto di una donna o di un junior non è tra i migliori quattro, usiamo quello invece del quarto più alto.L'ho in qualche modo ribadito, per ragioni che potrebbero diventare evidenti...

OK.Formule di matrice in soccorso!(Spero)

Dovrebbe essere il punteggio più alto della squadra A

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

dove {} indica una formula di matrice creata utilizzando Control-Shift-Invio per inserire la formula.I primi quattro vengono creati in modo simile.Per la parte Lady/Junior, abbiamo bisogno di un po' più di complessità.Prendendo la Signora, abbiamo bisogno di questo:

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

Spero che Junior possa tranquillamente essere lasciato come esercizio per lo studente.

Ora sto guardando una tabella con il seguente layout per il 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

Il punteggio del club dovrebbe essere costituito dai primi tre punteggi di "chiunque" più la migliore donna o junior se non sono già tra i primi quattro.

Quindi nella Q2 inserisco questo:

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

MAX(O2,P2) mi dice il punteggio migliore femminile o junior, che deve essere incluso.Se è superiore al quarto punteggio più alto della squadra, è già nell'elenco e prendiamo solo i primi quattro.Altrimenti sostituiremo il quarto punteggio più alto con quello della migliore lady/junior.

Ora potremmo fare tutto in un'unica formula, sostituendo le parti nella formula 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)))}

Ma non lo consiglio...

Quindi, per i dati di cui sopra, finisco con questo:


            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       

Ratti.Nella mia eccitazione per (credo) riuscire a far funzionare la parte difficile, ho dimenticato di dirlo

  • L'elenco dei punteggi può essere in qualsiasi ordine
  • Puoi ottenere la classifica del club con RANK()
  • Puoi quindi inserire i primi 10 in un'altra tabella utilizzando MATCH() e 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   

Le colonne A e B sono i nostri punteggi calcolati, la colonna E è l'ordine in cui i club verranno inseriti nel tavolo finale.Le altre formule sono le seguenti:

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

Quello che faccio è noioso, ma funziona.

Crea semplicemente una nuova colonna, quindi inserisci questa formula =If(a1=N,b1,0) Dove A1 è la colonna dei criteri, N è criteri e B1 è nella colonna da cui stai cercando di ottenere il valore grande.Quindi eseguo semplicemente la formula grande in un'altra colonna.

A volte divento tutto fantasioso e invece di stendere un N, lo farò dire $C$1, quindi specifica i criteri in quella cella.

La risposta perfetta sarebbe che Microsoft aggiungesse un file largeifs (si prega di leggere questo Microsoft)

Scrivere una soluzione in VBA sarebbe la mia prima scelta, soprattutto se le regole hanno la possibilità di diventare più complesse.

Utilizza una tabella pivot che fungerà da query del database sui dati in tuo possesso.Ruota in modo che i team scendano nelle colonne e i membri del team insieme al loro tipo di stato attraversino la tabella pivot.Non sono sicuro per il 2003, ma Excel 2007 ti consente di ordinare in modo che i punteggi più alti vengano visualizzati a sinistra.Quindi la tua prima somma può semplicemente prendere i primi tre punteggi per ciascuna squadra.Tuttavia per ottenere la somma delle ultime persone, devi determinare se puoi utilizzare il 4° punteggio, o se devi utilizzare il massimo dei tipi junior o lady.Ciò potrebbe essere fatto utilizzando una formula complessa e di forza bruta simile a questa:

se (tipo di posizione 1 è junior o lady oppure...2 o 3...) quindi usa la posizione 4 altrimenti se la posizione 5 è junior o lady allora usa 5 altrimenti se p 6 è...e così via.

Non penso che ciò possa essere fatto a meno che la tabella non sia ordinata in qualche modo.La maggior parte delle funzioni di ricerca di Excel richiedono elenchi ordinati.Questo potrebbe sicuramente essere fatto con una funzione VBA.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top