Imprimir página | Cerrar ventana

Vincular correos Access Outlook

Impreso de: Foro de Access y VBA
Categoría: Access y VBA
Nombre del foro: Access y VBA
Descripción del foro: Foro de programacion en Access (Con código y sin código)
URL: http://www.mvp-access.com/foro/forum_posts.asp?TID=84705
Fecha de impresión: 22/Noviembre/2019 a las 06:40


Tema: Vincular correos Access Outlook
Publicado por: valencianoblaugrana
Asunto: Vincular correos Access Outlook
Fecha de publicación: 14/Septiembre/2019 a las 17:13
Buenos días,

He creado una base de datos a través de la cual envío correos a través de Microsoft Outlook, todos los correos se me quedan almacenados en una tabla. ¿Hay alguna manera de vincular éstos registros de esta tabla con la bandeja de correos enviados de Outlook?, es decir, que yo pueda, con un enlace y con un clic, ir al correo que envié en su día en Outlook. Conectar la bandeja de enviados de Outlook y Access. Agradecería sugerencias o ejemplos.

Muchas gracias de antemano

Saludos



Respuestas:
Publicado por: jilo
Fecha de publicación: 15/Septiembre/2019 a las 08:40
Hola.

Mira este codigo que te lista los asuntos de los emails de la bandeja enviados, por sí te sirve...
Sub ListaBandejaEnviadosDeOutllok()
Dim objOL As Outlook.Application
   Dim objNS As NameSpace
   Set objOL = New Outlook.Application
   Set objNS = objOL.GetNamespace("MAPI")
   Set objfolder = objNS.GetDefaultFolder(olFolderSentMail)
   For Each correo In objfolder.Items
       Debug.Print correo
   Next
End Sub



-------------
Espero te sirva !!!!!!
Iñaki


Publicado por: happy
Fecha de publicación: 15/Septiembre/2019 a las 11:36
Los mensajes de correo de Outlook tienen una propiedad llamada EntryID, que es un identificador único del elemento. A través de un objeto NameSpace puedes acceder a un elemento cualquiera a través con esa propiedad. Eso sí, primero deberás almacenar esa propiedad en tu tabla de mensajes y luego podrás a ese correo de nuevo

Ejemplo simple de código para hacerlo:

Set OL = CreateObject("Outlook.Application")
    Set Ns = OL.GetNamespace("MAPI")
   
    Set rs = CurrentDb.OpenRecordset("TuTabla")
   
    While Not rs.EOF
        ' referenciamos el mensaje de correo mediante su EntryID
        Set oMail = Ns.GetItemFromID(rs("EntryID"))
        ' visualizamos el correo
        oMail.display
       
        rs.MoveNext
    Wend

Sustituye los nombres y el procedimiento según te convenga ...

Otra cosa más: si los correos se mueven a otra ubicación u otra carpeta de Outlook  esa propiedad EntryID cambiará, así que le perderás de nuevo el rastro ... pero supongo que ese es otro tema



-------------
Saludos,

Juan M. Afan de Ribera


Publicado por: valencianoblaugrana
Fecha de publicación: 15/Septiembre/2019 a las 17:50
Muchas gracias Happy, 
Pero el problema se presenta en como almaceno en el campo correspondiente de la tabla "ENVIADOS" el elemento "EntryID" al enviar un correo electrónico para posteriormente localizarlo a través del código de ejemplo que me indicas.


Saludos


Publicado por: happy
Fecha de publicación: 15/Septiembre/2019 a las 18:11
Cuando envias el correo supongo que utilizas un objeto MailItem de Outlook no? Pues una vez enviado y antes de que se destruya el objeto o se cree otra instancia referenciando un nuevo correo recuera la propiedad EntryID del objeto y lo almacenas en esa tabla junto con el resto de datos del mensaje enviado.

-------------
Saludos,

Juan M. Afan de Ribera


Publicado por: valencianoblaugrana
Fecha de publicación: 15/Septiembre/2019 a las 19:11
Perdona, pero mis conocimientos de vba son muy limitados. Lo estoy recuperando después de enviar el mensaje justo después de la propiedad msg.send pongo MSGBOX msg.entryID para que me muestre el indentificador pero me dice que que se eliminó y cambió de ubicación. Si lo pongo antes me dice que no se encuentra.

Gracias


Publicado por: happy
Fecha de publicación: 15/Septiembre/2019 a las 20:18
Si, tienes razón. Se me había olvidado que funcionaba de otra manera. En realidad debes hacer una copia del MailItem original, guardar la copia y almacenar el EntryID de la copia. Luego ya te funcionará como se espera. Por ejemplo:

Dim OL As Outlook.Application
Dim Ns As Outlook.Namespace
Dim oMail As Outlook.MailItem
Dim oMail2 As Outlook.MailItem
Dim rs As DAO.Recordset
   
    Set OL = CreateObject("Outlook.Application")
    Set Ns = OL.GetNamespace("MAPI")
   
    Set oMail = OL.CreateItem(olMailItem)
    oMail.Subject = "Asunto del mensaje"
    oMail.To = "destinatario@dominio.com"
    ' antes de enviar el mensaje, creamos una copia
    Set oMail2 = oMail.Copy
    ' ahora sí, enviamos el correo y éste se "perderá"
    oMail.send
    ' guardamos la copia
    oMail2.Save
    ' y ahora guardamos el EntryID de la copia
    ' (la copia NO la hemos enviado y por tanto no se "pierde")
    Set rs = CurrentDb.OpenRecordset("TuTabla")
    rs.AddNew
    rs("Asunto") = oMail2.Subject
    rs("EntryID") = oMail2.EntryID
    rs.Update

luego ya podrás acceder al EntryID almacenado y mostrar el mensaje o lo que sea. Recuerda que si el mensaje se mueve de carpeta, entonces el EntryID almacenado ya no será válido (Outlook habrá creado otro EntryID y ya no servirá el anterior)


-------------
Saludos,

Juan M. Afan de Ribera


Publicado por: valencianoblaugrana
Fecha de publicación: 15/Septiembre/2019 a las 22:08
Quieres decir si se mueve de la bandeja de enviados?.


Publicado por: happy
Fecha de publicación: 15/Septiembre/2019 a las 22:57
Sí. Cuando mueves un mensaje de un lado para otro pierde ese EntryID. Me imagino que internamente no se "mueve" el mensaje, sino que se crea una copia y se coloca en la nueva ubicación. Esa copia será un nuevo elemento y por tanto tendrá un EntryID propio diferente del original.




-------------
Saludos,

Juan M. Afan de Ribera


Publicado por: happy
Fecha de publicación: 15/Septiembre/2019 a las 23:55
Me he dado cuenta de que lo que te he dicho antes funcionar, funciona, pero creo que no es lo más correcto. Al hacer una copia del mensaje y no enviarlo, éste se queda en la bandeja de salida, y ese será el que luego almacenarás su EntryID. Creo que NO es una solución limpia.

Lo que he pensado es que una manera "aproximada" de hacerlo sería básicamente enviar el correo e inmediatamente después ir a la bandeja de enviados y consultar el último mensaje enviado. De ese último mensaje, tomar el EntryID y ya lo tendríamos. Un ejemplo de código podría ser éste:

Dim OL As Outlook.Application
Dim Ns As Outlook.NameSpace
Dim oMail As Outlook.MailItem
Dim oMail2 As Outlook.MailItem
Dim rs As DAO.Recordset
Dim f As Outlook.Folder
Dim MensajesEnviados As Long
   
    Set OL = CreateObject("Outlook.Application")
    Set Ns = OL.GetNamespace("MAPI")
    ' referenciamos la carpeta enviados
    Set f = Ns.GetDefaultFolder(olFolderSentMail)
   
    Set oMail = OL.CreateItem(olMailItem)
    oMail.Subject = "Asunto del mensaje de correo"
    oMail.To = "destimatario@dominio.com"
    ' tomamos nota del nº de mensajes enviados hasta el momento
    MensajesEnviados = f.Items.Count
    ' enviamos el mensaje
    oMail.send
    ' bucle para esperar que se actualice la carpeta enviados
    ' cuando notemos que el nº de mensajes cambie, salimos del bucle
    Do While MensajesEnviados = f.Items.Count
        DoEvents
    Loop
    ' referenciamos el último mail de la carpeta enviados
    Set oMail2 = f.Items(f.Items.Count)
    ' y ahora guardamos el EntryID de ese mensaje   
    Set rs = CurrentDb.OpenRecordset("TuTabla")
    rs.AddNew
    rs("Asunto") = oMail2.Subject
    rs("EntryID") = oMail2.EntryID
    rs.Update

    ' ... ...

Esto creo que puede funcionar. Pero si estás enviando mensajes en un entorno multiusuario, con Exchange y desde una cuenta compartida, esta lógica podría tener algún punto débil, ya que otro usuarios podría enviar un mensaje de correo al mismo tiempo y "colarse" en el tiempo de espera mientras se actualiza la carpeta de enviados. Pero vamos, yo creo que es difícil que se de tanta casualidad. Aún así, puedes comprobar el asunto del mensaje de ese último mensaje enviado y si no lo fuera, seguir esperando la actualización hasta el siguiente mensaje. Espero explicarme bien ...

Por cierto, el código que pongo aquí (y normalmente el que publico al dar alguna respuesta en general) NO tiene por qué ser completamente infalible. Funcionar suele funcionar, ya que normalmente lo pruebo. Pero no intento darlo todo hecho del todo. Suelen ser ideas y cosas en las que basarse para luego escribir el código que se adapte al entorno al que se dirija. Smile


-------------
Saludos,

Juan M. Afan de Ribera


Publicado por: valencianoblaugrana
Fecha de publicación: 16/Septiembre/2019 a las 20:13
Hola Happy,

Es muy útil y funciona el último código,pero tarda mucho en ejecutar, puesto que si la carpeta enviados tiene mas de 300 correos, te obliga a tener el formulario abierto para que cuando el proceso termine copie el EntryID en el campo correspondiente para después enviarlo a la tabla al guardar. Si el usuario lo cierra antes de tiempo o le da al botón de guardar mientras el campo esta en blanco no se almacenaría.

Saludos


Publicado por: happy
Fecha de publicación: 17/Septiembre/2019 a las 00:37
No se si te entiendo. ¿Qué formulario es ese que comentas? ¿Qué tiene que ver con la rutina de ejemplo que he puesto? Lo que debes hacer es adecuarla bien al procedimiento que tengas y pulirla y pulir también el procedimiento hasta que consigas el mejor rendimiento posible.

Lo de los 300 correos ... yo, las pruebas que hice para esa rutina de ejemplo, las he hecho con una carpeta de Enviados que tiene unos 9.000 correos almacenados. No creo que vaya por ahí.

Ya te lo decía en mi anterior mensaje, es un código de ejemplo. NO pretendo escribir rutinas para otras personas, sólo darles pistas para que aprendan y les ayuden a que se trabajen sus propios proyectos

Smile


-------------
Saludos,

Juan M. Afan de Ribera


Publicado por: valencianoblaugrana
Fecha de publicación: 21/Septiembre/2019 a las 11:45
Buenos días Happy

Estoy utilizando el siguiente código para visualizar el correo en cuestión:

Private Sub Visualizar_Click()

Dim f As Outlook.Folder
Dim Msg2 As Outlook.MailItem
Dim rs As DAO.Recordset
Dim Ns As Outlook.NameSpace
Dim OutLookApp  As Outlook.Application

    Set OutLookApp = CreateObject("Outlook.Application")
     
    Set Ns = OutLookApp.GetNamespace("MAPI")
    
    Set rs = CurrentDb.OpenRecordset("TDatos")
    
    Set f = Ns.GetDefaultFolder(olFolderSentMail)
    
        
    While Not rs.EOF
        ' referenciamos el mensaje de correo mediante su EntryID
        Set Msg2 = Ns.GetItemFromID(rs("EntryID"))
        ' visualizamos el correo
        Msg2.Display
        
        rs.MoveNext
    Wend

End Sub

El caso es que la ejecución se para en la linea en rojo y me dice que no es posible valor nulo. 
Decir que lo estoy ejecutando desde un formulario a través de un botón llamado "visualizar" en dicho formulario recupero el registro del correo que luego quiero ver en outlook el campo "EntryID" en el formulario se llama "ID_Txt".


Muchas gracias

Saludos


Publicado por: happy
Fecha de publicación: 21/Septiembre/2019 a las 13:21
Pero ¿has comprobado previamente el valor que viene en rs("EntryID")?. Evidentemente, si como te aparece en el error, ese campo tiene un valor nulo o una cadena vacía, no hay nada qué hacer. Pon algún punto de interrupción en el código (señala una línea para detener y pulsa F9) y haz un debug.print nombre variable o un msgbox nombre variable para ver qué hay dentro de los campos del recordset o en las variables (también sirve si por encima de la variable o lo que sea pasas el ratón y te aparecerá un tool tip con el valor de esa variable o campo).

En la tabla ¿has comprobado que realmente hayas guardado el valor de EntryID en cada registro?


-------------
Saludos,

Juan M. Afan de Ribera


Publicado por: valencianoblaugrana
Fecha de publicación: 21/Septiembre/2019 a las 13:30
Hola Happy

Si, en la tabla están almacenados los "entryID" correspondientes, solo en los últimos 5 registros desde que estoy haciendo estas pruebas, los demás registros están en blanco. Influye eso?

Saludos


Publicado por: happy
Fecha de publicación: 21/Septiembre/2019 a las 13:55
Hombre, claro. Si la forma en que Outlook va a localizar cada mensaje o elemento es a través del EntryID, si tú le dices que EntyID = (en blanco), pues Outlook también se va a quedar (en blanco) Smile

- Comprueba primero que el campo EntryID tenga algo dentro. 
- Si NO tiene nada, pasa al siguiente registro
- Si contiene algo, pásale a Outlook el valor de EntryID (tal y como lo tienes ahora) para mostrar el mensaje.

Igualmente, el código que utilizas te podría llegar a abrir un montón de mensajes uno detrás de otro. Ahora son 5, como dices, pero a lo mejor en el futuro tienes 30 o 100 o ... ¿Realmente es así como lo quieres hacer?

Por otro lado también estaría bien que comprobaras que el EntryID, si existe, es válido y apunta a un mensaje real (no fuera que ese mensaje haya desaparecido o se haya movido a otra carpeta, con lo que el EntryID habría cambiado)


-------------
Saludos,

Juan M. Afan de Ribera


Publicado por: valencianoblaugrana
Fecha de publicación: 21/Septiembre/2019 a las 14:15
Yo lo que quiero es que me abra sólo aquel correo cuyo EntryID coincida con el id_txt que tengo activo en ese momento en el formulario. No que me abra los 5 que tengo ahora almacenados en la tabla.

Saludos


Publicado por: happy
Fecha de publicación: 21/Septiembre/2019 a las 16:10
Pues entonces 

- busca en la tabla el EntryID que coincida con el id_txt que tengas en el formulario (sentencia SQL con el Where adecuado)
- carga el recordset con la SQL o utiliza si quieres un dlookup
- visualiza el mensaje utilizando el EntryID que hayas recuperado en el recordset o en el dlookup


-------------
Saludos,

Juan M. Afan de Ribera


Publicado por: valencianoblaugrana
Fecha de publicación: 28/Septiembre/2019 a las 11:58
Buenos días Happy y muchas gracias por tu ayuda, rutina funcionando y sin ningún problema.

Se puede cerrar el hilo.

Un Saludo



Imprimir página | Cerrar ventana