Excel 2007-2010. El formato condicional y VBA. (Parte I)
El formato condicional y VBA. Problemas.
Hace unos días, para crear un reporte "profesional" y sin depender directamente de VBA, decidí usar el formato condicional. Yo creo que dicho formato es muy útil, sobre todo para resaltar encuestas, beneficios de una empresa, presentación de resultados y un largo etc. El problema me surgió cuando quise obtener el color de una celda con formato condicional.
"Un formato condicional cambia el aspecto de un rango de celdas en función de una condición (o criterio)". Lo curioso es que no es lo mismo el formato que tiene una celda, el formato condicional de esa celda y el formato final de esa condición. Vamos a ver unos ejemplos.
Primer ejemplo. Color de fondo.
Voy a hacer algo muy sencillo, observa la siguiente tabla que he creado en Excel y te voy a enseñar a hacerla:
Voy a empezar con la columna B. Primero voy a colorear el fondo de las celdas B2:B5. Voy a usar los colores básicos: blanco, azul y verde que voy a introducir correctamente usando el valor RGB. Esto se hace seleccionando Color de relleno ? Más colores ? Personalizado ? Modelo de color: RGB. Las celdas y los colores son los siguientes (R:Rojo, V:Verde, A:Azul):
- Celda B2: R:255, V:255, A:255
- Celda B3: R:0, V:0, A:255
- Celda B4: R:0, V:255, A:0
- Celda B5: R:0, V:0, A:255
Ahora, en el rango de celdas (B2:B5) voy a poner un formato condicional para que si el contenido de la celda es mayor que 3, pinte el fondo de verde y el texto de blanco. Así que, selecciono dichas celdas, les pongo que sean números sin decimales y voy a Formato condicional ? Administrar reglas ? Nueva regla ? Utilice una fórmula. Y donde dice "Dar formato a los valores donde esta fórmula sea verdadera", escribo lo siguiente:
=(B2>3)
Y ahora pulso el botón de abajo de formato y pongo de relleno el color verde (R:0, V:255, A:0) y letra en blanco. Excel automáticamente reconoce esa celda relativa B2 y cuando calcula el formato, lo hace con el contenido individual de cada otra celda. Verás que esto luego es un problema con VBA. En estos momentos tiene que quedar la columna B tal cual está en la imagen. Si no has hecho algo mal.
Lo primero que se observa es que la celda B5 tiene un formato condicional y además su fondo real es azul. Para diferenciar el formato condicional he puesto la letra en blanco.
Obtener el color de fondo con VBA
Aquí viene el primer problema. ¿cómo puedes saber el color de fondo de una celda? El color de fondo real (sin condición) nos lo da rápidamente VBA. Vamos a ver la columna C. Yo voy a hacer una simple función y en cada celda de C2:C5 voy a pegar lo siguiente:
GetColor(celda)
Por ejemplo en la celda C2 pongo esto
=GetColor(B2)
Y ahora creo una simple macro, y la modifico creando una función y la dejo así de sencilla:
Public Function GetColor(ByVal celda As Range) Select Case celda.Interior.ColorIndex Case 2 GetColor = "BLANCO" Case 4 GetColor = "VERDE" Case 5 GetColor = "AZUL" Case Else GetColor = "OTRO" End Select End Function
El resultado tiene que ser igual a la columna C de la imagen.
Obtener el color de fondo condicional con VBA
Como puedes observar, la sencilla forma anterior no da el color condicional de una celda. Para esto se puede utilizar lo siguiente:
celda.FormatConditions(1).Interior.ColorIndex
Con eso obtienes el color del formato condicional pero no el real que vemos en pantalla. Entonces, ¿cómo se obtiene el color que realmente vemos? Hay que recurrir en VBA a saber si la condición del formato condicional se cumple o no se cumple.
Si la condición se cumple, el color de la celda es:
celda.FormatConditions(1).Interior.ColorIndex
Si la condición NO se cumple, el color de la celda es:
celda.Interior.ColorIndex
En VBA para saber el resultado de dicha condición se usa lo siguiente:
Application.Evaluate
Pero esto también conlleva un pequeño problema, y si observas la imagen anterior, verás que el color condicional recibido en la celda D5 es azul cuando debería ser verde, ¿por qué? Pues después de estrujarme un poquito las neuronas, observo que en VBA la fórmula evaluada (evaluate) es la siguiente:
=(B2>3)
Este es el problema, que la fórmula condicional que pusimos en el formato, en VBA solo se extrae en modo de direcciones absolutas, es decir, solo para una determinada celda. Por eso, si ves la imagen anterior, verás que la fórmula evaluada es la misma en todas. En el siguiente artículo mostraré cómo resolver esta situación, inspecciones de 4 códigos, el código VBA utilizado y mi opinión.