I'm trying to pull information from Outlook into an Excel spreadsheet using VBA.
I cannot pull the ticket number column data. The ticket number is a user-defined field.
Outlook email columns:
Excel spreadsheet:
For Each objItem In myFolder.Items
Set objMail = objItem
Cells(iRows, 1) = objMail.SenderEmailAddress
Cells(iRows, 2) = objMail.Subject
Cells(iRows, 3) = objMail.ReceivedTime
Cells(iRows, 4) = objMail.body
Cells(iRows, 5) = objMail.Categories
Cells(iRows, 6) = objMail.ItemProperties("Ticket Number").Value
inc = inc + 1
End If
iRows = iRows + 1
First of all, Outlook folders may contain different item types - mails, appointments, documents and etc. So, in the loop you need to check whether you deal with a mail item or not before accessing any MailItem-specific properties.
For Each objItem In myFolder.Items
If objItem.Class = olMail Then
The MailItem.ItemProperties property returns an ItemProperties collection that represents all standard and user-defined properties associated with the Outlook item.
'Create a reference to the email item's properties collection.
Set objItems = objMail.ItemProperties
So, you can iterate over all items in the collection to make sure the required property exists. So, if you find the property you can then ask for the Value.
Related
Background: Working on a project to pull information from Outlook emails into an Excel sheet using VBA.
Problem: I'm able to get all of the values but Ticket Number. The ticket number is a custom column heading we created.
Code source: https://www.encodedna.com/excel/how-to-parse-outlook-emails-and-show-in-excel-worksheet-using-vba.htm
For Each objItem In myFolder.Items
If objItem.Class = olMail Then
Dim objMail As Outlook.MailItem
Set objMail = objItem
Cells(iRows, 1) = objMail.SenderEmailAddress
Cells(iRows, 2) = objMail.Subject
Cells(iRows, 3) = objMail.ReceivedTime
Cells(iRows, 4) = objMail.body
Cells(iRows, 5) = objMail.Categories
Cells(iRows, 6) = objMail.ticketnumber
End If
iRows = iRows + 1
Next
Variations I tried:
ObjectMail.ticketnumber
ObjectMail.TicketNumber
ObjectMail.ticket_Number
You can try looking in the UserProperties collection. The corresponding property returns the UserProperties collection that represents all the user properties for the Outlook item. The UserProperties.Find method locates and returns a UserProperty object for the requested property name, if it exists. Here is what MSDN states:
If you use Find to look for a custom property and the call succeeds, it returns a UserProperty object. If it fails, it returns Null (Nothing in Visual Basic).
If you use Find to look for a built-in property, specify False for the Custom parameter. If the call succeeds, it returns the property as a UserProperty object. If the call fails, it returns Null (Nothing in Visual Basic). If you specify True for Custom, the call does not find the built-in property and returns Null (Nothing in Visual Basic).
Also you may check the transport message headers to make sure such property exists (PR_TRANSPORT_MESSAGE_HEADERS):
propertyAccessor.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x007D001E")
Try:
objMail.ItemProperties("TicketNumber").Value
Overview of ItemProperties/UserProperties:
https://learn.microsoft.com/en-us/office/vba/outlook/how-to/navigation/properties-overview
I tried to extract the data from an Outlook email using VBA:
Sub DLPExtract()
Dim OutlookApp As Outlook.Application
Dim OutlookNamespace As Namespace
Dim Folder As MAPIFolder
Dim OutlookMail As MailItem
Dim i As Integer
Set OutlookApp = New Outlook.Application
Set OutlookNamespace = OutlookApp.GetNamespace("MAPI")
Set Folder = OutlookNamespace.GetDefaultFolder(olFolderInbox).Folders("gfdo#aviva.com\Inbox")
i = 1
For Each OutlookMail In Folder.Items
If InStr(OutlookMail.Subject, "Data Loss Prevention Report: GFDO DLP Daily Report Retrospective") > 0 And OutlookMail.ReceivedTime >= Range("From_date").Value Then
Range("Date").Offset(i, 0).Value = OutlookMail.Date
Range("Type").Offset(i, 0).Value = OutlookMail.
Range("Reference").Offset(i, 0).Value = OutlookMail.ID
Range("eMail_text").Offset(i, 0).Value = OutlookMail.Body
i = i + 1
End If
Next OutlookMail
Set Folder = Nothing
Set OutlookNamespace = Nothing
Set OutlookApp = Nothing
End Sub
I want to extract only IDs in the fourth column but first need to check if that is already in the respective column on Excel sheet. If yes, do nothing and If no, then take that ID out from this fourth column in email and paste it in respective column on Excel sheet.
I believe you are trying to check the email body format.
If that is the case then follow this link which talks about the "Bodyformat" property.
Range("Type").Offset(i, 0).Value = OutlookMail.BodyFormat
It is not clear what "Type" property you are interested in - the Outlook object model doesn't provide the Type property for their items. Instead, you may be interested in the MessageClass property which returns or sets a string representing the message class for the Outlook item. The MessageClass property links the item to the form on which it is based. When an item is selected, Outlook uses the message class to locate the form and expose its properties, such as Reply commands.
Also you may be interested in the BodyFormat property which returns or sets an OlBodyFormat constant indicating the format of the body text. The body text format determines the standard used to display the text of the message. Microsoft Outlook provides three body text format options: Plain Text, Rich Text (RTF), and HTML.
Finally, there is no need to iterate over all items in the folder and checking whether they correspond to the predefined condition:
For Each OutlookMail In Folder.Items
If InStr(OutlookMail.Subject, "Data Loss Prevention Report: GFDO DLP Daily Report Retrospective") > 0 And OutlookMail.ReceivedTime >= Range("From_date").Value Then
Instead, I'd recommend using the Find/FindNext or Restrict methods of the Items class. Read more about them in the following articles:
How To: Use Find and FindNext methods to retrieve Outlook mail items from a folder (C#, VB.NET)
How To: Use Restrict method to retrieve Outlook mail items from a folder
I have a UserForm with information and botton. When I click on "Demander Attest." (cbAskAttestation), which you can see here:
this prepares me an email:
However, how to replace the data in a matrix of an email with those in the text box of a user form? I would like to replace the texts in the right column of the email table with the ones in the userform. For example, replace "GRADE" in the email with SAP.
Annex
The data in the UserForm ufReservistInformations comes from this code:
Sheets("RECAP").Cells(Lig, 2) = cboFunction
Sheets("RECAP").Cells(Lig, 5) = cboSexReservist
Sheets("RECAP").Cells(Lig, 6) = cboRankReservist
Sheets("RECAP").Cells(Lig, 7) = txtIncorporationNumberReservist
Sheets("RECAP").Cells(Lig, 8) = txtBsnReservist
Sheets("RECAP").Cells(Lig, 9) = txtBirthdateReservist
Sheets("RECAP").Cells(Lig, 10) = txtAgeReservist
Sheets("RECAP").Cells(Lig, 11) = txtBirthplaceReservist
Sheets("RECAP").Cells(Lig, 12) = txtAddressReservist
Sheets("RECAP").Cells(Lig, 13) = txtZipcodeReservist
Sheets("RECAP").Cells(Lig, 15) = txtPhoneReservist
Sheets("RECAP").Cells(Lig, 17) = txtEmailReservist
Sheets("RECAP").Cells(Lig, 18) = txtContactReservist
Sheets("RECAP").Cells(Lig, 19) = txtJobReservist
Sheets("RECAP").Cells(Lig, 20) = txtEsrReservist
Sheets("RECAP").Cells(Lig, 21) = cboLengthContractReservist
Sheets("RECAP").Cells(Lig, 22) = txtEndEsrReservist
Sheets("RECAP").Cells(Lig, 23) = cboSav1Reservist
Sheets("RECAP").Cells(Lig, 24) = txtSav1CommentReservist
Sheets("RECAP").Cells(Lig, 25) = txtRetrainingReservist
Sheets("RECAP").Cells(Lig, 26) = txtFmaChiefReservist
Sheets("RECAP").Cells(Lig, 27) = txtVsaReservist
Sheets("RECAP").Cells(Lig, 28) = txtNextVsaReservist
And I create an email of the following template:
Sub CreateEmailfromTemplate(ByVal email As String, ByVal pathToTemplate As String)
Dim obApp As Object
Dim NewMail As Outlook.MailItem
Set obApp = Outlook.Application
'Change the template file folder path according to your case
Set NewMail = obApp.CreateItemFromTemplate(pathToTemplate)
With NewMail
.To = email
End With
NewMail.Display
Set obApp = Nothing
Set NewMail = Nothing
End Sub
Attempt with RobertBaron's answer described below
I tried to use Replace function.
Dim obApp As Object
Dim NewMail As Outlook.MailItem
Set obApp = Outlook.Application
'Change the template file folder path according to your case
Set NewMail = obApp.CreateItemFromTemplate("\\bspp.fr\Travail\CCL1\MTMA\Groupe Adjudant de Compagnie\RESERVISTES\CORRESPONDANCE\Demande d'attestation de recyclage.msg")
With NewMail
mailBody = .Body
End With
mailBody = Replace(mailBody, "1cl", cboRankReservist)
With NewMail
.Body = mailBody
End With
NewMail.Display
Set obApp = Nothing
Set NewMail = Nothing
Yet the results don't keep the array and renders a column of words. Indeed here are the results just after using mailBody = Replace(mailBody, "1cl", cboRankReservist)
Bonjour,
J’ai l’honneur de vous demander une attestation de formation continue équipier-secouriste pour le personnel suivant :
Groupement
1 GIS
Compagnie
20
N° incorporation
91109
Grade
1cl
...
After this line has executed, NewMail contains a MailItem.
Set NewMail = obApp.CreateItemFromTemplate(pathToTemplate)
You can use the Body property to get the contents of the email as created by the template, change the contents, and set the Body property to the new contents. To set the values you want in the templated email, you can use the VBA Replace function, to replace "Numero ?", "Grade ?", etc., by their desired values.
There are three main ways for working with bodies in Outlook:
Body.
HTMLBody.
The Inspector class provides the WordEditor property which returns an instance of the Document class from the Word object model which represents the message body. Outlook uses Word as an email editor.
You can read more about that in the Chapter 17: Working with Item Bodies article.
It is up to you which way is to choose. But I think Word may help in this scenario. To use these techniques in Outlook VBA code, use the Tools | References command to add a reference to the Microsoft Word Object Library.
I am trying to get all the recipients "list of people in TO: .. section" of an outlook appointment that I select.
I need the subject and and the recipients of all the selected appointments, I could get the subject but am not able to get the recipients. Below is the code I tried..
Sub testCode()
Dim objItem As Object
Dim objApp As Outlook.Application
Set objApp = Application
Set xlApp = CreateObject("Excel.Application")
xlApp.Application.Visible = True
xlApp.workbooks.Open "C:\data.xlsm"
For i = 1 To 49
Set objItem = objApp.ActiveExplorer.Selection.Item(i)
xlApp.Range("A" & i & "").Value = objItem.Subject
xlApp.Range("B" & i & "").Value = objItem.To // not working
Next i
End Sub
There is no To field in an appointment. There are required attendees and optional attendees.
Use these properties:
objItem.OptionalAttendees
and
objItem.RequiredAttendees
As a sidenote, the easiest way to figure out things like this is to examine the object in the locals window of the code window while stepping through the code. This way you can see all of the properties that the object has and figure out what to use.
Use the AppointmentItem.Recipients collection and loop through all recipients. Recipient.Type = olTo are required, olCC - optional, olBCC - resources.
I am using the following vba code which should search for all emails with a specific subject title i.e. with the subject 'test'
Then only if the email is unread then save the attachment from that email into a folder.
There may be one or several emails with the subject test so I want all the unread emails with the subject test to have their attachments saved to the folder.
Here is my code:
Sub Work_with_Outlook()
Set olApp = CreateObject("Outlook.Application")
Dim olNs As Outlook.Namespace
Dim Fldr As Outlook.MAPIFolder
Dim myItem As Object
Dim myAttachment As Outlook.Attachment
Dim I As Long
Dim olMail As Variant
Set olApp = New Outlook.Application
Set olNs = olApp.GetNamespace("MAPI")
Set Fldr = olNs.GetDefaultFolder(olFolderInbox)
Set myTasks = Fldr.Items
Set UnRead = myTasks.Restrict("[UnRead] = False")
Set olMail = myTasks.Find("[Subject] = ""test""")
If Not (olMail Is Nothing) And UnRead.Count = 0 Then
For Each myItem In myTasks
If myItem.Attachments.Count <> 0 Then
For Each myAttachment In myItem.Attachments
If InStr(myAttachment.DisplayName, ".txt") Then
I = I + 1
myAttachment.SaveAsFile "\\uksh000-file06\Purchasing\NS\Unactioned\" & myAttachment
End If
Next
End If
Next
For Each myItem In myTasks
myItem.UnRead = False
Next
MsgBox "Scan Complete."
Else
MsgBox "There Are No New Supplier Requests."
End If
End Sub
This does work to some degree, if I only have one email with the subject 'test' and it is unread then the script will get the attachment from that email and save it to my folder. However, if I have one email with the subject 'test' which is read and another email with the subject 'test' which is unread then the code won't work?
Please can someone show me where I am going wrong? Thanks in advance
It looks like you need to combine both comditions into a single one and use the Find/FindNext or Restrict methods to get an instance of the Items class which contains all items correspodning to your conditons. For example:
Set resultItems = myTasks.Restrict("[UnRead] = False AND [Subject] = ""test""")
See Enumerating, Searching, and Filtering Items in a Folder for information in MSDN.
Also you may find the sample code in the following articles:
How To: Use Find and FindNext methods to retrieve Outlook mail items from a folder (C#, VB.NET)
How To: Use Restrict method to retrieve Outlook mail items from a folder
How To: Get unread Outlook e-mail items from the Inbox folder
Advanced search in Outlook programmatically: C#, VB.NET