Comment copier le message de courrier D'Outlook dans excel en utilisant VBA ou des Macros
je suis un débutant en VBA et Macros. Si quelqu'un m'aide avec le code VBA et les macros, il sera utile.
tous les jours je recevrai environ 50-60 courriers avec un sujet standard: "tâche terminée". J'ai créé une règle à tous ces mails pour passer à un dossier spécifique: "tâche terminée".
lire tous les 50 à 60 courriels par jour et mettre à jour tous les courriels prend beaucoup de temps. Tous les messages 50-60 venant dans ma boîte de réception auront le même sujet mais d'utilisateurs différents. Corps de mail varier.
2 réponses
Puisque vous n'avez pas mentionné ce qui doit être copié, j'ai quitté la section vide dans le code ci-dessous.
Aussi, vous n'avez pas besoin de déplacer l'email pour le dossier, puis exécutez la macro dans ce dossier. Vous pouvez exécuter la macro sur le courrier entrant et le déplacer vers le dossier en même temps.
Cela vous aidera à démarrer. J'ai commenté le code pour que vous n'ayez aucun problème à le comprendre.
Premier coller le texte ci-dessous mentionné code dans le module outlook.
- cliquez sur Outils~>règles et alertes
- Cliquez sur "Nouvelle Règle"
- Cliquez sur "démarrer à partir d'une règle vide"
- sélectionnez "Vérifier les messages à leur arrivée"
- Sous conditions, cliquez sur "avec des mots spécifiques dans l'objet"
- cliquez sur" mots spécifiques " dans la description des règles.
- Tapez le mot que vous voulez vérifier dans la boîte de dialogue qui apparaît et cliquez sur "ajouter".
- Cliquez sur "Ok" et cliquez sur suivant
- Sélectionner "déplacer vers le dossier spécifié" et sélectionner "exécuter un script" dans la même case
- dans la case ci-dessous, spécifiez le dossier spécifique et aussi le script (la macro que vous avez dans module) à exécuter.
- Cliquez sur terminer et vous avez terminé.
Quand le mail arrive non seulement l'e-mail déplacer vers le dossier que vous spécifiez, mais les données qu'il sera également exporté vers Excel.
non testé
Const xlUp As Long = -4162
Sub ExportToExcel(MyMail As MailItem)
Dim strID As String, olNS As Outlook.Namespace
Dim olMail As Outlook.MailItem
Dim strFileName As String
'~~> Excel Variables
Dim oXLApp As Object, oXLwb As Object, oXLws As Object
Dim lRow As Long
strID = MyMail.EntryID
Set olNS = Application.GetNamespace("MAPI")
Set olMail = olNS.GetItemFromID(strID)
'~~> Establish an EXCEL application object
On Error Resume Next
Set oXLApp = GetObject(, "Excel.Application")
'~~> If not found then create new instance
If Err.Number <> 0 Then
Set oXLApp = CreateObject("Excel.Application")
End If
Err.Clear
On Error GoTo 0
'~~> Show Excel
oXLApp.Visible = True
'~~> Open the relevant file
Set oXLwb = oXLApp.Workbooks.Open("C:\Sample.xls")
'~~> Set the relevant output sheet. Change as applicable
Set oXLws = oXLwb.Sheets("Sheet1")
lRow = oXLws.Range("A" & oXLApp.Rows.Count).End(xlUp).Row + 1
'~~> Write to outlook
With oXLws
'
'~~> Code here to output data from email to Excel File
'~~> For example
'
.Range("A" & lRow).Value = olMail.Subject
.Range("B" & lRow).Value = olMail.SenderName
'
End With
'~~> Close and Clean up Excel
oXLwb.Close (True)
oXLApp.Quit
Set oXLws = Nothing
Set oXLwb = Nothing
Set oXLApp = Nothing
Set olMail = Nothing
Set olNS = Nothing
End Sub
suivi
pour extraire le contenu de votre corps de courrier électronique, vous pouvez le diviser en utilisant SPLIT() et ensuite extraire les informations pertinentes de celui-ci. Voir cet exemple
Dim MyAr() As String
MyAr = Split(olMail.body, vbCrLf)
For i = LBound(MyAr) To UBound(MyAr)
'~~> This will give you the contents of your email
'~~> on separate lines
Debug.Print MyAr(i)
Next i
Nouvelle introduction 2
dans la version précédente de la macro "SaveEmailDetails" j'ai utilisé cette instruction pour trouver Inbox:
Set FolderTgt = CreateObject("Outlook.Application"). _
GetNamespace("MAPI").GetDefaultFolder(olFolderInbox)
j'ai depuis installé une nouvelle version D'Outlook et j'ai découvert qu'elle n'utilise pas la boîte de réception par défaut. Pour chacun de mes comptes e-mail, il a créé un magasin séparé (nommé pour l'adresse e-mail) chacun avec sa propre boîte de réception. Aucune de ces boîtes N'est la valeur par défaut.
cette macro, affiche le nom du stockez la boîte de réception par défaut dans la fenêtre immédiate:
Sub DsplUsernameOfDefaultStore()
Dim NS As Outlook.NameSpace
Dim DefaultInboxFldr As MAPIFolder
Set NS = CreateObject("Outlook.Application").GetNamespace("MAPI")
Set DefaultInboxFldr = NS.GetDefaultFolder(olFolderInbox)
Debug.Print DefaultInboxFldr.Parent.Name
End Sub
sur mon installation, cette sortie: "fichier de données Outlook".
j'ai ajouté une instruction supplémentaire à la macro "SaveEmailDetails" qui montre comment accéder à la boîte de réception de n'importe quel magasin.
Nouvelle introduction 1
Un certain nombre de personnes ont ramassé la macro ci-dessous, trouvée utile et m'ont contacté directement pour de plus amples conseils. A la suite de ces contacts, j'en ai pris quelques-uns. améliorations à la macro donc j'ai posté la version révisée ci-dessous. J'ai aussi ajouté une paire de macros qui ensemble retourneront L'objet MAPIFolder pour n'importe quel dossier avec la hiérarchie Outlook. Ils sont utiles si vous souhaitez accéder à d'autres qu'un dossier par défaut.
le texte original faisait référence à une question par date qui se rapportait à une question antérieure. La première question a été supprimée de sorte que le lien a été perdu. Ce lien était à mise à jour de la feuille excel basée sur outlook mail (fermé)
texte Original
il y a un nombre surprenant de variations de la question: "Comment puis-je extraire des données des e-mails Outlook pour exceller classeurs?"Par exemple, deux questions sur [outlook vba] la même question a été posée le 13 août. Cette question fait référence à une variation de décembre à laquelle j'ai tenté de répondre.
pour la question de décembre, je suis allé trop loin avec une réponse en deux parties. La première partie était une série de l'enseignement des macros qui ont exploré la structure de dossier D'Outlook et ont écrit des données à des dossiers de texte ou des classeurs Excel. La deuxième partie discuté de la façon de concevoir le processus d'extraction. Pour cette question, Siddarth a fourni une réponse excellente et succincte, puis un suivi pour aider à la prochaine étape.
ce que le questionneur de chaque variation semble incapable de comprendre, c'est que nous montrer à quoi ressemblent les données à l'écran ne nous dit pas à quoi ressemble le texte ou le corps html. Ce la réponse est une tentative pour dépasser ce problème.
la macro ci-dessous est plus compliquée que celle de Siddarth, mais beaucoup plus simple que celles que j'ai incluses dans ma réponse de décembre. Il n'y a plus que l'on peut ajouter, mais je pense que c'est suffisant pour démarrer.
la macro crée un nouveau classeur Excel et affiche les propriétés sélectionnées de chaque courriel dans la boîte de réception pour créer cette feuille de travail:
en haut de la macro il y a un commentaire contenant huit hachages (#). La déclaration ci-dessous que le commentaire être modifié parce qu'il identifie le dossier dans lequel le classeur Excel sera créé.
tous les autres commentaires contenant des hachures suggèrent des modifications pour adapter la macro à vos besoins.
comment les courriels à partir desquels les données doivent être extraites sont-ils identifiés? Est-ce l'expéditeur, le sujet, une chaîne dans le corps ou tout ça? Les commentaires aident à éliminer inintéressant e-mails. Si je comprends la question correctement, un email intéressant aura Subject = "Task Completed"
.
les commentaires n'aident pas à extraire des données de courriels intéressants, mais la feuille de travail montre les versions texte et html du corps du courriel si elles sont présentes. Mon idée est que vous pouvez voir ce que la macro verra et commencer à concevoir le processus d'extraction.
ceci n'est pas montré dans l'image d'écran ci-dessus mais la macro produit deux versions sur le corps du texte. La première version est inchangée, ce qui signifie que les tabulations, les retours de chariot, les lignes d'alimentation sont respectés et que les espaces non cassés ressemblent à des espaces. Dans la seconde version, j'ai remplacé ces codes par les chaînes [TB], [CR], [LF] et [NBSP] afin qu'ils soient visibles. Si mon interprétation est correcte, je m'attendrais à voir ce qui suit dans le second corps de texte:
Activity [TAB]Count[CR] [LF]Open [TAB]35[CR] [LF]HCQA [TAB]42 [CR] [LF]HCQC [TAB]60 [CR] [LF]HAbst [TAB]50 45 5 2 2 1[CR] [LF] and so
Extraire les valeurs de l'original de cette chaîne ne devrait pas être difficile.
j'essaierais de modifier ma macro pour afficher les valeurs extraites en plus des propriétés de l'email. Ce n'est que lorsque j'aurai réussi ce changement que j'essaierai d'écrire les données extraites dans un classeur existant. Je déplacerais également les e-mails traités dans un autre dossier. J'ai montré où ces changements doivent être faits mais ne donnent pas plus d'aide. Je vais répondre à une question supplémentaire si vous arrivez au point où vous avez besoin de ces informations.
Bonne chance.
dernière version de macro incluse dans le texte original
Option Explicit
Public Sub SaveEmailDetails()
' This macro creates a new Excel workbook and writes to it details
' of every email in the Inbox.
' Lines starting with hashes either MUST be changed before running the
' macro or suggest changes you might consider appropriate.
Dim AttachCount As Long
Dim AttachDtl() As String
Dim ExcelWkBk As Excel.Workbook
Dim FileName As String
Dim FolderTgt As MAPIFolder
Dim HtmlBody As String
Dim InterestingItem As Boolean
Dim InxAttach As Long
Dim InxItemCrnt As Long
Dim PathName As String
Dim ReceivedTime As Date
Dim RowCrnt As Long
Dim SenderEmailAddress As String
Dim SenderName As String
Dim Subject As String
Dim TextBody As String
Dim xlApp As Excel.Application
' The Excel workbook will be created in this folder.
' ######## Replace "C:\DataArea\SO" with the name of a folder on your disc.
PathName = "C:\DataArea\SO"
' This creates a unique filename.
' #### If you use a version of Excel 2003, change the extension to "xls".
FileName = Format(Now(), "yymmdd hhmmss") & ".xlsx"
' Open own copy of Excel
Set xlApp = Application.CreateObject("Excel.Application")
With xlApp
' .Visible = True ' This slows your macro but helps during debugging
.ScreenUpdating = False ' Reduces flash and increases speed
' Create a new workbook
' #### If updating an existing workbook, replace with an
' #### Open workbook statement.
Set ExcelWkBk = xlApp.Workbooks.Add
With ExcelWkBk
' #### None of this code will be useful if you are adding
' #### to an existing workbook. However, it demonstrates a
' #### variety of useful statements.
.Worksheets("Sheet1").Name = "Inbox" ' Rename first worksheet
With .Worksheets("Inbox")
' Create header line
With .Cells(1, "A")
.Value = "Field"
.Font.Bold = True
End With
With .Cells(1, "B")
.Value = "Value"
.Font.Bold = True
End With
.Columns("A").ColumnWidth = 18
.Columns("B").ColumnWidth = 150
End With
End With
RowCrnt = 2
End With
' FolderTgt is the folder I am going to search. This statement says
' I want to seach the Inbox. The value "olFolderInbox" can be replaced
' to allow any of the standard folders to be searched.
' See FindSelectedFolder() for a routine that will search for any folder.
Set FolderTgt = CreateObject("Outlook.Application"). _
GetNamespace("MAPI").GetDefaultFolder(olFolderInbox)
' #### Use the following the access a non-default Inbox.
' #### Change "Xxxx" to name of one of your store you want to access.
Set FolderTgt = Session.Folders("Xxxx").Folders("Inbox")
' This examines the emails in reverse order. I will explain why later.
For InxItemCrnt = FolderTgt.Items.Count To 1 Step -1
With FolderTgt.Items.Item(InxItemCrnt)
' A folder can contain several types of item: mail items, meeting items,
' contacts, etc. I am only interested in mail items.
If .Class = olMail Then
' Save selected properties to variables
ReceivedTime = .ReceivedTime
Subject = .Subject
SenderName = .SenderName
SenderEmailAddress = .SenderEmailAddress
TextBody = .Body
HtmlBody = .HtmlBody
AttachCount = .Attachments.Count
If AttachCount > 0 Then
ReDim AttachDtl(1 To 7, 1 To AttachCount)
For InxAttach = 1 To AttachCount
' There are four types of attachment:
' * olByValue 1
' * olByReference 4
' * olEmbeddedItem 5
' * olOLE 6
Select Case .Attachments(InxAttach).Type
Case olByValue
AttachDtl(1, InxAttach) = "Val"
Case olEmbeddeditem
AttachDtl(1, InxAttach) = "Ebd"
Case olByReference
AttachDtl(1, InxAttach) = "Ref"
Case olOLE
AttachDtl(1, InxAttach) = "OLE"
Case Else
AttachDtl(1, InxAttach) = "Unk"
End Select
' Not all types have all properties. This code handles
' those missing properties of which I am aware. However,
' I have never found an attachment of type Reference or OLE.
' Additional code may be required for them.
Select Case .Attachments(InxAttach).Type
Case olEmbeddeditem
AttachDtl(2, InxAttach) = ""
Case Else
AttachDtl(2, InxAttach) = .Attachments(InxAttach).PathName
End Select
AttachDtl(3, InxAttach) = .Attachments(InxAttach).FileName
AttachDtl(4, InxAttach) = .Attachments(InxAttach).DisplayName
AttachDtl(5, InxAttach) = "--"
' I suspect Attachment had a parent property in early versions
' of Outlook. It is missing from Outlook 2016.
On Error Resume Next
AttachDtl(5, InxAttach) = .Attachments(InxAttach).Parent
On Error GoTo 0
AttachDtl(6, InxAttach) = .Attachments(InxAttach).Position
' Class 5 is attachment. I have never seen an attachment with
' a different class and do not see the purpose of this property.
' The code will stop here if a different class is found.
Debug.Assert .Attachments(InxAttach).Class = 5
AttachDtl(7, InxAttach) = .Attachments(InxAttach).Class
Next
End If
InterestingItem = True
Else
InterestingItem = False
End If
End With
' The most used properties of the email have been loaded to variables but
' there are many more properies. Press F2. Scroll down classes until
' you find MailItem. Look through the members and note the name of
' any properties that look useful. Look them up using VB Help.
' #### You need to add code here to eliminate uninteresting items.
' #### For example:
'If SenderEmailAddress <> "JohnDoe@AcmeSoftware.co.zy" Then
' InterestingItem = False
'End If
'If InStr(Subject, "Accounts payable") = 0 Then
' InterestingItem = False
'End If
'If AttachCount = 0 Then
' InterestingItem = False
'End If
' #### If the item is still thought to be interesting I
' #### suggest extracting the required data to variables here.
' #### You should consider moving processed emails to another
' #### folder. The emails are being processed in reverse order
' #### to allow this removal of an email from the Inbox without
' #### effecting the index numbers of unprocessed emails.
If InterestingItem Then
With ExcelWkBk
With .Worksheets("Inbox")
' #### This code creates a dividing row and then
' #### outputs a property per row. Again it demonstrates
' #### statements that are likely to be useful in the final
' #### version
' Create dividing row between emails
.Rows(RowCrnt).RowHeight = 5
.Range(.Cells(RowCrnt, "A"), .Cells(RowCrnt, "B")) _
.Interior.Color = RGB(0, 255, 0)
RowCrnt = RowCrnt + 1
.Cells(RowCrnt, "A").Value = "Sender name"
.Cells(RowCrnt, "B").Value = SenderName
RowCrnt = RowCrnt + 1
.Cells(RowCrnt, "A").Value = "Sender email address"
.Cells(RowCrnt, "B").Value = SenderEmailAddress
RowCrnt = RowCrnt + 1
.Cells(RowCrnt, "A").Value = "Received time"
With .Cells(RowCrnt, "B")
.NumberFormat = "@"
.Value = Format(ReceivedTime, "mmmm d, yyyy h:mm")
End With
RowCrnt = RowCrnt + 1
.Cells(RowCrnt, "A").Value = "Subject"
.Cells(RowCrnt, "B").Value = Subject
RowCrnt = RowCrnt + 1
If AttachCount > 0 Then
.Cells(RowCrnt, "A").Value = "Attachments"
.Cells(RowCrnt, "B").Value = "Inx|Type|Path name|File name|Display name|Parent|Position|Class"
RowCrnt = RowCrnt + 1
For InxAttach = 1 To AttachCount
.Cells(RowCrnt, "B").Value = InxAttach & "|" & _
AttachDtl(1, InxAttach) & "|" & _
AttachDtl(2, InxAttach) & "|" & _
AttachDtl(3, InxAttach) & "|" & _
AttachDtl(4, InxAttach) & "|" & _
AttachDtl(5, InxAttach) & "|" & _
AttachDtl(6, InxAttach) & "|" & _
AttachDtl(7, InxAttach)
RowCrnt = RowCrnt + 1
Next
End If
If TextBody <> "" Then
' ##### This code was in the original version of the macro
' ##### but I did not find it as useful as the other version of
' ##### the text body. See below
' This outputs the text body with CR, LF and TB obeyed
'With .Cells(RowCrnt, "A")
' .Value = "text body"
' .VerticalAlignment = xlTop
'End With
'With .Cells(RowCrnt, "B")
' ' The maximum size of a cell 32,767
' .Value = Mid(TextBody, 1, 32700)
' .WrapText = True
'End With
'RowCrnt = RowCrnt + 1
' This outputs the text body with NBSP, CR, LF and TB
' replaced by strings.
With .Cells(RowCrnt, "A")
.Value = "text body"
.VerticalAlignment = xlTop
End With
TextBody = Replace(TextBody, Chr(160), "[NBSP]")
TextBody = Replace(TextBody, vbCr, "[CR]")
TextBody = Replace(TextBody, vbLf, "[LF]")
TextBody = Replace(TextBody, vbTab, "[TB]")
With .Cells(RowCrnt, "B")
' The maximum size of a cell 32,767
.Value = Mid(TextBody, 1, 32700)
.WrapText = True
End With
RowCrnt = RowCrnt + 1
End If
If HtmlBody <> "" Then
' ##### This code was in the original version of the macro
' ##### but I did not find it as useful as the other version of
' ##### the html body. See below
' This outputs the html body with CR, LF and TB obeyed
'With .Cells(RowCrnt, "A")
' .Value = "Html body"
' .VerticalAlignment = xlTop
'End With
'With .Cells(RowCrnt, "B")
' .Value = Mid(HtmlBody, 1, 32700)
' .WrapText = True
'End With
'RowCrnt = RowCrnt + 1
' This outputs the html body with NBSP, CR, LF and TB
' replaced by strings.
With .Cells(RowCrnt, "A")
.Value = "Html body"
.VerticalAlignment = xlTop
End With
HtmlBody = Replace(HtmlBody, Chr(160), "[NBSP]")
HtmlBody = Replace(HtmlBody, vbCr, "[CR]")
HtmlBody = Replace(HtmlBody, vbLf, "[LF]")
HtmlBody = Replace(HtmlBody, vbTab, "[TB]")
With .Cells(RowCrnt, "B")
.Value = Mid(HtmlBody, 1, 32700)
.WrapText = True
End With
RowCrnt = RowCrnt + 1
End If
End With
End With
End If
Next
With xlApp
With ExcelWkBk
' Write new workbook to disc
If Right(PathName, 1) <> "\" Then
PathName = PathName & "\"
End If
.SaveAs FileName:=PathName & FileName
.Close
End With
.Quit ' Close our copy of Excel
End With
Set xlApp = Nothing ' Clear reference to Excel
End Sub
Macros non inclus dans le post original mais que certains utilisateurs de la macro ci-dessus ont trouvé utile.
Public Sub FindSelectedFolder(ByRef FolderTgt As MAPIFolder, _
ByVal NameTgt As String, ByVal NameSep As String)
' This routine (and its sub-routine) locate a folder within the hierarchy and
' returns it as an object of type MAPIFolder
' NameTgt The name of the required folder in the format:
' FolderName1 NameSep FolderName2 [ NameSep FolderName3 ] ...
' If NameSep is "|", an example value is "Personal Folders|Inbox"
' FolderName1 must be an outer folder name such as
' "Personal Folders". The outer folder names are typically the names
' of PST files. FolderName2 must be the name of a folder within
' Folder1; in the example "Inbox". FolderName2 is compulsory. This
' routine cannot return a PST file; only a folder within a PST file.
' FolderName3, FolderName4 and so on are optional and allow a folder
' at any depth with the hierarchy to be specified.
' NameSep A character or string used to separate the folder names within
' NameTgt.
' FolderTgt On exit, the required folder. Set to Nothing if not found.
' This routine initialises the search and finds the top level folder.
' FindSelectedSubFolder() is used to find the target folder within the
' top level folder.
Dim InxFolderCrnt As Long
Dim NameChild As String
Dim NameCrnt As String
Dim Pos As Long
Dim TopLvlFolderList As Folders
Set FolderTgt = Nothing ' Target folder not found
Set TopLvlFolderList = _
CreateObject("Outlook.Application").GetNamespace("MAPI").Folders
' Split NameTgt into the name of folder at current level
' and the name of its children
Pos = InStr(NameTgt, NameSep)
If Pos = 0 Then
' I need at least a level 2 name
Exit Sub
End If
NameCrnt = Mid(NameTgt, 1, Pos - 1)
NameChild = Mid(NameTgt, Pos + 1)
' Look for current name. Drop through and return nothing if name not found.
For InxFolderCrnt = 1 To TopLvlFolderList.Count
If NameCrnt = TopLvlFolderList(InxFolderCrnt).Name Then
' Have found current name. Call FindSelectedSubFolder() to
' look for its children
Call FindSelectedSubFolder(TopLvlFolderList.Item(InxFolderCrnt), _
FolderTgt, NameChild, NameSep)
Exit For
End If
Next
End Sub
Public Sub FindSelectedSubFolder(FolderCrnt As MAPIFolder, _
ByRef FolderTgt As MAPIFolder, _
ByVal NameTgt As String, ByVal NameSep As String)
' See FindSelectedFolder() for an introduction to the purpose of this routine.
' This routine finds all folders below the top level
' FolderCrnt The folder to be seached for the target folder.
' NameTgt The NameTgt passed to FindSelectedFolder will be of the form:
' A|B|C|D|E
' A is the name of outer folder which represents a PST file.
' FindSelectedFolder() removes "A|" from NameTgt and calls this
' routine with FolderCrnt set to folder A to search for B.
' When this routine finds B, it calls itself with FolderCrnt set to
' folder B to search for C. Calls are nested to whatever depth are
' necessary.
' NameSep As for FindSelectedSubFolder
' FolderTgt As for FindSelectedSubFolder
Dim InxFolderCrnt As Long
Dim NameChild As String
Dim NameCrnt As String
Dim Pos As Long
' Split NameTgt into the name of folder at current level
' and the name of its children
Pos = InStr(NameTgt, NameSep)
If Pos = 0 Then
NameCrnt = NameTgt
NameChild = ""
Else
NameCrnt = Mid(NameTgt, 1, Pos - 1)
NameChild = Mid(NameTgt, Pos + 1)
End If
' Look for current name. Drop through and return nothing if name not found.
For InxFolderCrnt = 1 To FolderCrnt.Folders.Count
If NameCrnt = FolderCrnt.Folders(InxFolderCrnt).Name Then
' Have found current name.
If NameChild = "" Then
' Have found target folder
Set FolderTgt = FolderCrnt.Folders(InxFolderCrnt)
Else
'Recurse to look for children
Call FindSelectedSubFolder(FolderCrnt.Folders(InxFolderCrnt), _
FolderTgt, NameChild, NameSep)
End If
Exit For
End If
Next
' If NameCrnt not found, FolderTgt will be returned unchanged. Since it is
' initialised to Nothing at the beginning, that will be the returned value.
End Sub