Formato condicional

Hola Fejoal, por tus respuestas me da que sabrás encontrar una solución para mi problema. Vamos a ver, necesito que el fondo de una celda se torne de un color diferente dependiendo del valor de dicha celda, en el menú formato tenemos una opción que soluciona este problema, pero tiene un inconveniente, solo son posibles tres condiciones, y yo necesito al menos 6. Por favor, y perdona si te doy la impresión de ir de cómodo, pero es que aún no me manejo muy bien con código Vb, así que, a ser posible me lo pasas lo más organizado y lineal que puedas posible, me refiero a que no des cosas por sabidas y te saltes algún paso, OK. Te recompensaré, no soy desagradecido, por lo pronto vayan un millón de gracias por adelantado.

1 respuesta

Respuesta
1
Intuiste bien: Necesitarás usar Visual Basic for Applications (VBA)
La macro que sigue cambia el color de la celda de acuerdo al valor ingresado en ella.
Para que funcione, activa el editor de Visual Basic (presiona Alt+F11) y busca
la hoja donde quieres que esto ocurra (donde la celda cambiará de valor). Da doble click sobre ella. (Otra forma de llegar a este punto es hacer click derecho sobre la solapa de esta hoja y elegir la opción "Ver Código)
Copia el código siguiente y pégalo en el panel desplegado a la derecha de su Editor de Visual Basic:
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
'Indica las celdas o rangos donde debe aplicarse el formato multiple
Celda = "C8"
'-----------
If Target.Address(False, False) = Celda Then 'Vericando que la celda que cambió es la que quieres colorear
Select Case Target.Value
Case 1 'cambia aquí el valor de la celda para el primer color
Target.Interior.ColorIndex = 3
Case 2
Target.Interior.ColorIndex = 4
Case 3
Target.Interior.ColorIndex = 5
Case 4
Target.Interior.ColorIndex = 6
Case 5
Target.Interior.ColorIndex = 7
Case 6
Target.Interior.ColorIndex = 8
Case Else
Target.Interior.ColorIndex = xlNone
End Select
End If
End Sub
'---- Fin de tu macro. Copia hasta arriba de esta línea
Bien. Notarás que tienes la posibilidad de indicarle, al comienzo del código, qué celda debe considerar.
Un poco más abajo se abre el set de condiciones a modos de casos.
Así, donde dice:
Case 1 significa que tomará el color codificaco en la linea siguiente, cuando la celda en cuestión valga 1.
De la misma manera, si la celda tiene un 2 tomará el color 4 que equivale a amarillo en la tabla de colores de la propiedad ColorIndex.
Nota, si quieres ver tal tabla bastará que selecciones la instrucción ColorIndex y presiones F1. Esto te llevará a la ayuda de VBA para esa propiedad que incluye la citada tabla.
Si no coincide con ninguno de los casos detallados, entrará por la opción Case Else asignándole ningún color a esa celda.
Tu tarea será, modificar los valores que debe tomar la celda y los códigos de color que quieres que se apliquen en cada "case".
Espero haber sido claro, pero no me molesta que me preguntes de nuevo si te quedo alguna duda.
Recuerda que este procedimiento es válido sólo para cuando se ingresan datos en la celda indicada al rincipio dl código.
Un abrazo!
Fernando
Entendido el concepto de aquella macro, podemos seguir con una complicación.
¿Que pasa si quieres que esos criterios se apliquen a más de una celda y/o que sus valores dependen de una fórmula y no del ingreso directo del dato como en el caso anterior.
Deberás reemplazar toda aquella macro por esta variante:
Private Sub Worksheet_Calculate()
'Indica las celdas o rangos donde debe aplicarse el formato multiple
Celda1 = "A2"
Celda2 = "C7"
Celda3 = "D9"
'...
'---------------- si es más de una agragala en
Dim UnaC As Range
Set RangoCol = Union(Range(Celda1), Range(Celda2), Range(Celda3))
For Each UnaC In RangoCol
Select Case UnaC.Value
Case 1
UnaC.Interior.ColorIndex = 3
Case 2
UnaC.Interior.ColorIndex = 4
Case 3
UnaC.Interior.ColorIndex = 5
Case 4
UnaC.Interior.ColorIndex = 6
Case 5
UnaC.Interior.ColorIndex = 7
Case 6
UnaC.Interior.ColorIndex = 8
Case Else
UnaC.Interior.ColorIndex = xlNone
End Select
Next UnaC
End Sub
En este caso cambiamos el evento que dispara la macro al momento del cálculo.
Notarás que hay tres celdas que deberían cambiar -de acuerdo a su valor- según el set de condiciones que definiste.
Si la cantidad de celdas fuese mayor a las allí detalladas, agrega variables numeradas como las que ya ves allí y recuerda agregarlas también dentro de
Union(Range(Celda1), Range(Celda2), Range(Celda3))
Así para una celda más, colocarás una variable llamada:
Celda4 = "Z33"
Y también la agregarás dentro de Union() quedando algo así como esto:
Union(Range(Celda1), Range(Celda2), Range(Celda3), Range(Celda4))
Por último te aclaro que el lugar de una sola celda también es válido colocar la dirección de un rango.
Por ejemplo
Celda4 = "G8:G28"
Bien, espero haber cubierto tu caso particular con estas dos soluciones posibles.
Buen fin de semana!
Fernando
En realidad no uso ADSL ni otra droga parecida... Es pura inteligencia natural (jaa! :))
Como dije en la segunda parte era probable que lo necesitaras para más de una celda. Esa segunda versión contemplaba la posibilidad de que ese rango fuera discontiguo.
Pero veo que encontraste una forma de "complicar" la respuesta. La verdad que es que necesitarás una simplificación en aquella 2ª macro para que opere como quieres. Usa esta versión, simplificada:
Private Sub Worksheet_Calculate()
'Indica las celdas o rangos donde debe aplicarse el formato multiple
Celda1 = "C1:C8"
'Celda2 = "C7"
'Celda3 = "D9"
'...
'---------------- si es más de una agregala en este listado de variables y en la función unión.
Dim UnaC As Range
Set RangoCol = Range(Celda1)
For Each UnaC In RangoCol
Select Case UnaC.Value
Case 1
UnaC.Interior.ColorIndex = 3
Case 2
UnaC.Interior.ColorIndex = 4
Case 3
UnaC.Interior.ColorIndex = 5
Case 4
UnaC.Interior.ColorIndex = 6
Case 5
UnaC.Interior.ColorIndex = 7
Case 6
UnaC.Interior.ColorIndex = 8
Case Else
UnaC.Interior.ColorIndex = xlNone
End Select
Next UnaC
End Sub
Hasta donde la probé funciona.
De hecho la otra hubiera funcionado también si a las variables Celda2 y Celda3 les hubieras asignado celdas que nunca tendrían valor (ej BD88, AA1)
Pero, bueno, ésta versión opera estrictamente en el rango C1:C8.
Espero haberte satisfecho.
Otro abrazo!
Fernando
! Tienes ADSL en tus neuronas¡, lo digo por tu rapidísima respuesta. Por tu completísima respuesta, me quito el sombrero, además por tu esfuerzo de intuir posibles dudas, y de verdad, has hecho que se me haga cuesta arriba no darme por satisfecho, pero concretamente el formato condicional lo necesito para aplicarlo a un rango de celdas, siento ser tan torpe, después de las molestias que te has tomado, te merecías que hubiese sido capaz de solventar esta dudo yo solo, lo siento. En mi intento de hacerlo solo he modificado tu macro en
Celda="C8"
poniendo
Celda="C1:C8"
Pero no funciona, de verdad que siento no ser capaz de solucionar el problema por mi cuenta, cuando ya lo que queda es insignificante, tampoco quisiera tener la pregunta abierta mientras practico puesto que podría pasar demasiado tiempo, he leído entre tus respuestas que se te agota el espacio y no puedes contestar a otros. He practicado durante el fin de semana, pero no lo he conseguido.La duda concreta es ¿Qué debo modificar de tu macro para que actúe sobre un rango de celdas?. Para otras dudas ya he aprendido tu método y concretaré lo más posible la duda.
No me lo explico, pero no funciona, la primera macro va de maravilla, esto es cuando se aplica a una sola celda. Pero en la segunda incluida la que me has vuelto a mandar, no funciona, y para evitar errores al transcribir he copiado todo el código y lo he pegado en el editor de VB de la hoja de cálculo, pero nada de nada. Bueno, antes no te informé que utilizo Excel 2000, no sé si esa circunstancia pudiera tener algo que ver. Y por otro lado te explico que el rango que necesito, para el caso concreto, incluye varias columnas, vamos que el rango sería A1:Z365. ! AH¡ Y lo de ADSL no es ninguna droga ni nada por estilo, son las siglas por las que se llama a la línea de alta velocidad para conexión con Internet, por lo menos se llama así aquí en España no sé si en Argentina se conoce dicha línea telefónica por otras siglas. Espero no haberte molestado con el comentario, creo entender por tu respuesta que ha sido así, no obstante ahí va mi aclaración por si acaso.
Lo del ADSL fue un juego de palabras, más exactamente de letras, pues cuenta con las mismas que LSD que sí es una droga. Pero un chiste explicado deja de ser un chiste.
Sé que ADSL (Asymmetric Digital Suscriber Line) es una tecnología de transmisión veloz por vía telefónica y, desde luego, no me molestó en absoluto tu comentario (todo lo contrario, lo tomé como un alago).
Bueno, respecto a la macro.
Efectivamente, la única forma de que funcione es si está copiada en el panel de macros de la hoja donde están los datos.
Como dije: click derecho sobre la solapa de esta hoja y elegir la opción "Ver Código" y pega el código en le panel ubicado a la derecha de la pantalla de VBE
Private Sub Worksheet_Calculate()
'Indica las celdas o rangos donde debe aplicarse el formato multiple
Celda1 = "A1:Z365"
Dim UnaC As Range
Set RangoCol = Range(Celda1)
For Each UnaC In RangoCol
Select Case UnaC.Value
Case 1
UnaC.Interior.ColorIndex = 3
Case 2
UnaC.Interior.ColorIndex = 4
Case 3
UnaC.Interior.ColorIndex = 5
Case 4
UnaC.Interior.ColorIndex = 6
Case 5
UnaC.Interior.ColorIndex = 7
Case 6
UnaC.Interior.ColorIndex = 8
Case Else
UnaC.Interior.ColorIndex = xlNone
End Select
Next UnaC
End Sub
COmo esta segunda versión recorre todas y cada una de las celdas indicadas en la variable Celda1, permite que sea en más de una columna.
---
¿Qué puede fallar?
a.- Que tu versión de MS Excel tenga una configuración de seguridad ALTA que impide que las macros se ejecuten.
Prueba creando una macro cualquiera y ejecutándola.
Pero esto es poco probable porque mencionas que la primera funcionó OK...
b.- Que, por alguna razón, VBA haya dejado de considerar los eventos.
Recuerda que esta macro se dispara cuando la hoja se recalcula.
Prueba cambiando -temporalmente- el nombre de la macro de
Private Sub Worksheet_Calculate()
por este otro:
Sub Colorea()
Luego, ejecuta Colorea para ver si funciona correctamente.
Te sugiero que pruebes la macro como está, colocando aleatoriamente en tal rango valores que van de 1 a 6
Si funcionara, es que hubo algún conflicto con los eventos.
Ejecuta la siguiente macro una vez para que restituya ese comportamiento:
Sub Eventos()
Application.EnableEvents = True
End sub
Esta apunta a restutuir la consideración de eventos.
Luego, vuelve a nombrar tu macro como:
Private Sub Worksheet_Calculate()
Y debería funcionar.
Pruébalo y dime si funciona (aquí lo hizo perfectamente)
Ten en cuenta que debes forzar un cálculo para ver el resultado, intrduciendo una fórmula en una celda cualquiera, por ejemplo. Además, al ser muchas celdas esto implicará alguna demora.
En tal caso, personalmente preferiría desvincularla de los eventos y usarla como una macro común para poder dispararla cuando yo lo decida. O, eventualmente, asociarla a un evento menos frecuente, por ejemplo, antes de imprimir
Un abrazo!
Fernando
Perdona, perdona, perdona, el error es mío. No leí con la debida atención tu respuesta, ! Necesitaba hacer un cálculo¡, así funciona a la perfección. Es que para mi problema concreto, y no quiero fastidiarte tus respuestas, lo que yo introduzco en las celdas son caracteres alfabéticos (M, T, N, V, B,) y claro con ellos no es posible realizar cálculos. No obstante he estado practicando con la macro que hay que ejecutar manualmente y puedo darme por satisfecho, aunque en honor a la verdad, y tampoco es que ejecutar la macro sea agotador, pero como que se le queda a uno un hueco por llenar ¿No crees?. En fin como tú lo consideres, si no resulta muy farragoso y no te consume mucho tiempo, si te parece envías la modificación, y si no lo dejamos, te valoro y cerramos la pregunta. ! Ah¡, una vez más llevas razón, un chiste explicado deja de serlo, muy cierto. Saludos desde Cádiz (España).
Bien, Saturno
Entiendo el punto, ciertamente el evento Calculate no es un evento más apropiado pero sí es el que más se le acerca.
Atar la última macro al evento Change, provoca grandes demoras pues obligas a la macro a revisar 9094 celdas (365 x 26) cuando sólo cambiaste una sola de ellas.
Teniendo un poco más claro tu situación te recomendaría que tengas dos macros basadas en distintos eventos.
Una que revise todas esas celdas asignando el color que le hayas indicado y que se dispare esporádicamente, por ejemplo asociándola al evento de activar una hoja (Worksheet_Activate) o al abrir el archivo (Workbook_Open) o antes de imprimir (Workbook_BeforePrint)
o, incluso, asociado a un botón y que se dispare solo cuando lo presiones.
El de activación de hoja se copia, como te dije en la hoja donde cargas los datos, mientras que la macro asociada a cualquiera de los otros dos eventos, va en la hoja "ThisWorkBook".
Tal macro sería:
Private Sub Worksheet_Activate()
'Indica las celdas o rangos donde debe aplicarse el formato multiple
Celda1 = "A1:Z365"
Dim UnaC As Range
Set RangoCol = Range(Celda1)
For Each UnaC In RangoCol
Select Case UnaC.Value
Case "M"
UnaC.Interior.ColorIndex = 3
Case "T"
UnaC.Interior.ColorIndex = 4
Case "N"
UnaC.Interior.ColorIndex = 5
Case "B"
UnaC.Interior.ColorIndex = 6
Case "V"
UnaC.Interior.ColorIndex = 7
Case Else
UnaC.Interior.ColorIndex = xlNone
End Select
Next UnaC
End Sub
---
Y, por otro lado, tendrías otra macro local que evalúa una sola celda si es que esta cambió y si se encuentra dentro del rango de celdas especificado.
En la hoja donde esto ocurra tendrías que tener un código como este:
Private Sub Worksheet_Change(ByVal Target As Excel.Range)
'Indica las celdas o rangos donde debe aplicarse el formato multiple
Celda1 = "A1:Z365"
Set RangoCol = Range(Celda1)
Set EnRango = Application.Intersect(RangoCol, Target)
If Not EnRango Is Nothing Then
Select Case Target.Value
Case "M"
Target.Interior.ColorIndex = 3
Case "T"
Target.Interior.ColorIndex = 4
Case "N"
Target.Interior.ColorIndex = 5
Case "B"
Target.Interior.ColorIndex = 6
Case "V"
Target.Interior.ColorIndex = 7
Case Else
Target.Interior.ColorIndex = xlNone
End Select
End If
Set RangoCol = Nothing
Set EnRango = Nothing
End Sub
Esta macro puede estar junto a la de Worksheet_activate.
Recuerda que puedes cambiar los códigos de los colores de fondo, ayudándote con la tabla de colores (seleccionas la instrucción ColorIndex y presiones F1. Esto te llevará a la ayuda de VBA para esa propiedad que incluye la citada tabla)
Sí ten presente que deberás colocar el mismo código en ambas macro para cada caso.
Esto, además de lograr el resultado esperado, acelerará notablemente los tiempos de uso de tu archivo, sin necesidad de que tengas que usar la macro que hay que ejecutar manualmente.
Espero haberme hecho entender y que puedas llenar ese hueco.
Un abrazo!
Fernando
! Bingo¡, es que alucino en colores, nunca mejor dicho. El hueco ha quedado más que lleno, ha rebosado. Fantástico. Lástima que esta página solo me permita puntuar hasta cinco, por lo que a mí respecta te mereces un 10. Hasta la próxima duda.
Otro abrazo!
Antonio.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas