# Macro de fecha y hora con otra condicion



## jce (Feb 12, 2008)

Buenos días a todos 

Este es mi primer mensaje en el foro, y lo primero decir que no tengo ni idea de macros, pero tengo la necesidad de resolver un problema. 

Después de mucho navegar por internet he creado una macro que me pone la hora en la columna "D" y la fecha en la "E" cuando meto un dato en la columna "A" (para el rango A5:A100)

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 
With Target(1, 4) 
.Value = Time 
.EntireColumn.AutoFit 
End With 

With Target(1, 5) 
.Value = Date 
.EntireColumn.AutoFit 
End With 
End If 
End Sub 


Mi problema es que necesito que sólo se aplique la macro cuando las columnas de fecha (D) y hora (E) están vacías. Sería algo así:

si las columnas d y e no tienen ningun valor 
actualizar fecha y hora 
fin si 

Pero como lo pongo y donde en la macro?

Gracias y un saludo


----------



## Greg Truby (Feb 12, 2008)

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...
	
	
	
	
	
	



```
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.
	
	
	
	
	
	



```
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í:
	
	
	
	
	
	



```
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:

```
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í.


----------



## jce (Feb 12, 2008)

Muchas gracias por la ayuda

Ya les había comentado que estoy empezando con el tema de las macros por lo que me encuantro bastante perdido.

Probaré el código modificado a ver que tal funciona.

Muchas gracias de nuevo y un saludo


----------



## Greg Truby (Feb 12, 2008)

jce said:


> ...Ya les había comentado que estoy empezando con el tema de las macros por lo que me encuantro bastante perdido...


 
Sí, fue justamente por eso que dividí la explicación en cuatro piezas en vez de combinar todo en un solo tiro.  Para un principiante es más fácil si puede ver la cosa paso por paso. 

Ya cuando uno tenga como 40 o 50 mensajes aquí tengo otra actitud y doy "lecturas de como pescar" y no regalo pescados.


----------



## jce (Feb 12, 2008)

Lo he probado y funciona perfectamente para lo que pretendía.

Muchas gracias por la ayuda y sobre todo la explicación.

Cuando yo tenga 40 o 50 mensajes espero haberme comprado ya la caña de pescar y haber pescado algún pececito pequeño.

Muchas gracias de nuevo y un saludo


----------



## galileogali (Feb 17, 2008)

Greg:
me has enseñado un truco, cuando necesite una explicación abundante de tu parte, el camino es Registrarme como nuevo Uusario y entonces eres capaz de "escribirme" todo un libro.......


----------



## jce (Feb 18, 2008)

Buen truco, si señor.

Yo lo que realmente necesito es algún manual o libro, que estoy empezando y no se por donde tirar.

Aguien me puede recomendar algún manual?

Gracias y un saludo


----------



## memokorella (Jun 16, 2008)

SALUDOS.. acabo de entrar a este foro, ojala me puedan ayudar en lo siguiente: hice un sistema para captura de datos e hice un programa en excel con unos macros para que pongan la fecha y la hora de registro de ciertos datos, tambien otro que hace que se guarde automaticamente cada tres registros y hasta ahi todo bien...solo que ahora necesito hacer un macro que haga un salto de filas a una determinda hora.
como ejemplo:
se capturan los datos en la columna A.
el ultimo dato quedo guardado en la celda A100
la celda activa es la A101
a las 10:00am necesito que se haga el salto de las tres filas
que se vaya a la celda A104 como la celda activa para que ahi siga la captura...
espero haber sido claro.. de antemano gracias y espero su participacion..
por ahi lei en este foro que alguien ocupaba un macro para que se guarde automaticamente, el que tengo yo puede servirle----
aqui en este mismo tema me pueden ayudar o tengo que abrir otro?????


----------



## pichu10 (Jan 3, 2013)

Hola Greg! Yo soy aun mas inexperto que "jce", por eso apelo a tu ayuda. Necesito una macro que me complete la fecha y hora en una celda cuando pongo un valor en otra. Estoy armando una planilla para ventas de un comercio, y quiero que al registrar una venta con el lector de códigos de barra en una celda, en otra quede registrado cuando se realizó esa venta. Creo que "jce" dijo que la macro que hizo hacía justamente eso, pero la verdad es que la copié y no logré hacerla funcionar. Si bien abrí el editor de VBA, aun no se muy bien como hacer funcionar la macro luego de escribirla. 
Desde ya gracias por tu ayuda!!!


----------

