Return custom Outlook property value - vba

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

Related

MS Access VBA code to send an Outlook email

I am trying to get Access to send a simple email programatically. I have added the Outlook 16.0 reference. Below is the code. When it gets to the With oMail part, it returns an error: "Application-defined of object-defined error."
It errors on the .ReplyRecipients.Add line. If I comment out that line, then it errors on the .Send line.
Note I am running the TestSend() sub to activate the SendEmailOutlook sub.
Sub TestSend()
Call SendEmailOutlook("myemail#email.com", "Test message", "Test message.")
End Sub
Public Sub SendEmailOutlook(strTo As String, strSubject As String, strBody As String)
On Error GoTo SendEmailOutlookErr
Dim strEmail As String
Dim strMsg As String
Dim oLook As Object
Dim oMail As Object
Set oLook = CreateObject("Outlook.Application")
Set oMail = oLook.createitem(0)
With oMail
.ReplyRecipients.Add "myemail#email.com"
.to = strTo
.htmlbody = strBody
.Subject = strSubject
.Send
End With
Set oMail = Nothing
Set oLook = Nothing
Exit Sub
SendEmailOutlookErrExit:
Exit Sub
SendEmailOutlookErr:
MsgBox Err.Description, vbOKOnly, Err.Source & ":" & Err.Number
Resume SendEmailOutlookErrExit
End Sub
In the code the late binding technology is used, so the COM reference is optional. But if you have already added the Outlook COM refence you may declare all Outlook objects instead of just having the object in the declaration. It can help. Read more about the late and early binding in the Using early binding and late binding in Automation article.
Also the following line of code contains multiple property and method calls:
With oMail
.ReplyRecipients.Add "myemail#email.com"
The code is valid. But it makes sense to declare each property or method on a separate line of code, so you could easily find the faulting one - where exactly the error occurs.
The MailItem.ReplyRecipients property returns a Recipients collection that represents all the reply recipient objects for the Outlook item. Use the Add method to create a new Recipient object and add it to the Recipients object. The Type property of a new Recipient object is set to the default for the associated AppointmentItem, JournalItem, MailItem, or TaskItem object and must be reset to indicate another recipient type.
Set myItem = Application.CreateItem(olMailItem)
Set myRecipient = myItem.Recipients.Add ("Jon Grande")
myRecipient.Type = olCC
Another aspect is how Outlook has been configured to trust applications on a client computer, an application that uses the Outlook object model to access certain data or execute certain actions can invoke security warnings or throw errors when Outlook is automated without any UI. Depending on the type of information or action that the program was attempting to access or execute, there are three different security prompts that applications can invoke through the Object Model Guard: the address book warning, send message warning, and execute action warning. Read more about that in the Outlook Object Model Security Warnings article.

How to return Outlook email custom property?

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.

How to extract "type" - Email or Web from an Outlook Email using VBA?

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

VBA Excel create Outlook 2013 Appointment

I am trying to create an Outlook Appointment with a Macro, I am having an issue with the code giving me an error of "Object Doesn't support this property or method" when it comes the Default Appointment Values. I have tried several fixes but am not experienced enough to resolve. Any assistance is greatly appreciated.
Here is what I am working with:
Sub CalendarInvite()
Dim olApp As Object
Dim olAppItem As Object
Dim r As Long
Set olApp = GetObject("", "Outlook.Application")
Dim mysub, myStart, myEnd
mysub = Range("Title")
myStart = Range("Date")
myEnd = Range("Date")
'creates a new appointment
Set olAppItem = olApp.CreateItem(olAppointmentItem)
'set default appointment values
With olAppItem
.Location = Range("Location")
.Body = Range("Body")
.ReminderSet = True
.BusyStatus = olFree
.RequiredAttendees = "email#email.com"
'saves the new appointment to the default folder
.Save
End With
Set olAppItem = Nothing
Set olApp = Nothing
End Sub
Set olAppItem = olApp.CreateItem(olAppointmentItem)
Assuming you're late-binding the Outlook library, the constant olAppointmentItem is not defined, so if you specify Option Explicit at the top of the module the VBE will highlight if as undeclared.
I copied your code into ThisWorkbook in an empty workbook, and ran Rubberduck code inspections (disclaimer: I manage that open-source project; it's completely free, and it's improving every day).
These results are particularly relevant to your problem:
Error: Option Explicit is not specified in 'ThisWorkbook' - (Book3) VBAProject.ThisWorkbook, line 1
Error: Variable 'olAppointmentItem' is used but not assigned - (Book3) VBAProject.ThisWorkbook, line 16
Error: Variable 'olFree' is used but not assigned - (Book3) VBAProject.ThisWorkbook, line 23
Error: Local variable 'olAppointmentItem' is not declared - (Book3) VBAProject.ThisWorkbook, line 16
Error: Local variable 'olFree' is not declared - (Book3) VBAProject.ThisWorkbook, line 23
The underlying value of olFree in the Outlook library is 0, so that's not a big deal as far as run-time errors are concerned.
However olAppointmentItem not being defined is pretty big: you think you're working against an AppointmentItem object, but because the underlying value of olAppointmentItem in the Outlook library is 1 and you're providing a 0, the runtime type of olAppItem is actually a MailItem.
And because a MailItem doesn't have a Location property, attempting to set it will raise that run-time error 438 you're getting - "object doesn't support this property or method".
Therefore, you should be creating the olAppItem like this:
Set olAppItem = olApp.CreateItem(1)
Or, define the olAppointmentItem constant:
Const olAppointmentItem As Long = 1
Set olAppItem = olApp.CreateItem(olAppointmentItem)
Or, reference the Outlook object model (Tools > References...), replace As Object with the actual types you want to be using (olApp As Outlook.Application, olAppItem As AppointmentItem), and then the olAppointmentItem and olFree constants will be taken from the Outlook library.
I'll skip the other inspection results because they're not relevant to that specific question, but you'll notice a number of dead variables there.
If you want to create an appointment in Outlook, using Excel, run the script below.
Private Sub Add_Appointments_To_Outlook_Calendar()
'Include Microsoft Outlook nn.nn Object Library from Tools -> References
Dim oAppt As AppointmentItem
Dim Remind_Time As Double
i = 2
Subj = ThisWorkbook.Sheets(1).Cells(i, 1)
'Loop through entire list of Reminders to be added
While Subj <> ""
Set oAppt = Outlook.Application.CreateItem(olAppointmentItem)
oAppt.Subject = Subj
oAppt.Location = ThisWorkbook.Sheets(1).Cells(i, 2)
oAppt.Start = ThisWorkbook.Sheets(1).Cells(i, 3)
Remind_Time = ThisWorkbook.Sheets(1).Cells(i, 4) * 1 * 60
oAppt.ReminderMinutesBeforeStart = Remind_Time
oAppt.AllDayEvent = True
oAppt.Save
i = i + 1
Subj = ThisWorkbook.Sheets(1).Cells(i, 1)
Wend
MsgBox "Reminder(s) Added To Outlook Calendar"
End Sub
' The code comes from this link:
http://officetricks.com/add-appointment-to-outlook-calendar-through-excel-macro-vba/
The script is run from Excel, and as such, you must set a reference to Outlook before you run the code. Also, notice that the worksheet needs to be setup properly for the script to run. It should look something like this. Everything is read from Excel into Outlook.

Outlook VBA-- Some MailItem Properties return values, others do not

EDIT: New info: I just now realised that, while the return of Mailitem.Body is "", the actual value is "Application-defined or object-defined error" . I'm not entirely sure what that means, but I do know it shows up in multiple fields-- I included a screen shot below.
I am having an issue where certain properties will return the correct value, and others will not. I have an example email, where I have an email with subject "Subject", the message is "Body", the sender email address is "email#address.com", and the date sent is 12 June 2013.
When I run the following code:
Dim ComputerName As String
Dim ErrorState As String
For Each MailItem In InboxItems
ComputerName = MailItem.Subject
'ErrorState = MailItem.Body
ErrorState = MailBody(MailItem)
strDate = GetDate(MailItem.SentOn)
SenderEmail = MailItem.SenderEmailAddress
If strDate = DateToday And SenderEmail = "email#address.com" Then
Computers(a, 0) = ComputerName
Computers(a, 1) = ErrorState
a = a + 1
End If
Debug.Print MailItem.Subject
Debug.Print MailItem.Body
Next MailItem
What I get is ComputerName = "Subject", ErrorState = "", SenderEmail = "", and strDate = "2013/6/12" (which is the proper format in this case). Why would this return proper values for two of the Mailitem properties, but not for two of the others? This is a very strange problem, and I would appreciate any help you all might be able to give!
I will add more of the context for the code here:
Set objOutlook = CreateObject("Outlook.Application", "localhost")
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set Inbox = GetFolder("email#address.org/inbox")
Set InboxItems = Inbox.Items
InboxItems.SetColumns ("SentOn")
GetFolder is a function to get the mailbox by folder path. I have to do this because I am not using the default inbox in outlook.
I also tried using the MailBody Function proposed below, in case the body were in an HTML or RTF format. Unfortunately, it proved that the body was normal, and MailItem.Body should have retrieved it, and it still is not working. MailItem.Body returns "", even though I know that the email has a body. The body is just the number 1, and that is what I should be getting.
Also, I should note that the sender of the email is the same as the recipient; in other words, the email was sent from one email address to itself. I don't know if this could make a difference, but I figured that I would put it out there just in case.
Multiple Item Types
First, there is no guarantee that all items in the Inbox.Items collection are of type MailItem. Inboxes also contain AppointmentItem, MeetingItem, and other *Item type objects. Not all of these item types have the same properties populated. To ensure you do not get a type mismatch error, declare your iterator variable as a generic Object and only assign it to a strongly-typed MailItem variable if it is of the correct type:
Dim oInbox As Outlook.Folder
Dim oItem As Object
Dim oMailItem As MailItem
Set oInbox = ActiveExplorer.Session.DefaultStore.GetRootFolder().Folders("Inbox")
For Each oItem In oInbox.Items
If TypeOf oItem Is MailItem Then
Set oMailItem = oItem
' Do stuff
Else
Debug.Print "Skipping " & TypeName(oItem)
End If
Next
Optional properties
Second, there is no gaurantee that all properties of an object will be populated. If a mail item was never sent, it will have no sender address, and certainly it is possible to have an email with no body. A good way to get familiar with which properties are available and what they contain is to use the Locals window (View > Locals Window in the VBA IDE). Here's a screen shot of the above code paused in the loop, with some of the properties of the oMailItem object expanded:
Body vs. HTMLBody
MailItem objects have three body properties: Body, HTMLBody, and RTFBody. Usually only one of them is populated. Which one depends on the format of the email. You can check the BodyFormat property to find which one is applicable to the current item. Using that, here's a generalized way to get the raw body of a MailItem, no matter what the format:
Public Function MailBody(ByVal MailItem As MailItem) As String
Select Case MailItem.BodyFormat
Case OlBodyFormat.olFormatPlain, OlBodyFormat.olFormatUnspecified
MailBody = MailItem.Body
Case OlBodyFormat.olFormatHTML
MailBody = MailItem.HTMLBody
Case OlBodyFormat.olFormatRichText
MailBody = MailItem.RTFBody
End Select
End Function