jueves, 24 de noviembre de 2016

VBA: Detectar si una Celda ha cambiado de valor

Una lectoar preguntaba por una manera de detectar si una celda ha cambiado de valor:
[...] me gustaría guardar el valor actual de la celda para luego compararlo con la misma celda, y resaltar si el valor cambió, son valores numéricos y me gustaría identificar si alguno cambió [...]

La idea según explica nuestra lectora es detectar cuándo se ha modificado o cambiado de valor una celda dentro de un rango definido (en nuestro ejemplo A1:B10).

Para ello emplearemos el evento de hoja Worksheet_Change que hará posible verificar la variación.
Por otro lado haremos uso del tipo de variable Static, que permite fijar el valor antes de los cambios.


El procedimiento es en sí simple (al menos en la idea).
Si guardo en memoria los valores antes del cambio, y tras un posible cambio compruebo celda a celda si el nuevo valor comparado con el anterior, sabremos si efectivamente se ha producido o no dicho cambio.


Si tenemos esta situación inicial en nuestro rango A1:B10:

VBA: Detectar si una Celda ha cambiado de valor



En la ventana de código de nuestra hoja de trabajo incluimos el siguiente evento:

'Al definir las variables antes del procedimiento,
'trabajamos con ellas como si fueran 'estáticas' (Static)
'i.e., mantienen el valor en memoria para comprobar si se ha producido un cambio...
Dim inicio As Long
Dim ValorAnterior() As Variant

Private Sub Worksheet_Change(ByVal Target As Range)
Dim fila As Long, col As Long
Dim contador As Long
'definimo el rango sobre el que aplicar el control
Dim RangoTrabajo As Range
Set RangoTrabajo = Range("A1:B10")

If inicio = 0 Then
    ValorAnterior = RangoTrabajo
    inicio = 1
    Exit Sub
End If

'si no trabajamos sobre el rango descrito salimos del procedimiento
If Intersect(Target, RangoTrabajo) Is Nothing Then Exit Sub

'iniciamos contador
contador = 1
'recorremos el rango de trabajo
'comprobando si los valores anteriores difieren de los actuales
'después del cambio
'recorremos las filas del rango A1:B10
For fila = LBound(ValorAnterior, 1) To UBound(ValorAnterior, 1)
    'recorremos las columnas del rango A1:B10
    For col = LBound(ValorAnterior, 2) To UBound(ValorAnterior, 2)
        valor1 = RangoTrabajo(contador)         'acual valor de la celda(después cambio)
        valor2 = ValorAnterior(fila, col)       'anterior valor de la celda (antes cambio)
        'si difieren entonces lanzamos mensaje
        If valor1 <> valor2 Then
            MsgBox "La Celda " & RangoTrabajo(contador).Address & " ha cambiado del valor " & valor2 & " al nuevo valor " & valor1
        End If
        contador = contador + 1
    Next col
Next fila

'cargamos la matriz con un nuevo valor
ValorAnterior = RangoTrabajo
End Sub



Si tras insertar nuestro código y realizar algún cambio comprobamos el efecto.
Por ejemplo cambiamos la celda B3, de un valor 100 a introducir el valor 1313. El evento Worksheet_Change actuará y lanzará el siguiente mensaje:

VBA: Detectar si una Celda ha cambiado de valor



Cada vez que entramos en el rango A1:B10 se produce una carga de datos en memoria, para poder así comparar con la siguiente vez que accedamos a dicho rango...

No hay comentarios:

Publicar un comentario en la entrada