¿Quién ha abierto mi libro de Excel?

Basado en la opción de confirmación de lectura que tiene Microsoft Outlook, te presento una pequeña herramienta que te permitirá averiguar tanto el usuario como el momento exacto en que se ha abierto un libro de Excel.

Atención: Antes de implementar este ejemplo debes saber que cada vez que un usuario abra el archivo, recibirás un correo electrónico de confirmación. Esto puede parecer algo inofensivo, pero si se hace una gran distribución y el archivo es abierto por cientos o miles de usuarios, recibirás otros tantos correos electrónicos, lo que puede ser agobiante.

La mayor parte del código que contiene el archivo que adjunto al pie del artículo se encuentra dentro del evento Open del libro. Además, he creado un módulo que contiene una pequeña función que extrae el nombre de usuario de Windows en caso de no tener configurado el remitente en Outlook.

Inserta el siguiente código en el módulo de libro:

Option Explicit

Private Sub Workbook_Open()
   Dim objOutlook As Outlook.Application
   Dim objOutlookMsg As Outlook.MailItem
   Dim objOutlookRecip As Outlook.Recipient
   Dim strUser As String
   Set objOutlook = CreateObject("Outlook.Application")
   Set objOutlookMsg = objOutlook.CreateItem(olMailItem)
   strUser = cptName
   If cptName = "" Then strUser = Application.UserName
   On Error Resume Next
   With objOutlookMsg
' La siguiente línea es la que contiene el correo del destinatario
      Set objOutlookRecip = .Recipients.Add("micorreo@correo.com")
      objOutlookRecip.Type = olTo
      .Subject = "Atención: Se ha abierto el archivo " & ThisWorkbook.Name
      .Body = "El archivo " & ThisWorkbook.Name & _
         " fue abierto por " & strUser & " el " & Date & " a las " & Time & _
            " h." & vbLf & vbLf
      objOutlookRecip.Resolve
      .Send
   End With
   Set objOutlook = Nothing
End Sub

Y este otro en un módulo estándar:

Option Explicit

Declare Function GetUserName Lib "advapi32.dll" _
    Alias "GetUserNameA" (ByVal lpBuffer As String, _
    nSize As Long) As Long

Function cptName()
   Dim Buffer As String * 100
   Dim BuffLen As Long
   BuffLen = 100
   GetUserName Buffer, BuffLen
End Function
  • Para que el código funcione correctamente, el usuario debe tener Microsoft Outlook abierto. En caso contrario, se produce un error que es gestionado por la instrucción On Error Resume Next, por lo que no se muestra de ninguna forma.
  • Si deseas implementar este código en otro archivo, tienes que habilitar la referencia a Microsoft Outllook 14 Object Library.

Si tienes cualquier duda puedes plantearla en el foro de Ayuda Excel.

 

Respuestas

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

  1. Buenos días,
    Muy buena: Supongo que te estarás hinchando a recibir correos… como acaba de ser el mío.
    El inconveniente que tiene es que no pasa desapercibido ¿podría hacerse?.
    Excelente,
  2. Hola, Juan Luis. Efectivamente he recibido un correo tuyo…

    ¿A qué te refieres con que no pasa desapercibido?

  3. Sí, me refiero a que requiere la autorización del usuario para el envío del correo: Un mensajes de Microsoft Outlook pide el permiso o la denegación del acceso al correo.
  4. Depende del tipo de configuración de seguridad que tengas en Outlook, te solicitará el permiso o no. Trataré de encontrar la forma de hacer lo que dices.
  5. Que pasaría si la persona que abriera el libro no tuviese Outlook y contara con otro proveedor de mail? Es necesario o no?
  6. Lo que pasaría, Fernando, es que directamente la macro no funcionaría. Cada cliente de correo cuenta con un modelo de objetos diferente y éste no siempre es accesible a través de programación.

    Resumiendo, para cada cliente de correo (cuyo modelo de objetos fuese accesible) habría que desarrollar una macro diferente.

  7. Buenos días:

    Me parece interesante, con esta macro, a parte de saber quién abre, consigues también su dirección de correo electrónico (al menos la de su perfil en outlook), de modo que puede ser un poco “ilícito”.

    Podría hacerse también, haciendo que el excel lo envíe desde un servidor de correo externo (evitando así el que el usuario tenga abierto el outlook), claro que el ordenador debe tener activada la conexión a internet, pero puedes enviarte un correo desde tu propio correo con la información necesaria (solo obtendrías la información de la apertura del libro, no tendrías el mail, claro)

    Un saludo

    Andrés

  8. SERGIO.
    BUENOS DIAS, ENCONTRE TU PAGINA Y PEDIRTE COLABORACION Y ACONSEJARME LA MEJOR MANERA DE MANEJAR BASE DE DATOS CON ALIMENTACION AUTOMATICA DE DATOS, YA QUE EN ESTA INCURSION QUE REALICE EN MI TRABAJO CON EL OBJETIVO DE AUTOMATIZAR LA GRANINFORMACION QUE TENEMOS CREE BASE DE DATOS CON FORMULAS Y QUE AL FINAL RESULTARON CARGOSAS YA QUE NO ABRIAN Y EN ALGUNOS MOMENTOS SE COLGABAN. Y BUENO DESPUES DE PASAR POR ESOS PROBLEMAS AHORA ESTOY CREANDO BASE DE DATOS CON VBA PARA LA ALIMENTACION DE DATOS Y ESPERO NO PASAR POR LO MISMO.
    ESPERO TUS COMENTARIOS.
    HECTOR.

  9. Hola,
    Al abrir el archivo que mandas, me da el siguiente error:
    Error de compilación.
    No se ha definido el tipo definido por el usuario
    Qué es lo que sucede?

  10. Buenos días. Me parece muy interesante este artículo.
    ¿Se podría hacer una macro que cada vez que un usuario abre el archivo se copie su nombre de usuario y la fecha en una hoja del Excel? De esta manera tendríamos la misma información, evitaríamos tener tantos correos electrónicos y no dejaría el rastro de un correo electrónico en la bandeja de salida del usuario.

    1. Hola, Fernando! Claro que es posible, pero perderías el control hasta que el archivo no llegue a ti de nuevo. Si alguien decide hacer una copia del archivo, ya no sabrás los usuarios por los que ha pasado esa copia…

      1. Cierto que perdería el control. Mi caso es diferente. Trabajo con archivos colgados en un portal y con permisos de solo lectura. A mí me gustaría saber cuanta gente ha abierto el fichero para saber si ese fichero es útil y mis compañeros lo utilizan. En el caso que no lo utilicen dejaría de realizar ese fichero que tanto tiempo me lleva hacerlo. A ver si alguien se anima y escribe la macro.

        1. Ahora lo entiendo, Fernando…
          Recuerda que si el archivo es de solo lectura, debes tenerlo en cuenta a la hora de crear la macro. Desde el código, cambia los permisos para que se pueda escribir, a continuación ejecutar la macro, y vuelves a establecer los permisos de solo lectura…

  11. Me autorrespondo:

    Private Sub Workbook_Open()
    Dim i As Integer
    i = Worksheets(“Hoja2”).Cells(Rows.Count, 1).End(xlUp).Row + 1
    Worksheets(“Hoja2”).Cells(i, 1) = Environ(“Username”)
    Worksheets(“Hoja2”).Cells(i, 2) = Date
    Worksheets(“Hoja2”).Cells(i, 3) = Time

    Application.DisplayAlerts = False
    ActiveWorkbook.Save
    Application.DisplayAlerts = True

    End Sub