VBA Modificar formato de un Rango cuando cambia una celda

He hecho una macro para detectar un cambio de celda en un rango de una hoja y cambiar automaticamente el formato de la línea donde se produjo el cambio.

Si se selecciona "X" de una lista despegable en el rango "C15:C2000" se cambia el formato de toda la línea a itálica y font gris. Hasta aquí parece funcionar aunque me envía la celda seleccionada varias columnas a la izquierda (¿?) Pero es un bug menor. El problema es que deseo que al modificar dicho valor de la celda de "X" a su valor original de "P" o "U" la línea vuelva a su formato original (font xlAutomatic.)

¿Alguna sugerencia?

Gracias

---------

Private Sub Worksheet_Change(ByVal Target As Range)

Dim BuscarRango As String
BuscarRango = "C15:C2000"
Application.EnableEvents = False
On Error GoTo Error
If Not Application.Intersect(Target, Range(BuscarRango)) Is Nothing Then
Encontrarvalores
End If
Error:
Application.EnableEvents = True

End Sub

----------------
Public Sub Encontrarvalores()

Dim resultadoX, resultadoP, resultadoU As Range
Dim primerabusqueda As String
Dim Rango As String

Rango = "C15:C2000"

resultadoX = Range(Rango).Find("X")
If resultadoX Is Nothing Then
Else
primerabusqueda = resultadoX.Address
Do
ActiveCell.Offset(0, -2).Range("A1:R1").Select
With Selection.Font
.ThemeColor = xlThemeColorDark1
.TintAndShade = -0.349986266670736
End With
Selection.Font.Italic = True
ActiveCell.Offset(0, 0).Select
ActiveCell.Offset(0, 13).Range("A1").Value = "Deleted by MMI"
'ActiveCell.Value = "Deleted by MMI"
resultadoX = Range(Rango).FindNext(resultadoX)
Loop While Not resultadoX Is Nothing And resultadoX.Address <> primerabusqueda
End If
'Set resultadoP = Range(Rango).Find("P")
'If resultadoP Is Nothing Then
'Else
'primerabusqueda = resultadoP.Address
' Do
' 'resultadoP.Select
' ActiveCell.Offset(0, -2).Range("A1:R1").Select
' With Selection.Font
' .ColorIndex = xlAutomatic
' .TintAndShade = -0
' End With
'Selection.Font.Italic = False
'ActiveCell.Offset(0, 13).Range("A1").Select
'ActiveCell.Value = "" 'Borrar la etiqueta "Deleted by MMI"
'resultadoP = Range(Rango).FindNext(resultadoP)
'Loop While Not resultadoP Is Nothing And resultado.Address <> primerabusqueda
'End If

'IDEM para resultadoU

End Sub

1 Respuesta

Respuesta
1

No hagas una macro para cambiar el formato de la fila... te estas complicando demasiado la vida... Por un formato condicional y listo... que tu macro solo se dedique a escribir el Deleted by...

Por cierto, el colocar ese valor en la celda A, ¿cambia alguna fórmula para que no considere ese dato?

Porque en realidad, si estas usando alguna fórmula como SUMAR. SI podrías haber aprovechado el valor de la columna C para no considerar ese valor...

Antes de hablar del formato condicional, tu macro tiene algunos problemas... (por si quisieras mantenerla) el Deleted, lo escribe en un Offset(0,-2) pero con respecto al activecell... pero el activecell despues de escribir la X es una linea abajo de la X...

o cambias      ActiveCell.Offset(0, -2). Range("A1:R1").Select

por                  ActiveCell.Offset(-1, -2).Range("A1:R1").Select    o  po

por                  Target(0, -2).Range("A1:R1").Select   

además el

Dim resultadX......           tienes que poner as Range para cada uno... no se puede hacer definicion conjunta en VBA

a              resultadoX = Range(Rango).Find("X")              le falta Set.... pues resultadoX es un objeto

Con eso ya debería funcionar

Ahora si, vamos al formato condicional

Selecciona el rango A15:R2000 (me parece que ese es el rango que quieres formatear)

En la pestaña Inicio, Formato Condicional, Nueva Regla, Utilice una fórmula que determine...

Debajo de Dar formato a los valores... escribe esta fórmula

=$C15="X"

Haz click en el boton Formato y programa lo italico, color gris, etc...

Con eso, el color se aplicará apenas pongas X y desaparecerá apenas quites la X...

Con esto tu macro original podría simplificarse mucho pues podrías borrar todo lo que tiene que ver con formato

Suerte!

Jaime

¡Gracias Jaime!

El formato condicional resultó una maravilla, no sabía que se podía condicionar formato a un rango diferente de la celda que activa la condición.!!! Mucho mas limpio el procediento.

Me puedes explicar el significado de  =$C15="X"?   (la formula parece aludir a la celda C15 pero se aplica a toda la columna C de mi rango seleccionado, porqué?)

así que el tema del formato condicional quedó resuelto fácil y muy exitosamente ya que puedo deshacer el formato simplemente cambiando la letra...


En cambio poner el texto "Deleted by MMI" en la columna N si se pone una X en la columna C de la misma línea...

No logro resolverlo y no sé porque... ayer funcionaba aunque de manera extraña y hoy modifiqué según tus consejos pero ya no aparece ninguna etiqueta. ¿es correcto usar  el evento Change o será mejor usar el evento Selection Change? 

Piensa que esta hoja es un template que se multiplicará con datos diferentes y el funcionamiento tiene que ser igualmente válido en las hojas copiadas.

El objetivo que busco es que si hay una "X" o "x"  en el rango "C15:C2000" se inserte el texto " Deleted by ..." en la columna N, en la misma línea.

Si NO hay "X" o "x"  o se borra una "X" existente, entonces la celda "N" quedará vacía y puede recibir nuevamente fórmulas provenientes de otra macro. Espero tu consejo!

Gracias y saludos

Que bueno que te ayudó!

El evento Selection_Change ocurre cada vez que seleccionas una celda, no es eso lo que necesitas

El Change ocurre cada vez que cambias una celda, como escribir o borrar algo, esta bien que estes usando este.

Yo vi que tu macro insertaba el "Dele..." en la columna A de la fila siguiente y pensé que eso querías...

Para hacer lo que pides debes poner...

Cells( Target.Row, "N") = "Deleted by ...................."

Asi, la colocará en la misma fila de la celda donde escribas "X" y en la columna "N"

Hay dos tipos de formatos condicionales, los típicos (pero bastante vistosos) en los cuales el formato (color, ícono, etc) es aplicado a la celda e función del valor que figure en la celda, y aquellos en los cuales se evalúa una fórmula a lo largo del rango...

=$C15="X"         te explico como funciona la fórmula en ese caso

Te dije que seleccionaras el rango A15:R2000 pues en ese rango que seleccionas es que se programará el formato... Ahora la fórmula que tu escribes, la escribes pensando en como resultará evaluada en la celda superior izquierda del rango seleccionada, en este caso A15.

Excel evalúa la fórmula que tu indicas, y se el resultado de la fórmula es verdadero, aplica el formato... pero..

... Como esa fórmula la has "pensado" y escrito para la primera celda, Excel internamente debe copiar la fórmula a cada celda del rango seleccionado y evaluar nuevamente en cuales cumple con tener un valor verdadero... las fórmulas se "copian" internamente utilizando las mismas reglas que se tienen cuando escribes fórmulas en Excel... la columna y/o fila que tenga $ no cambiará el resto si...

Entonces en la fila A15 Excel revisa la celda $C15, y asi lo hace en toda esa fila... (al copiar una fórmula hacia la derecha las letras cambian, pero en este caso al tener $ no lo hace)

Al "copiar" la fórmula para ser evaluada en la fila 16, la celda indicada en la fórmula $C15, cambia a $C16 (como NO has fijado los números, estos cambian al copiar la fórmula hacia abajo), y así lo sigue haciendo en cada fila.

Prueba si con esta macro basta...

Private Sub Worksheet_Change(ByVal Target As Range)

Dim BuscarRango As String
BuscarRango = "C15:C2000"
Application.EnableEvents = False
On Error GoTo Error
If Not Application.Intersect(Target, Range(BuscarRango)) Is Nothing Then
    Cells(Target.Row, "N").Resize(Target.Rows.Count,1) ="Deleted by MMI"

Else

    Cells(Target.Row, "N").Resize(Target.Rows.Count,1) = ""
End If
Error:
Application.EnableEvents = True

End Sub

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas