Pregunta

Tengo una hoja de cálculo de Excel en un formato similar al siguiente...

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

Necesito convertir esta tabla en una lista de los "Diez mejores" equipos.las reglas son

  • La puntuación de cada equipo se obtiene de la suma de cuatro miembros de ese club.
  • Estos totales deben ser de las cuatro mejores puntuaciones excepto...
    • Cada equipo debe estar formado por al menos un Junior o Lady.

Por ejemplo, en la tabla de arriba, la puntuación del equipo para el club A sería 625. no 640 como tomarías las puntuaciones de Harry(190), Bert(150), Jim(150) y Simon(130).No podría tomar la puntuación de Fred (145), ya que eso le daría solo Caballeros.

Mi pregunta es: ¿se puede hacer esto fácilmente como una serie de fórmulas de Excel o tendré que recurrir a algo más procedimental?

Idealmente, la solución debe ser automática en las selecciones de equipo, no quiero tener que crear una fórmula hecha a mano por separado para cada equipo.Tampoco tendré necesariamente una lista ordenada de los miembros de cada club.Aunque probablemente podría generar la lista mediante una hoja de cálculo adicional.

¿Fue útil?

Solución

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) dónde H2 contiene la carta del club.

Otros consejos

¿Se puede hacer fácilmente como una serie de fórmula de Excel?

Respuesta corta, SÍ.(Dependiendo de su definición de "fácilmente").

Respuesta larga...

(I pensar esto funciona)

Aquí están mis (breves) datos de prueba:


    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

Ahora, si he entendido las reglas correctamente, queremos los cuatro mejores puntajes, excepto que si el puntaje más alto de una dama o un junior no está entre los cuatro mejores, lo usamos en lugar del cuarto más alto.Lo he reformulado un poco, por razones que pueden resultar evidentes...

DE ACUERDO.¡Fórmulas de matriz al rescate!(Espero)

La puntuación más alta del equipo a debe ser

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

donde {} indica una fórmula matricial creada usando Control-Shift-Enter para ingresar la fórmula.Los cuatro primeros se crean de manera similar.Para la parte Dama/Junior, necesitamos un poco más de complejidad.Tomando a la Dama, necesitamos esto:

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

Espero que Junior pueda dejarse tranquilamente como ejercicio para el estudiante.

Ahora estoy mirando una tabla con el siguiente diseño para el 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

La puntuación del club debe ser la de los tres mejores puntajes de "cualquiera" más la mejor dama o junior. si aún no están entre los cuatro primeros.

Entonces en el segundo trimestre pongo esto:

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

MAX(O2,P2) me dice la mejor puntuación femenina o junior, que debe incluirse.Si es más alto que el cuarto puntaje más alto del equipo, entonces ya está en la lista y simplemente tomamos los cuatro primeros.De lo contrario, reemplazamos la cuarta puntuación más alta con la mejor puntuación femenina/junior.

Ahora podríamos hacerlo todo en una sola fórmula, sustituyendo las partes en la 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)))}

Pero no lo recomiendo...

Entonces, para los datos anteriores, termino con esto:


            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       

Ratas.En mi entusiasmo por (creo) hacer que la parte difícil funcione, olvidé mencionar eso

  • La lista de puntuaciones puede estar en cualquier orden.
  • Puedes obtener la clasificación del club con RANK()
  • Luego puede colocar los 10 primeros en otra tabla 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   

Las columnas A y B son nuestras puntuaciones calculadas, la columna E es el orden en el que los clubes aparecerán en la mesa final.Las otras fórmulas son las siguientes:

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

Lo que hago es tonto, pero funciona.

Simplemente cree una nueva columna y luego inserte esta fórmula. =If(a1=N,b1,0) dónde A1 es la columna de criterios, N son criterios y B1 está en la columna de la que está intentando obtener el tamaño grande.Luego simplemente hago la fórmula grande en otra columna.

A veces me pongo muy elegante y en lugar de desplegar un N, haré que diga $C$1, luego detalla los criterios en esa celda.

La respuesta perfecta sería que Microsoft agregue un largeifs (por favor lea este Microsoft)

Escribir una solución en VBA sería mi primera opción, especialmente si las reglas tienen la posibilidad de volverse más complejas.

Utilice una tabla dinámica que actuará como una consulta de base de datos sobre los datos que tiene.Gire para que los equipos bajen por las columnas y los miembros del equipo junto con su tipo de estado pasen por la tabla dinámica.No estoy seguro de 2003, pero Excel 2007 le permite ordenar para que las puntuaciones más altas aparezcan a la izquierda.Luego, su primera suma puede simplemente tomar los primeros tres puntajes de cada equipo.Sin embargo, para obtener la suma de las últimas personas, debes determinar si puedes usar la cuarta puntuación o si tienes que usar el máximo de los tipos junior o Lady.Esto podría hacerse usando una fórmula compleja y de fuerza bruta similar a esta:

si (tipo de puesto 1 es junior o dama o...2 o 3...) luego use la posición 4 en caso contrario, si la posición 5 es junior o dama, entonces use 5 en caso contrario si p 6 es...etcétera.

No creo que esto se pueda hacer a menos que la tabla esté ordenada de alguna manera.La mayoría de las funciones de búsqueda de Excel requieren listas ordenadas.Ciertamente, esto podría hacerse con una función de VBA.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top