OK, tenemos varias cosas para cubrir.
Bueno antes de "la primera" -- ¡bienvenido a MrExcel.com!
La primera es la tema de bucles infinitos. Si estamos en el procesador de eventos de cambio (Change Event Handler) y cambiamos una celda vamos a generar un segundo evento
cambio. Entonces cuando uno está dentro del procesador de cambios y va a cambiar una celda, hay que apagar eventos...
Code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
If Not Intersect(Target, Range("A5:A100")) Is Nothing Then
Application.EnableEvents = False '// para evitar un bucle infinito
With Target(1, 4)
.Value = Time
.EntireColumn.AutoFit
End With
With Target(1, 5)
.Value = Date
.EntireColumn.AutoFit
End With
Application.EnableEvents = True
End If
End Sub
En este caso específico, no generamos un bucle infinito debido al IF NOT INTERSECT(...) que nos tira por fuera la primera vez que hacemos segunda entrada a
_change() porque TARGET está en columna D y nos tira por fuera la segunda vez que hacemos segundo entrada porque TARGET está en columna E. Pero siempre es buen costumbre apagar eventos cuando cambiando celda dentro de una rutina
_change().
OK. Segunda cosa:
Use un rango nombrado para la prueba. O sea seleccione A5:A100 y déle un nombre como
miRangitoFavorito. Nombrando el rango se hace su programa más resistente a cambios al rango. O sea si después decide insertar una columna a la izquierda o unas filas más o suprimir filas, no tiene que cambiar el programa.
Code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
'// usamos un rango nombrado para ser a prueba de filas insertadas o suprimidas
If Not Intersect(Target, Range("miRangitoFavorito")) Is Nothing Then
Application.EnableEvents = False '// para evitar un bucle infinito
With Target(1, 4)
.Value = Time
.EntireColumn.AutoFit
End With
With Target(1, 5)
.Value = Date
.EntireColumn.AutoFit
End With
Application.EnableEvents = True
End If
End Sub
Ahora
la tercera:
Vamos a aplicar el mismo concepto para tiempo y fecha. Seleccione todo columna D y déle el nombre
colTiempo. Ahora columna E y el nombre
colFecha y ajustamos el código así:
Code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
'// usamos un rango nombrado para ser a prueba de filas insertadas o suprimidas
If Not Intersect(Target, Range("miRangitoFavorito")) Is Nothing Then
Application.EnableEvents = False '// para evitar un bucle infinito
'// colTiempo es el rango donde metemos la hora
With Cells(Target.Row, Range("colTiempo").Column)
.Value = Time
.EntireColumn.AutoFit
End With
'// colTiempo es el rango donde metemos el día
With Cells(Target.Row, Range("colFecha").Column)
.Value = Date
.EntireColumn.AutoFit
End With
Application.EnableEvents = True
End If
End Sub
Ahora
para la pregunta suya, cómo no hacer nada si ya tiene valores:
Code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
'// usamos un rango nombrado para ser a prueba de filas insertadas o suprimidas
If Not Intersect(Target, Range("miRangitoFavorito")) Is Nothing Then
Application.EnableEvents = False '// para evitar un bucle infinito
'// colTiempo es el rango donde metemos la hora (originalmente D:D)
With Cells(Target.Row, Range("colTiempo").Column)
'// hacemos algo solamente si no hay nadita en la celda
If Len(.Formula) = 0 Then
.Value = Time
.EntireColumn.AutoFit
End If
End With
'// colTiempo es el rango donde metemos el día (originalmente E:E)
With Cells(Target.Row, Range("colFecha").Column)
'// hacemos algo solamente si no hay nadita en la celda
If Len(.Formula) = 0 Then
.Value = Date
.EntireColumn.AutoFit
End If
End With
Application.EnableEvents = True
End If
End Sub
Y
de último, favor use las etiquetas de CODE. Se pone la palabra "
CODE" entre brackets (paréntesis cuadrado
[] ) y
[/code] al final. Sin las etiquetas la rutina arriba se ve asi:
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
'// usamos un rango nombrado para ser a prueba de filas insertadas o suprimidas
If Not Intersect(Target, Range("miRangitoFavorito")) Is Nothing Then
Application.EnableEvents = False '// para evitar un bucle infinito
'// colTiempo es el rango donde metemos la hora (originalmente D:D)
With Cells(Target.Row, Range("colTiempo").Column)
'// hacemos algo solamente si ya no hay nadita en la celda
If Len(.Formula) = 0 Then
.Value = Time
.EntireColumn.AutoFit
End If
End With
'// colTiempo es el rango donde metemos el día (originalmente E:E)
With Cells(Target.Row, Range("colFecha").Column)
'// hacemos algo solamente si ya no hay nadita en la celda
If Len(.Formula) = 0 Then
.Value = Date
.EntireColumn.AutoFit
End If
End With
Application.EnableEvents = True
End If
End Sub
Como ve, es mucho más difícil leer así.