jueves, 26 de noviembre de 2015

VBA: Contar o Sumar valores según el color de Fondo o Fuente de una celda.

Hoy contaré un clásico de las cuestiones planteadas: Contar o Sumar los valores de una celda según el color de fondo o de la fuente.
Estimado tengo una duda. Si tuviera un rango por ejemplo de "$A$1:$A$10", en donde: 
A1(color negro), A2(color azul), A3, (color amarillo), A4 (color blanco), A5 (color blanco), A6 (color amarillo), A7 (color blanco), A8 (color blanco), A9 (color azul), A10 (color amarillo).
Como haría para sumar las celdas del mismo color mediante una macro, es decir: La A1 = SUMA(A2,A9) , A3 = SUMA(A4,A5) , A6 = SUMA(A7,A8) , A9 = SUMA(A10).

Hay muchos ejemplos al respecto en casi todos los foros especializados, pero en el caso de hoy, le daremos un poco más de valor añadido, incorporando variaciones para controlar el color de la fuente o del Fondo de la celda, así como el tipo de operación a realizar (Sumar o Contar).

Insertamos nuestro procedimiento Function en un módulo estándar de nuestro proyecto de VBA desde el editor de VB:

Function FxColor(rngRange As Range, CeldaComparacion As Range, Operacion As String, Optional Tipo As String) As Double
Dim color As Long, Resultado As Double, CeldaColor As Double
'rngRange: será el rango de estudio
'CeldaComparacion: la celda donde compararemos el color
'Operación: puede ser SUMA o CONTAR
'Tipo: Fuente o Fondo

For Each celda In rngRange
    'Definimos la casuística a comparar según el argumento Tipo
    If UCase(Tipo) = "FONDO" Then
        'si elegimos en Tipo Fondo, tomamos para comparar el color del Fondo
        color = CeldaComparacion.Interior.ColorIndex
        CeldaColor = celda.Interior.ColorIndex
    ElseIf UCase(Tipo) = "FUENTE" Then
        'si elegimos en Tipo Fuente, tomamos para comparar el color de la Fuente
        color = CeldaComparacion.Font.ColorIndex
        CeldaColor = celda.Font.ColorIndex
    Else
        'en cualquier otro caso tomamos para comparar el color del Fondo
        color = CeldaComparacion.Interior.ColorIndex
        CeldaColor = celda.Interior.ColorIndex
    End If
    
    'Evaluamos si el Argumento Tipo es SUMA
    If UCase(Operacion) = "SUMA" Then
        If CeldaColor = color Then
            'acumulamos valores sumados cuando coincida con color
            Resultado = WorksheetFunction.SUM(celda.Value, Resultado)
        End If
    'Evaluamos si el Argumento Tipo es CONTAR
    ElseIf UCase(Operacion) = "CONTAR" Then
        If CeldaColor = color Then
            Resultado = 1 + Resultado
        End If
    'Evaluamos si el Argumento Operacion es cualquier otra cosa distinto de SUMA o CONTAR
    'devolvemos valor como SUMA... lo dejamos abierto y preparado para otras opciones ;-)
    Else
        If CeldaComparada = color Then
            'acumulamos valores sumados cuando coincida con color
            Resultado = WorksheetFunction.SUM(celda.Value, Resultado)
        End If
    End If
Next celda
'devolvemos el valor a la función
FxColor = Resultado
End Function



Lo que hemos construido es una UDF-función personalizada con VBA que consta de cuatro argumentos:
1- rngRange: será el rango de estudio
2- CeldaComparacion: la celda donde compararemos el color
3- Operación: puede ser SUMA o CONTAR
4- Tipo: Fuente o Fondo
El cruce del tercer y cuarto argumento nos dará un flexibilidad adicional...


En la imagen vemos el resultado de aplicar esta función sobre diferentes rangos...

1 comentario: