IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VBA Outlook Discussion :

Mailer Daemon - pièce jointe - message d'origine impossible à enregistrer [Toutes versions]


Sujet :

VBA Outlook

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2009
    Messages : 28
    Points : 23
    Points
    23
    Par défaut Mailer Daemon - pièce jointe - message d'origine impossible à enregistrer
    Bonjour,
    J’ai conçu (sous Windows 10 64 bits) un programme VBA dans OUTLOOK 2007 (32 bits) pour enregistrer sur mon disque dur les mails envoyés et reçus.

    Je viens de passer à OUTLOOK 2019 (32 bits) et je rencontre la même difficulté ponctuelle.


    Mon programme fonctionne parfaitement : j’enregistre d’abord le mail sous la forme d’un fichier .msg.

    Ensuite, je récupère chaque pièce jointe que j’enregistre à la suite et j’obtiens dans le répertoire du dossier concerné le résultat suivant :

    C:\MonRépertoireDossier\MonMail_(002).msg
    C:\MonRépertoireDossier\MonMail_(002)_001_MaPJ01.txt
    C:\MonRépertoireDossier\MonMail_(002)_002_MaPJ02.doc

    (Etc… si le mail contient 15 pièces jointes….)
    Je rencontre un seul problème : lorsque j’envoie un message et qu’il n’est pas distribué….

    Dans ce cas, je reçois en retour un mail de non distribution de MAILER-DEMON que je veux logiquement enregistrer comme tous les autres mails.

    Ainsi, si j’envoie un mail intitulé « essai de mail » et qu’il n’est pas distribué, je reçois en retour un mail intitulé « UNDELIVERED MAIL RETURNED TO SENDER » auquel sont joints deux fichiers.

    Le mail lui même (qui contient deux pièces jointes) s'enregistre normalement.

    Puis je veux extraire les deux pièces jointes pour les enregistrer séparément, lesdites pièces sont :


    1.- Un fichier « DETAILS.TXT » qui précise par exemple « Recipient address rejected: User unknown ».

    Je l’enregistre normalement et aisément avec la commande

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaPJ.WriteToFile PathNomExportAttachment
    où le string PathNomExportAttachment est, comme son nom l’indique, le chemin et le nouveau nom sous lequel il sera enregistré sur le disque dur


    2.- le second fichier est une copie du mail envoyé.

    Je ne parviens pas à l’enregistrer… !!!

    Son nom d’après MaPJ.name est curieusement « ESSAI DE MAIL (3,59 Ko) »

    Son suffixe, bien qu’il soit identifié comme message outlook, est seulement « . » et non pas « .msg »

    J’ai l’impression que la commande .WriteToFile ne reconnait pas le nom d’origine de cette pièce jointe….

    Mon chemin de destination ne me parait pas être en cause.



    Je récupère l’erreur suivante :

    Erreur d’exécution ‘-2147221246 (80040102)’
    [Collaboration Data Objects – [MAPI_E_NO_SUPPORT(80040102)]]
    Voilà voilà où j’en suis…………….

    Je ne comprends pas pourquoi spécialement cette pièce jointe ne veut pas s’enregistrer.

    Quelqu’un aurait-il une idée ? une piste ? une solution ? Merci de votre aide.

    Je bloque sans savoir exactement où chercher la solution.



    PS :

    Les déclarations initiales sont les suivantes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    Dim MonOutlook As Outlook.Application
    Set MonOutlook = Outlook.Application
    Dim myNameSpace As Outlook.NameSpace
    Set myNameSpace = MonOutlook.GetNamespace("MAPI")
    Dim objSession, StrEntryID, StrStoreID
     
    Set objSession = CreateObject("Mapi.Session")
    objSession.Logon , , False, False
     
    StrEntryID = ObjCurrentMessage.EntryID
    StrStoreID = ObjCurrentMessage.Parent.StoreID
     
    Set objMAPIMsg = objSession.GetMessage(StrEntryID, StrStoreID)
     
    Dim ObjMAPIMsgAttachments As MAPI.Attachments
    Dim ObjMAPIMsgAttachment As MAPI.Attachment
     
    .....etc....

  2. #2
    Expert éminent
    Avatar de Oliv-
    Homme Profil pro
    solution provider
    Inscrit en
    Mars 2006
    Messages
    4 087
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : solution provider

    Informations forums :
    Inscription : Mars 2006
    Messages : 4 087
    Points : 7 168
    Points
    7 168
    Billets dans le blog
    20
    Par défaut
    Bonjour,
    PAs assez de code pour y voir un problème

    par contre WriteToFile c'est pas du VBA !?

    Tu veux à tout prie l'enregistrer ou juste éviter l'erreur ?

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2009
    Messages : 28
    Points : 23
    Points
    23
    Par défaut
    Le code est bien long et complexe et les détails ne me paraissent pas utiles.

    Oui, je veux garder la trace du mail non distribué et puisqu'il se trouve en PJ, je voudrai l'enregistrer (et pas le sauter).

    Je crois que je n'ai pas bien saisi la différence entre VBA OUTLOOK, MAPI et CDO (CDO que j'avais installé lorsque je travaillais avec OUTLOOK 2007.

    J'ai ré-écrit mon programme en utilisant MAPI car auparavant, lorsque je recevais un mail qui n'était pas de la classe 43 (MAIL OUTLOOK), mon programme plantait et j'avais été obligé de distinguer selon la classe du mail à enregistrer, ce qui aboutissait à deux procédures parallèles.

    Aujourd'hui, je suis arrivé à unifier la procédure et tout fonctionne parfaitement sauf....les mails de MAILER-DAEMON.

    Je n'arrive pas à comprendre pourquoi la pièce jointe qui constitue le mail non distribué est un message outlook ( reconnu comme tel) alors même qu'il n'a pas de suffixe. J'ai bien vérifié et je corrige mon message précédent : il n'a pas de suffixe du tout, pas même le "."

    Je n'arrive pas non plus à comprendre pourquoi il comporte des parenthèses, des blancs...

    En tout cas, toute pièce jointe est parfaitement enregistrée par mon programme sauf....le mail non distribué de MAILER-DAEMON.

    Cette pièce jointe est-elle une pièce jointe ordinaire ou bien particulière...? En quoi un mail attaché à un autre mail serait-il différent ?

    Je nage...

  4. #4
    Expert éminent
    Avatar de Oliv-
    Homme Profil pro
    solution provider
    Inscrit en
    Mars 2006
    Messages
    4 087
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : solution provider

    Informations forums :
    Inscription : Mars 2006
    Messages : 4 087
    Points : 7 168
    Points
    7 168
    Billets dans le blog
    20
    Par défaut
    Citation Envoyé par JackRussel Voir le message
    Le code est bien long et complexe et les détails ne me paraissent pas utiles.
    c'est toi qui vois, mais je pense pouvoir le comprendre ;-)



    Je crois que je n'ai pas bien saisi la différence entre VBA OUTLOOK, MAPI et CDO (CDO que j'avais installé lorsque je travaillais avec OUTLOOK 2007.

    J'ai ré-écrit mon programme en utilisant MAPI car auparavant, lorsque je recevais un mail qui n'était pas de la classe 43 (MAIL OUTLOOK), mon programme plantait et j'avais été obligé de distinguer selon la classe du mail à enregistrer, ce qui aboutissait à deux procédures parallèles.
    Ah ok, mais à priori si tu utilises OUTLOOK 2019, le modèle d'objet fourni par OUtlook doit permettre de faire tes traitements sans passer par MAPI, qui n'est plus installé par défaut et qui même est difficile à installer sans OFFICE2007.

    -->https://www.developpez.net/forums/bl...le-disque-msg/
    -->https://www.developpez.net/forums/bl...yperlien-mail/

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2009
    Messages : 28
    Points : 23
    Points
    23
    Par défaut OUTLOOK 2007 - OUTLOOK 2019 - MAPI - CDO ET MAILER-DEAMON
    Merci Oliv de m'avoir encore une fois mis sur la piste..... Il a suffit de me faire remarquer que PJ.WriteAsFile Mon Cheim n'était pas du VBA

    Il s'agissait d'un mélange intellectuel de ma part : dis moi si j'ai bien compris.

    Avec OUTLOOK 2007, j'avais installé CDO 1.21 pour pouvoir gérer les mails reçus qui n'étaient pas des mails Outlook ( MailItem.class <> 43). Je n'ai d'ailleurs toujours pas compris pourquoi la plupart des mails reçus sont des mails Outlook et pourquoi quelques uns ne le sont pas..... Des zombies ?

    Bref, il m'a fallu gérer ces mails différents et j'y étais parvenu en créant deux procédures, selon qu'il s'agissait d'un mail Outlook ( bibliothèque OUTLOOK) ou bien qu'il s'agissait d'un mail différent ( bibibliothèque MAPI avec CDO 1.21. ).

    Lorsque j'ai installé OUTLOOK 2019, j'ai bien évidemment désinstallé OUTLOOK 2007 mais pas CDO 1.21; j'avais d'ailleurs lu que CDO n'était pas compatible avec OUTLOOK 2019, ce qui s'est avéré faux selon ce que tu as dit et considérant que la bibliothèque est actuellement disponible dans l'explorateur de projet.

    Comme j'avais déjà commencé à ré-écrire ma procédure avant d'installer OUTLOOK 2019, j'ai fait un mélange entre les deux bibliothèques, utilisant sans m'en rendre compte tantot les propriétés OUTLOOK, tantot les propriété MAPI-CDO... En fait, OUTLOOK pour enregistrer le message principal, et MAPI-CDO pour ENREGISTRER les pièces jointes.

    Tout fonctionnait apparemment correctement ....sauf lorsque je voulais enregistrer un message de MAILER DAEMON parce que mon message d'origine n'avait pas été distribué : la pièce jointe constitué par le message non distribué (en fait un message OUTLOOK parti de ma messagerie) ne parvenait pas à être enregistré avec les outils MAPI-CDO comme PJ.WriteToFile.

    J'ai donc repris toute ma procédure et j'ai remplacé les déclarations, les objets, les propriétés et procédures MAPI par des déclarations, des objets, des propriétés et des procédures OUTLOOK 2019 là où ce n'était pas le cas.

    Finalement, tout baigne....

    1.- le mail est enregistré normalement avec : MonMail.saveas MonChemin, OlSaveAsType.olMSG

    2.- chaque pièce jointe (même s'il s'agit d'un message outlook attaché ) est enregistré avec : MaPJ.SaveAsFile MonChemin



    Voilà, voilà...

    Merci encore, Oliv, de tes lumières et j'espère que les explications qui précèdent pourront aider ceux qui, comme moi, se noient avec MAPI et CDO

  6. #6
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2009
    Messages : 28
    Points : 23
    Points
    23
    Par défaut CA PLANTE AILLEURS....
    J'ai parlé trop vite....

    En déclarant partout qu'il s'agit d'un mail OUTLOOK, les pièces jointes (y compris les mails attachés) s'enregistrent parfaitement.

    Encore faut-il qu'il s'agisse d'un mail OUTLOOK, de la classe 43 (MonMail.class = 43)

    Je retombe sur le problème récurrent que j'avais résolu avec MAPI qui permettait de travailler avec des mails qui ne sont pas des mails OUTLOOK : par exemple, l'accusé de réception d'un mail que j'envoie est un mail de la classe 46 (Lu : sujet_de_mon_mail_original).

    Si, dans la procédure, je déclare que le mail est un Object, la procédure s'amorce mais, puisqu'il ne s'agit pas d'un MailItem d'Outlook, il n'est pas possible de récupérer le Sender, le Récipient, et c..., toutes variables qui ne fonctionne qu'avec un mail de la classe 43.

    Une solution ?

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2009
    Messages : 28
    Points : 23
    Points
    23
    Par défaut ReportItem >>> classe 46
    Je découvre dans la (nouvelle) aide de OUTLOOK 2019 qu'un objet de la classe 46 n'est pas un MailItem mais un.... ReportItem.

    Cà avance.

    Sauf erreur, il faut donc créer une procédure spécifique aux ReportItem pour récupérer leurs propriétés, méthodes et tout et tout...

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2009
    Messages : 28
    Points : 23
    Points
    23
    Par défaut [OL-2019] MailItem - ReportItem - Mailer Daemon - Sauvegarder tous les messages sans exception
    Mon besoin était de sauvegarder tous les messages (reçus et envoyés) en indiquant qui est le destinataire pour les messages envoyés et qui est l'expéditeur pour les messages reçus.

    Parmi les messages reçus, il y avait des messages qui faisaient planter la procédure et je n'arrivais pas à comprendre pourquoi. Notamment les les "accusés de lecture" et les messages Mailer Daemon de "non distribution d'un message envoyés".

    Dans un premier temps, avec Outlook 2007, ma procédure fonctionnait parfaitement pour tous les mails reçus ou envoyés de classe 43 (MailItem) mais j'avais téléchargé CDO 1.21 pour récupérer, sur les messages "accusés de lecture" et "mailer daemon" (qui répondaient à la classe 46 ) les données de ces messages particuliers afin de récupérer leurs expéditeur, subject, heure de création, et c...

    Il s'en est suivi une confusion dans le programme entre les propriétés Outlook des uns (MailItem) et les propriétés des autres (CDO.message)....

    Jusqu'à ce que je découvre que les messages de la classe 46 ne sont pas des MailItem mais des ReportItem et que les procédures sont différentes.

    Il a donc fallu distinguer dans la procédure de lancement selon qu'il s'agissait d'un MailItem ou d'un ReportItem :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    For Each MyMessage Ins MyMessagesSélectionnés                        
     
    	Select Case MyMessage.Class 
    		Case 43     'MailItem
    			'procédure de sauvegarde spécifique aux MailItem Outlook
          		Case 46     'ReportItem
     			'procédure de sauvegarde spécifique aux ReportItem Outlook                      
            End select
     Next Lemail
    Ensuite la difficulté venait de ce qu'il était impossible de récupérer pour les ReportItem les mêmes propriétés que pour les MailItem : il fallait donc passer par CDO 1.21.

    J'avais installé CDO 1.21 lorsque je travaillais avec Outlook 2007 et lorsque j'ai installé Outlook 2019, CDO est resté actif et fonctionne parfaitement avec Outllook 2019 : Oliv nous expliquera pourquoi il est dit que CDO 1.21 ne fonctionne pas avec Outllook 2019 (ce qui se révèle faux) et comment faire pour l'installer sur Outlook 2019... Je n'ai pas d'explication technique.

    Il fallait donc créer une routine séparée pour les seuls ReportItem et, à l'intérieur de cette routine, utiliser CDO pour récupérer les propriétés de ces messages là puisque ces propriétés n'existent pas pour les ReportItem.

    A partir du MessageSelectionné déclaré comme Object ( objCurrentMessage) , j'ai créé dans cette routine deux nouveaux objets : d'abord l'objet MonReportItem (ReportItem) et j'ai déclaré ObjCurrentMessage comme CDO.Message. Ainsi, j'ai pu récupérer les propriétés à partir du CDO.Message pour construire le nom sous lequel j'enregistre le fichier puis, grace à l'objet MonReportItem, l'enregistrer puis le déplacer.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    '---------------- OUTLOOK  -----------------------
    Dim MonOutlook As Outlook.Application
       Set MonOutlook = Outlook.Application
    Dim myNameSpace As Outlook.NameSpace
       Set myNameSpace = MonOutlook.GetNamespace("MAPI")
     
     
    '------- CREATION DE L'OBJET ReportItem------------------
    '---- sera utile pour l'enregistrement final ------------
     
        Dim MonReportItem As Outlook.ReportItem
     
            '-- création d'un nouvel objet
            Set MonReportItem = objCurrentMessage
     
    '----------------------------------------------------------------------
     
    '-----------------------------  POUBELLE ------------------------------
     
     
    Dim MesClassements As Outlook.MAPIFolder
       Set MesClassements = myNameSpace.GetDefaultFolder(olFolderDeletedItems)
     
    Dim MaPoubelle As Outlook.Folder
     
                        '--- je sélectionne le dossier et je gère l'erreur éventuelle s'il n'existe pas
                        Set MaPoubelle = MesClassements.Folders("CLASST_" & Format(Now, "yyyymmdd"))
     
                            On Error GoTo 0
     
                        '--- si le dossier sélectionné n'existe pas, je le crée...
                        If MaPoubelle Is Nothing Then
                            Set MaPoubelle = MesClassements.Folders.Add("CLASST_" & Format(Now, "yyyymmdd"))
                        End If
     
                           '-------------------
                            With MaPoubelle
                                .ShowItemCount = olShowTotalItemCount
                            End With
                           '-------------------
     
    '----------------------------------------------------------------------
     
     
    '--------------- CDO-MAPI ------------
    Dim objSession, StrEntryID, StrStoreID
     
     
    '----------CDO-MAPI Propriétés--------
     
    Dim Obj_CDOSender As Object
     
    Dim MySenderName, MySenderAdress As String
     
    Dim Obj_CDORecipients As MAPI.Recipients
    Dim Obj_CDORecipient As MAPI.Recipient
     
    Dim obj_CDOFields As MAPI.Fields
    Dim obj_CDOField As MAPI.Field
     
    Dim Obj_CDOAttachments As MAPI.Attachments
    Dim Obj_CDOAttachment As MAPI.Attachment
     
    '-- définit le suffixe du message MAPI (pour un ReportItem, c'est toujours .msg)
        MAPIextension = "msg"
     
    '--------------------------------------
     
     
    '----- CREATION OBJET MAPI.Message------------------
    '---utile pour extraire propriétés message ---------
     
        '-- création d'une session MAPI-CDO
            Set objSession = CreateObject("Mapi.Session")
                objSession.Logon , , False, False
     
        '-- récupère les identifiants du message en cours
            StrEntryID = objCurrentMessage.EntryID
            StrStoreID = objCurrentMessage.Parent.StoreID
     
        '-- transforme l'objet en cours en un MAPI.Message
            Set objCurrentMessage = objSession.GetMessage(StrEntryID, StrStoreID)
     
    '---------------------------------------------------
     
    Dim Expéditeur as string
    Dim SujetOriginal as string
    Dim MaDateFormatée as string
    Dim NomFinalMessage as string
     
     
    '-- je récupére le nom de l'expéditeur du ReportItem
        Expéditeur = objCurrentMessage.Sender
     
    '-- je récupére l'adresse mail de l'expéditeur du ReportItem
        ExpéditeurAdresse = objCurrentMessage.Sender.address
     
    '-- je récupére le sujet du mail
        SujetOriginal = objCurrentMessage.Subject
     
    '-- je récupére la date d'envoi du mail
        MaDateFormatée = "-[" & Format(DateobjCurrentMessage.TimeSent, "yyyy-mmdd-hhnn") & "]-" 
     
    ' .....et c....pour chaque propriété utile
    ' .... je construit le nom complet du fichier sous lequel le message sera enregistré
     
    	NomFinalMessage = Expéditeur & "-" & MaDateFormatée & "-" & SujetOriginal
     
     
    '---------------- ENREGISTREMENT DU ReportItem -----------
     
    '-- ici, j'utilise l'objet ReportItem crée au départ 
    MonReportItem.SaveAs NomFinalMessagePrincipal, OlSaveAsType.olMSG
     
    '---------------- SUPPRIME LE ReportItem -----------------
     
    'crée un objet résultat de l'action .Move
    Dim MaPoub As Object
     
    Set MaPoub = MonReportItem.Move(MaPoubelle)
    J'espère que les explications qui précèdent aideront à comprendre comment il faut procéder pour enregistrer sur le disque tous les messages sans exception.

    La procédure ci dessus est un résumé d'une procédure en réalité plus complexe car je vérifie aussi la longueur du fichier créé qui ne doit pas dépasser 255 caractères au total, que le sujet du message ne comporte pas des caractères interdits ou inutiles avec une procédure incidente qui me donne la main s'il faut réduire la longueur du futur fichier.

    Il y a certainement des erreurs dans ce résumé ou des longueurs que je ne vois pas qu'Oliv corrigera certainement...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [javamail] envoi mail avec message en pièce jointe
    Par k4eve dans le forum API standards et tierces
    Réponses: 5
    Dernier message: 16/11/2007, 11h17
  2. Ouvrir un message avec fichier en pièce jointe
    Par drinkmilk dans le forum Autres Logiciels
    Réponses: 3
    Dernier message: 21/12/2005, 13h33
  3. Réponses: 6
    Dernier message: 16/11/2005, 11h46
  4. Ajouter des pièces pièces jointes à un message Mail
    Par skywaukers dans le forum Web & réseau
    Réponses: 4
    Dernier message: 05/10/2005, 10h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo