Pergunta

Eu tenho uma planilha Excel em um formato semelhante ao seguinte ...

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

Preciso converter esta tabela em uma lista das equipes "Top Ten".As regras são

  • A pontuação de cada equipe é obtida da soma de quatro membros daquele clube.
  • Esses totais devem ser das quatro melhores pontuações, exceto...
    • Cada equipe deve ser composta por pelo menos um Junior ou Lady

Por exemplo, na tabela acima, a pontuação da equipe para o clube A seria 625 não 640 como você faria com as pontuações de Harry (190), Bert (150), Jim (150) e Simon (130).Você não poderia pegar a pontuação de Fred (145), pois isso lhe daria apenas cavalheiros.

Minha dúvida é: isso pode ser feito facilmente como uma série de fórmulas do Excel ou precisarei recorrer a algo mais processual?

O ideal é que a solução seja automática nas seleções das equipes, não quero ter que criar fórmulas separadas e elaboradas à mão para cada equipe.Também não terei necessariamente uma lista ordenada dos membros de cada clube.Embora eu provavelmente pudesse gerar a lista por meio de uma planilha de cálculo extra.

Foi útil?

Solução

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

Usar como =TopTen(H2,$B$2:$E$30) onde H2 contém a carta do clube.

Outras dicas

isso pode ser feito facilmente como uma série de fórmula do Excel

Resposta curta, SIM.(Dependendo da sua definição de "facilmente").

Resposta longa...

(EU pensar isso funciona)

Aqui estão meus (breves) dados de teste:


    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

Agora, se entendi as regras corretamente, queremos as quatro melhores pontuações, exceto que se a pontuação mais alta de uma senhora ou de um júnior não estiver entre as quatro melhores, usaremos essa pontuação em vez da quarta maior.Eu reformulei um pouco, por razões que podem se tornar aparentes...

OK.Matriz de fórmulas para o resgate!(Espero)

A pontuação mais alta da equipe a deve ser

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

onde {} indica uma fórmula de matriz criada usando Control-Shift-Enter para inserir a fórmula.Os quatro primeiros são criados de forma semelhante.Para a parte Lady/Junior, precisamos de um pouco mais de complexidade.Levando a Senhora, precisamos disso:

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

Junior pode ser deixado com segurança como um exercício para o aluno, espero.

Agora estou olhando para uma mesa com o seguinte layout para o clube "a"


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

A pontuação do clube deve ser as três primeiras pontuações de "qualquer um" mais a melhor dama ou júnior se eles ainda não estiverem entre os quatro primeiros.

Então, no segundo trimestre, estou colocando isto:

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

MAX(O2,P2) me diz a pontuação da melhor senhora ou júnior, que deve ser incluída.Se for superior à quarta maior pontuação da equipe, então já está na lista e ficamos apenas com os quatro primeiros.Caso contrário, substituímos a quarta pontuação mais alta pela melhor senhora/júnior.

Agora poderíamos fazer tudo em uma fórmula, substituindo as partes na fórmula final:

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

Mas não recomendo...

Então, para os dados acima, acabo com isto:


            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       

Ratos.Na minha empolgação por (eu acho) conseguir fazer a parte difícil funcionar, esqueci de mencionar isso

  • A lista de pontuações pode estar em qualquer ordem
  • Você pode obter as classificações do clube com RANK()
  • Você pode então colocar os 10 primeiros em outra tabela usando 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   

As colunas A e B são as nossas pontuações calculadas, a coluna E é a ordem em que os clubes serão apresentados na mesa final.As outras fórmulas são as seguintes:

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

O que eu faço é ridículo, mas funciona.

Basta criar uma nova coluna e inserir esta fórmula =If(a1=N,b1,0) onde A1 é a coluna de critérios, N são critérios e B1 está na coluna da qual você está tentando obter o tamanho grande.Então eu apenas faço a fórmula grande em outra coluna.

Às vezes fico todo chique e em vez de lançar um N, vou fazer dizer $C$1, e, em seguida, especifique os critérios nessa célula.

A resposta perfeita seria fazer com que a Microsoft adicionasse um largeifs (por favor leia isto Microsoft)

Escrever uma solução em VBA seria minha primeira escolha, principalmente se as regras tiverem a possibilidade de se tornarem mais complexas.

Use uma tabela dinâmica que atuará como uma consulta ao banco de dados sobre os dados que você possui.Gire para que as equipes desçam nas colunas e os membros da equipe junto com seu tipo de status percorram a tabela dinâmica.Não tenho certeza para 2003, mas o Excel 2007 permite classificar para que as pontuações mais altas apareçam à esquerda.Então, sua primeira soma pode simplesmente levar as três primeiras pontuações de cada equipe.No entanto, para obter a soma das últimas pessoas, você deve determinar se pode usar a 4ª pontuação ou se deve usar o máximo dos tipos Junior ou Lady.Isso poderia ser feito usando uma fórmula complexa e de força bruta mais ou menos assim:

if (tipo de posição 1 é júnior ou senhora ou ...2 ou 3...) então use a posição 4 senão se a posição 5 for júnior ou senhora então use 5 senão se p 6 for ...e assim por diante.

Não acho que isso possa ser feito a menos que a tabela esteja ordenada de alguma forma.A maioria das funções de pesquisa do Excel requer listas ordenadas.Isso certamente poderia ser feito com uma função VBA.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top