ACTUALISER UN DOSSIER OUTLOOK AVEC ACCESS VBA (Ver 2019-2021

Patrick_68000 Messages postés 2 Date d'inscription mercredi 30 août 2023 Statut Membre Dernière intervention 5 septembre 2023 - Modifié le 30 août 2023 à 22:58
Patrick_68000 Messages postés 2 Date d'inscription mercredi 30 août 2023 Statut Membre Dernière intervention 5 septembre 2023 - 5 sept. 2023 à 00:22

Bonjour à tous,

J'ai un souci avec IMAP et VBA Access. Lorsque j'envoi des mails à parti d'Access en VBA (Outlook est ouvert), tout est correct. Les mails sont bien envoyés et apparaissent bien dans le dossier "Messages Envoyés" de Outlook et bien sûr chez le FAI puisque j'utilise IMAP. Le problème que je n'aurai jamais pensé avoir sur une propriété aussi simple est le suivant :

Une fois mes mails envoyés je veux simplement récupérer le nombre de mails présents dans le dossier "Messages envoyés" avec "Items.Count" et là le dossier n'est pas actualisé bien que les mails sont présents.

Si par exemple quand j'ouvre Outlook et qu'il y avait déjà 2 anciens mails dans le dossier "Messages envoyés", et que je fais un "Items.count" au début de mon code, le résultat est bien "2". Puis je lance ma procédure d'envois de mails et une fois les mails envoyés, "Items.Count" me retourne toujours 2 et ne comptabilise par les nouveaux mails bien que ceux-ci soient présents dans le dossier Outlook.

Même si je met un DoEvents après l'envoi des mails, cela ne change rien.

Un truc de fou, si je met un MsgBox après l'envoi des mails et avant le "Items.Count", dans ce cas il m'affiche bien le nombre total de mails. On dirai qu'il a besoin d'une interruption dans le déroulement du programme.

Mon code VBA ACCESS ci-dessous : (Outlook ouvert avec 2 mails déjà présents (ce pourrait être 0 mail, c'est pareil))

' ----------------------------------

' --- Connexion à Outlook ---

' ---------------------------------

Dim Total as Long

Dim Instance_Outlook As Outlook.Application

Set Instance_Outlook = New Outlook.Application

'

Dim Espace_Travail As Outlook.Namespace

Set Espace_Travail = Instance_Outlook.GetNamespace("MAPI")

Espace_Travail.Logon , , True, False

'

Dim Mli As Outlook.MailItem

'

Dim Dossier_Envoi As Outlook.Folder

Set Dossier_Envoi = Espace_Travail.GetDefaultFolder(olFolderSentMail) ' Dossier  "Messages envoyés"

Total = Dossier_Envoi.Items.Count

MsgBox Total ' Renvoi bien 2

'

' --------------------

' Envois des mails - x mails

' --------------------

'

Mli.Subject = "fgfgfgdd"

...

Mli.Save

Mli.Send

DoEvents ' Do Events ne change rien au problème

'

' -----------------------------------------------

' Récup du nombre total dans le dossier

' -----------------------------------------------

Total = Dossier_Envoi.Items.Count

MsgBox Total ' Renvoi toujours 2 - Ne prend pas en compte les nouveaux mails présents dans le dossier

'

' OU SI JE MET UN MSGBOX QUELCONQUE AVANT DE COMPTER

'

MsgBox "Un message" ' Interrompt le code temporairement

Total = Dossier_Envoi.Items.Count

MsgBox Total ' Affiche bien le nombre total de mails (nouveaux y compris)

'

BIEN SUR, je ne veux pas de ce MsgBox au milieu. Est-ce que je fais quelque chose d'incorrect dans mon code ? Existe il une instruction VBA pour actualiser le dossier "Messages Envoyés" (ou même la session IMAP ou autre collection) après l'envoi de mails ? Du style "Refresh" ou autre ? Qui me permettrai de récupérer un "Items.Count" opérationnel.

Je cherche des solutions et je dois reconnaitre que je bloque. Je ne vois rien qui permette d'actualiser.

Votre aide serait vraiment bienvenue. Merci à vous.

1 réponse

cs_Trim Messages postés 60 Date d'inscription samedi 4 mars 2006 Statut Membre Dernière intervention 4 septembre 2023 3
4 sept. 2023 à 21:12

Salut,

je ne pense pas que le problème vienne de ton code mais plutôt du fonctionnement du serveur.

Si tu utilises l'application Outlook et que tu fait un mail, tu constateras que ton mail ne part pas tout de suite et qu'il reste quelques milliseconde dans le dossier "en cours d'envoi", tout cela dépend de tout un tas de chose notement de l'activité serveur.

Dans ton code, tu envoies le mail et tu regardes tout de suite si le mail est dans la boite "envoyé". Je pense que ledit mail n'est mème pas encore parti du serveur. Cela marche avec ton msgbox car cela laisse le temps au serveur de faire les manips nécessaires. Tu obtiendrais le même résultat sans msgbox, juste avec un point d’arrêt de quelques secondes avant le "Dossier_Envoi.Items.Count".

Je ne sais pas en quoi cette information t'es utile :

- si tu te sert de cette information pour valider que ton email est bien parti : pas besoin de contrôle, la commande "Mli.Send" doit certainement renvoyer une erreur en cas de problème, regarde la doc. Tu peux simplement faire un "Total += 1".

- si tu te sert de cette information pour valider que ton mail est reçu par le destinataire, il faut bien comprendre qu'un serveur mail n'a aucune garantie de la bonne réception d'un email. Le passage dans le dossier "envoyé" pour outlook est équivalant à l'incrémentation de ta variable "Total".

Enfin, si tu tiens vraiment à te baser sur le count du dossier, fait simplement un timer qui check toutes les x secondes le nombre d'élément.

Clément


2
Patrick_68000 Messages postés 2 Date d'inscription mercredi 30 août 2023 Statut Membre Dernière intervention 5 septembre 2023 1
5 sept. 2023 à 00:22

La confirmation -

Je te remercie Clément pour ton excellente réponse qui correspond en tous points à la révélation que j'ai eu ce week-end.

En effet à force de chercher des solutions, je me suis dit :

"Pourquoi ne pas essayer dans mon code de fermer puis d'ouvrir à nouveau Outlook avec VBA . Peut-être que le fait de faire cette double opération va rafraichir les dossiers".

Donc je code et je lance l'opération et bingo, le système m'envoi un message me disant grosso modo : "Vous essayez de fermer Outlook mais des mails sont encore dans la boite d'envoi en attente d'être envoyés. A la fermeture ils resteront dans la boite d'envoi et vous devrez les envoyer lors de la prochaine ouverture d'Outlook". 

Sur le coup, je n'ai pas eu l'illumination car je me suis dit, "merde encore un problème supplémentaire, qui ne serait pas très agréable à un utilisateur de l'application". Sans compter que fermer/ouvrir Outlook dans un programme Access au milieu d'un traitement, c'est pas le top de l'ergonomie quand même. 

Pour en avoir le coeur net, j'ai relancé le code pour relire le message et ç'est après que j'ai eu l'éclair, la révélation.

Aussitôt j'ai fait une boucle basique pour tester : 

Do while BoiteEnvoi.Items.Count > 0 then

DoEvents

Loop

Et en effet à partir de là je n'ai plus eu de problème. Et je me suis dis comment j'ai fait pour ne pas me rappeler qu'un mail transite par la boite d'envoi avant d'atterrir dans Message Envoyés ? En envoyant quelques mails à la volée, il est évident que le code VBA est beaucoup plus réactif que Outlook lui-même et donc ce décalage crée un problème si on oublie une étape.

En effet que ce soit avec un MsgBox ou en faisant du pas à pas à partir d'un point d'arrêt, j'étais toujours nickel. Normal puisque sur le coup c'est Access qui devenait beaucoup plus lent que Outlook (pour imager).

Pour la petite histoire, j'ai testé l'envoi de simplement 2 mails à la volée et dans la boucle de temporisation j'ai ajouté un compteur. Dans ma séries de tests, il fallait en moyenne 23 tours de boucle pour sortir de celle-ci et synonyme que les 2 mails ont transité de la boite d'envoi vers le dossier Messages Envoyés. Ce qui laisse songeur sur les quelques "millisecondes" (millionième, milliardième..) dont tu parles et combien la notion de temps entre dans une autre dimension. 

Je te remercie très sincèrement de ton excellente réponse car si je n'avais pas trouvé par moi-même la solution (comme tout développeur, c'est toujours une grande satisfaction de trouver par soi-même), et bien ta réponse m'aurait évidemment sorti de la merde de tout façon.

Merci encore pour ton analyse évidemment très juste.

Patrick

1
Rejoignez-nous