domingo, 11 de diciembre de 2011

Fechador: da la fecha al cambiar un dato

Descargar el fichero: fechador.xlsm

Fechador contiene una macro que establece la fecha y la hora junto a cierta celda cuando ésta experimenta cambios. Esto se logra manejando los eventos, concretamente el evento Change que detecta cuando se produce un cambio en alguna celda de una hoja. Podemos ejecutar la macro cuando el cambio se produzca en todas las celdas, o bien únicamente en una de ellas, o en un rango, y esto lo conseguimos manejando el target. Veamos cómo se hace.

Hoja 1



Al escribir en cualquier celda de la columna D, y en particular en las celdas verdes, y bajo ellas, al pulsar INTRO, automáticamente se anotará en la celda de la derecha la fecha y hora actuales, siempre que su ordenador esté correctamente puesto en fecha y hora.

Esto se consigue con una pequeña macro que se ha de escribir, no en un Módulo como es habitual al programar macros, sino en la Hoja1. Vea la siguiente imagen. Por cierto, para pasar de un elemento a otro de los de la imagen, o de un módulo a otro, no basta con hacer click con el ratón, se ha de hacer doble click.



Al situarnos dentro del Editor de Visual Basic en la Hoja1, a la derecha aparecerá la posibilidad de manejar dos desplegables. Hemos de elegir "Worksheet" en el de la izquierda y "Change" en le de la derecha.


Código:

Private Sub Worksheet_Change(ByVal Target As Range)
Application.MoveAfterReturn = False
If Target.Count = 1 Then
  If (Target.Column = 4 And Target <> 0) Then
    Target.Offset(0, 1) = Now
  End If
End If
End Sub


Hoja 2

Nos situamos ahora en la Hoja 2. En este caso pretendemos que se indique la fecha y la hora de forma automática en la columna E, siempre que se efectúen anotaciones o cambios en cualquier celda del rango B7:D20.



Vamos al Editor de Visual Basic, y en el Explorador de Proyectos nos situamos en la Hoja2. Para ello debemos pulsar doble click sobre la Hoja2, tal y como se muestra en la siguiente imagen.



En este caso la macro cambia ligeramente.

Código:

Private Sub Worksheet_Change(ByVal Target As Range)
Application.MoveAfterReturn = False
If Target.Count = 1 Then
  If Not Intersect(Target, Range("B5:D39")) Is Nothing Then
    Cells(Target.Row, "E") = Now
  End If
End If
End Sub

19 comentarios:

  1. Mi estimado, gracias por la informacion, como podria yo usar esta funcion, con diferentes columnas y diferentes valores?

    saludos

    ResponderEliminar
  2. Interesante. En inglés lo llaman "record auditing". No se si en Español se podría traducir literalmente como auditoria de registros. Te lo digo porque al leer la entrada lo de fechador me sonaba raro :-)

    ResponderEliminar
  3. Hola Ángel.

    Gracias por la información. Así, si alguien busca mediante un buscador lo de record auditing es posible que llegue a esta entrada.

    ResponderEliminar
  4. Hola!

    Te recomiendo que incluyas esta librería javascript en la plantilla de tu blog para poder formatear códifo fuente en tus post: http://alexgorbatchev.com/SyntaxHighlighter/ Es muy fácil de usar, pero si no tienes tiempo te echo una mano.

    ResponderEliminar
  5. Hola Ángel.

    Gracias por el ofrecimiento.
    En su día estuve viendo esa página que tiene una pinta estupenda. El código queda genial. La descarté porque pensé que sólo valía para Wordpress y este blog esta en Blogger.
    Lo volveré a mirar, y si requiero de tus amables servicios te lo comento.
    Da gusto contar con lectores del blog tan animados.
    Mil gracias.

    ResponderEliminar
  6. Muy buen articulo.
    Es una instrucción muy interesante sobretodo cuando se utilizan documentos compartidos en red. Se podría añadir también una columna con los datos del usuario que ha realizado la modificación?

    ResponderEliminar
  7. Sí, sería interesante una celda "readonly" que automaticamente registra el "username" de las credenciales de la cuenta de Windows que ha iniciado sesión. Creo que en VB se usa esta variable "System.Enviroment.Username"

    ResponderEliminar
  8. He includido esta línea en la Hoja 2 dentro del segundo bloque "If" y añade el nombre:

    Cells(Target.Row, "F") = Application.UserName

    Es realmente útil para Hojas Excel compartidas.

    ResponderEliminar
  9. wuooo muy buena la explicación se entiende muy bien gracias por el aporte

    ResponderEliminar
  10. Saludos. Como podría que en una celda poner una fecha y que cambie automaticamente el día cada que imprima. Pero que no lo haga si es sábado o domingo hasta el fin de un mes. Gracias.

    ResponderEliminar
  11. Genial!!!
    Este es un señor macro, las aplicaciones con él son infinitas. Gracias!!!

    ResponderEliminar
  12. Hola el Cells(Target.Row, "F") = Application.UserName no me sirve queda en un loop :S

    ResponderEliminar
  13. Hola, como puedo hacer para que me indique cual celda o por lo menos el numero de columna.
    Gracias

    ResponderEliminar
  14. Que tal, quisiera saber si existe la posibilidad de aplicar esta fórmula para que coloque la hora en cada linea cuando se copian varias celdas de información. Para hacer una carga masiva de datos. Saludos!

    ResponderEliminar
  15. Muchas gracias, por la información a mi lo que me interesaría es un código similar pero que en vez de introducir yo directamente el dato en la celda sea por medio de una fórmula y que se actualice la información de manera automática.

    ResponderEliminar
  16. excelente, de tanto buscar encontre la solucion a mi problema. saludos

    ResponderEliminar
  17. muy buena, quien me puede decir como usar este codigo para que se autocomeplete con fecha y hora cuando modifiquen 3 diferentes columnas dentro de una misma hoja de excel

    ResponderEliminar
  18. COMO SE HACE PARA QUE CUANDO LA CELDA ESTE VACIA LA CELDA EN REFERENCIA NO DEVUELVA DATO DE HORA O NO QUEDE GRABADO EL ANTERIOR

    ResponderEliminar
  19. COMO SE HACE PARA QUE CUANDO LA CELDA ESTE VACIA LA CELDA EN REFERENCIA NO DEVUELVA DATO DE HORA O NO QUEDE GRABADO EL ANTERIOR

    ResponderEliminar