With the below code I'm getting an error when I try to add an attachment file name to the report. Perhaps it is the syntax?
The error is occurring at Report = Report & currentItem.Attachments.FileName line
The error is "object doesn't support this property or method.
Any ideas?
I am running this code in Outlook,
Private Sub GetAllEmailsInFolder(CurrentFolder As Outlook.Folder, Report As String)
Dim currentItem
Dim attachment As attachment
Dim currentMail As MailItem
Report = Report & "Folder Name: " & CurrentFolder.Name & " (Store: " & CurrentFolder.Store.DisplayName & ")" & vbCrLf
For Each currentItem In CurrentFolder.Items
Report = Report & currentItem.Subject
Report = Report & vbCrLf
Report = Report & "----------------------------------------------------------------------------------------"
Report = Report & vbCrLf
Report = Report & currentItem.Attachments.FileName
Next
End Sub
Also, I first run a sub that gets a list of emails:
Public Sub GetListOfEmails()
'On Error GoTo On_Error
Dim Session As Outlook.NameSpace
Dim Report As String
Dim Folder As Outlook.Folder
Set Session = Application.Session
Set Folder = Application.ActiveExplorer.CurrentFolder
Call GetAllEmailsInFolder(Folder, Report)
Dim retValue As Boolean
retValue = CreateReportAsEmail("List of Emails", Report)
Exiting:
Set Session = Nothing
Exit Sub
On_Error:
MsgBox "error=" & Err.Number & " " & Err.Description
Resume Exiting
End Sub
Then here is the sub I use to create the report in the form of an email I want to copy into excel.
Public Function CreateReportAsEmail(Title As String, Report As String)
'On Error GoTo On_Error
Dim Session As Outlook.NameSpace
Dim mail As MailItem
Dim MyAddress As AddressEntry
Dim Inbox As Outlook.Folder
CreateReportAsEmail = True
Set Session = Application.Session
Set Inbox = Session.GetDefaultFolder(olFolderInbox)
Set mail = Inbox.Items.Add("IPM.Mail")
Set MyAddress = Session.CurrentUser.AddressEntry
mail.Recipients.Add (MyAddress.Address)
mail.Recipients.ResolveAll
mail.Subject = Title
mail.Body = Report
mail.Save
mail.Display
Exiting:
Set Session = Nothing
Exit Function
On_Error:
CreateReportAsEmail = False
MsgBox "error=" & Err.Number & " " & Err.Description
Resume Exiting
End Function
The Attachments collection does not have a Filename property, but each individual Attachment does. Add an additional loop through the Attachments collection.
GetAllEmailsInFolder should be a Function returning a String. A Sub does something; a Function returns something.
GetAllEmailsInFolder assumes that all the items within CurrentFolder are MailItems, which might not be the case.
Use a different variable name than attachment for each Attachment. Same goes for Folder, Session...
Untested, but something like this:
Private Function GetAllEmailsInFolder(CurrentFolder As Outlook.Folder) As String
Dim currentItem As Object
Dim myAttachment As Attachment
Dim Report as String
Report = Report & "Folder Name: " & CurrentFolder.Name & " (Store: " & CurrentFolder.Store.DisplayName & ")" & vbCrLf
For Each currentItem In CurrentFolder.Items
If TypeOf currentItem Is Outlook.MailItem Then
Report = Report & currentItem.Subject
Report = Report & vbCrLf
Report = Report & "----------------------------------------------------------------------------------------"
Report = Report & vbCrLf
For Each myAttachment in currentItem.Attachments
Report = Report & myAttachment.Filename ' and add formatting inbetween as needed
Next myAttachment
End If
Next currentItem
GetAllEmailsInFolder = Report
End Sub
Here is quick Example, you may need to adjust little on how it displays on email.
For Each currentItem In CurrentFolder.Items
Report = Report & currentItem.Subject
Report = Report & vbCrLf
Report = Report & "--------------------------------------------------------"
Report = Report & vbCrLf
' Report = Report & currentItem.Attachments.FileName
For Each attachment In currentItem.Attachments
Debug.Print attachment.FileName
Report = Report & attachment.FileName
Next
Next
MSDN Attachment Object (Outlook)
Related
I have a Macro that works inconsistently and it is unable to run without an error occuring at some stage. It works without any problem for days but then doesn't, seemingly without reason. I change nothing, do not do anything different and am curious as to the fickleness of VBA/macros only having been dealing with them for some weeks now. An error is generated in those instances that it doesn't run as expected.
Error :object doesn't support this property or method
--despite the option of caption being generated on the insertion of .
Sub SnoozedReminders()
Dim oReminder As Reminder
Dim oReminders As Outlook.Reminders
Dim RemItems As String
Set oReminders = Outlook.Reminders
For Each oReminder In oReminders
If (oReminder.OriginalReminderDate <> oReminder.NextReminderDate)
Then
RemItems = RemItems & oReminder.Caption & vbCrLf & _
"Original Reminder time: " & oReminder.OriginalReminderDate & vbCrLf
& _
"Snoozed to: " & oReminder.NextReminderDate & vbCrLf _
& vbCrLf
End If
Next oReminder
Set oMail = Application.CreateItem(olMailItem)
oMail.Subject = "Generated on " & Now
oMail.Body = RemItems
oMail.Display
End Sub
In the code you are trying to set a type to the object:
Set oReminders = Outlook.Reminders
Instead, you need to use the following code which uses the Reminders property of the Outlook Application class:
Set oReminders = Application.Reminders
For example, the following code gets the Reminders collection and displays the captions of all reminders in the collection. If no current reminders are available, a message is displayed to the user.
Sub ViewReminderInfo()
'Lists reminder caption information
Dim objRem As Outlook.Reminder
Dim objRems As Outlook.Reminders
Dim strTitle As String
Dim strReport As String
Set objRems = Application.Reminders
strTitle = "Current Reminders:"
strReport = ""
'If there are reminders, display message
If Application.Reminders.Count <> 0 Then
For Each objRem In objRems
'Add information to string
strReport = strReport & objRem.Caption & vbCr
Next objRem
'Display report in dialog
MsgBox strTitle & vbCr & vbCr & strReport
Else
MsgBox "There are no reminders in the collection."
End If
End Sub
I have no VBA knowledge but am on a passage of learning. I have obtained the following coding from a public source (Diane Peremsky) of outlook forums. It has a bug I am working on to resolve and strangely returns different data on successive iterations.
Could somebody try provide (or guide me) to add the first 3 lines of the message body to which it refers?
Sub SnoozedReminders()
Dim oReminder As Reminder
Dim oReminders As Outlook.Reminders
Dim RemItems As String
Set oReminders = Outlook.Reminders
For Each oReminder In oReminders
If (oReminder.OriginalReminderDate <> oReminder.NextReminderDate) Then
RemItems = RemItems & oReminder.Caption & vbCrLf & _
"Original Reminder time: " & oReminder.OriginalReminderDate & vbCrLf & _
"Snoozed to: " & oReminder.NextReminderDate & vbCrLf _
& vbCrLf
End If
Next oReminder
Set oMail = Application.CreateItem(olMailItem)
oMail.Subject = "Generated on " & Now
oMail.Body = RemItems
oMail.Display
End Sub
The Reminder.Item property returns a corresponding Outlook item. So, you may get the message body from there.
Sub SnoozedReminders()
Dim oReminder As Reminder
Dim oReminders As Outlook.Reminders
Dim RemItems As String
Set oReminders = Outlook.Reminders
For Each oReminder In oReminders
If (oReminder.OriginalReminderDate <> oReminder.NextReminderDate) Then
RemItems = RemItems & oReminder.Caption & vbCrLf & "Original Reminder time: " &
oReminder.OriginalReminderDate & vbCrLf & "Snoozed to: " & oReminder.NextReminderDate & vbCrLf
& vbCrLf
End If
MsgBox oReminder.Item.Body
Next oReminder
...
End Sub
The Outlook object model provides three main ways for working with item bodies:
Body.
HTMLBody.
The Word editor. The WordEditor property of the Inspector class returns an instance of the Word Document which represents the message body.
See Chapter 17: Working with Item Bodies for more information.
I've written some code that scans my default Outlook inbox for emails received today with a specific subject.
I then download the attachment for Outlook items that meet my criteria. I am having trouble designating the Restrict method to pull back items received today.
Here is what I have:
Sub DownloadAttachmentFirstUnreadEmail()
Dim oOlAp As Object, oOlns As Object, oOlInb As Object
Dim oOlItm As Object, oOlAtch As Object
Dim sFilter As String
Dim NewFileName As String
NewFileName = "C:\Temp\" & "CHG_Daily_Extract_" & Format(Date, "MM-DD-YYYY") & ".csv"
'~~> Get Outlook instance
Set oOlAp = GetObject(, "Outlook.application")
Set oOlns = oOlAp.GetNamespace("MAPI")
Set oOlInb = oOlns.GetDefaultFolder(olFolderInbox)
'Declare email item restriction
sFilter = "[ReceivedTime] = '" & Format(Date, "DDDDD HH:NN") & "'"
'Catch
If oOlInb.Items.Restrict(sFilter).Count > 0 Then
'~~> Loop thru today's emails
For Each oOlItm In oOlInb.Items.Restrict(sFilter)
'~> Check if the email subject matches
If oOlItm = "ASG CDAS Daily CHG Report" Then
'~~> Download the attachment
For Each oOlAtch In oOlItm.Attachments
oOlAtch.SaveAsFile NewFileName
Exit For
Next
End If
Exit For
Next
'Display if no emails today
Else: MsgBox "No items"
End If
End Sub
When I run the code, I consistently receive my catch message of "No items".
Please let me know if I am using the Restrict method incorrectly. Thank you so much for the help.
How about the following-
Filter = "#SQL=" & "%today(" & Chr(34) & ("urn:schemas:httpmail:datereceived") & _
Chr(34) & ")%
Or with Attachment
Filter = "#SQL=" & "%today(" & Chr(34) & ("urn:schemas:httpmail:datereceived") & _
Chr(34) & ")% AND " & _
Chr(34) & "urn:schemas:httpmail:hasattachment" & _
Chr(34) & "=1"
Example
Option Explicit
Private Sub Examples()
Dim olNs As Outlook.NameSpace
Dim Inbox As Outlook.MAPIFolder
Dim Items As Outlook.Items
Dim Msg As String
Dim i As Long
Dim Filter As String
Set olNs = Application.GetNamespace("MAPI")
Set Inbox = olNs.GetDefaultFolder(olFolderInbox)
Filter = "#SQL=" & "%today(" & Chr(34) & ("urn:schemas:httpmail:datereceived") & _
Chr(34) & ")%"
Set Items = Inbox.Items.Restrict(Filter)
Msg = Items.Count & " Items in " & Inbox.Name
If MsgBox(Msg, vbYesNo) = vbYes Then
For i = Items.Count To 1 Step -1
Debug.Print Items(i) 'Immediate Window
Next
End If
End Sub
Filtering Items Using a Date-time Comparison MSDN
Outlook Date-time Macros
The date macros listed below return filter strings that compare the value of a given date-time property with a specified date in UTC; SchemaName is any valid date-time property referenced by namespace.
Note Outlook date-time macros can be used only in DASL queries.
Macro Syntax Description
today %today(" SchemaName")% Restricts for items with SchemaName
property value equal to today
More Examples Here
I have a code that returns various properties for mail items. I'm trying to add the "task status" to my report.
I get a run-time error '438' "Object doesn't support this property or method". I'm trying to extract whether the little flag in Outlook is completed (aka checked).
Here is what I have so far:
For Each currentTask In currentItem.Tasks
Debug.Print currentTask.Status
Report = Report & currentTask.Status
Next
It is part of this larger sub:
Private Sub GetAllEmailsInFolder(CurrentFolder As Outlook.Folder, Report As String)
Dim currentItem
Dim attachment As attachment
Dim currentMail As MailItem
Dim currenTask As TaskItem
Report = Report & "Folder Name: " & CurrentFolder.Name & " (Store: " & CurrentFolder.Store.DisplayName & ")" & " (Date of report: " _
& Date & ")" & vbCrLf & "Subject Name|Categories|Attachment Count|Task Status|Attachment Name(s)" & vbCrLf
For Each currentItem In CurrentFolder.Items
Report = Report & currentItem.Subject & "|"
Report = Report & currentItem.Categories & "|"
Report = Report & currentItem.Attachments.Count & "|"
'need help here
For Each currentTask In currentItem.Tasks
Debug.Print currentTask.Status
Report = Report & currentTask.Status
Next
'
For Each attachment In currentItem.Attachments
Debug.Print attachment.FileName
Report = Report & attachment.FileName & ","
Next
Report = Report & vbCrLf
Next
End Sub
A mailitem has a .FlagStatus property.
Option Explicit ' Consider this mandatory
' Tools | Options | Editor tab
' Require Variable Declaration
' If desperate declare as Variant
Private Sub GetAllEmailsInFolder(CurrentFolder As outlook.Folder, Report As String)
' Code for flags not reliable in IMAP accounts
Dim currentItem As Object
Dim attachment As attachment
Dim currentMail As MailItem
'Dim currenTask As TaskItem ' <--- missing Option Explicit?
Dim currentTask As TaskItem
Dim currentFolderItems As Items
Report = Report & "Folder Name: " & CurrentFolder.Name & " (Store: " & CurrentFolder.Store.DisplayName & ")" & " (Date of report: " _
& Date & ")" & vbCrLf & "Subject Name|Categories|Attachment Count|Task Status|Attachment Name(s)" & vbCrLf
Set currentFolderItems = CurrentFolder.Items
For Each currentItem In currentFolderItems
If currentItem.Class = olMail Then
Set currentMail = currentItem
With currentMail
Debug.Print .Subject
Report = Report & .Subject & "|"
Report = Report & .categories & "|"
Report = Report & .Attachments.Count & "|"
' No longer in current documentation
' https://learn.microsoft.com/en-us/previous-versions/office/developer/office-2010/bb644164(v=office.14)
' Still could be good for decades
' 0 - olNoFlag
' 1 - olFlagComplete
' 2 - olFlagMarked
Debug.Print ".FlagStatus.: " & .FlagStatus
'https://learn.microsoft.com/en-us/office/vba/api/outlook.mailitem.flagrequest
Debug.Print ".FlagRequest: " & .FlagRequest
Report = Report & .FlagStatus
For Each attachment In .Attachments
Debug.Print attachment.Filename
Report = Report & attachment.Filename & ","
Next
End With
Report = Report & vbCrLf
Debug.Print Report
ElseIf currentItem.Class = olTask Then
Set currentTask = currentItem
With currentTask
Report = Report & .Subject & "|"
Report = Report & .categories & "|"
Report = Report & .Attachments.Count & "|"
Debug.Print ".Status.....: " & .Status
Report = Report & .Status
For Each attachment In .Attachments
Debug.Print attachment.Filename
Report = Report & attachment.Filename & ","
Next
End With
Report = Report & vbCrLf
Debug.Print Report
Else
Debug.Print "neither a mailitem nor a taskitem"
End If
Set currentItem = Nothing
Set currentTask = Nothing
Set currentMail = Nothing
Next
End Sub
Private Sub test()
Dim currFolder As Folder
Dim reportStr As String
Set currFolder = ActiveExplorer.CurrentFolder
reportStr = "FlagStaus on mailitems: "
GetAllEmailsInFolder currFolder, reportStr
End Sub
Use MailItem.FlagDueBy / FlagIcon / FlagRequest / FlagStatus / IsMarkedAsTask / TaskCompletedDate / TaskDueDate / TaskStartDate / TaskSubject / ToDoTaskOrdinal properties.
In absence of a better solution, you can use the PropertyAccessor for this purpose.
I cannot provide you with a code snippet right now, but you have ilustrative examples on the reference page [1].
The property tag that you are looking for is 0x8025, with DASL http://schemas.microsoft.com/mapi/id/{00062003-0000-0000-C000-000000000046}/81010003.
You can use OutlookSpy to determine property tags of actual properties (thanks to [2] for this tip).
[1] https://learn.microsoft.com/en-us/office/vba/api/outlook.propertyaccessor
[2] How can I get task-specific properties from a MailItem
Edit 1
Private Function GetStatus(objItem As Object) As OlTaskStatus
Dim oPA As Outlook.PropertyAccessor
' MAPI-level access required to get the "status" property of a Mail Item object.
Set oPA = objItem.PropertyAccessor
GetStatus = oPA.GetProperty("http://schemas.microsoft.com/mapi/id/{00062003-0000-0000-C000-000000000046}/81010003")
Set oPA = Nothing
End Function
For some reason, I can't get the selected item which would be an email from my inbox to attach as an attachment when I create a new mail from my macro. I'm using Windows 10 / Outlook 2016. I had this working in Windows 7 Office 2010, but I'm not sure why it's not working now. Any help would be greatly appreciated.
Sub SendEmail()
Dim Inbox As Object
Dim MyItem As Object
Dim AddEmail As Boolean
Dim i As Long
Dim iAnswer As VbMsgBoxResult
'Check if User wants to copy an existing email to new form
iAnswer = MsgBox(Prompt:=" Do you want to copy the selected email to new form? (If you select YES, Keep the current email selected - DO NOT SELECT ANOTHER EMAIL - Until you finish sending)", _
Buttons:=vbYesNo, Title:="Copy Selected Email")
If iAnswer = vbYes Then
AddEmail = True
End If
'Check Version of Outlook (2007 vs 2010)
If Outlook.Application.Version = "12.0.0.6680" Then
On Error GoTo FolderError:
Set Inbox = Outlook.Application.GetNamespace("MAPI").Folders("Mailbox - #Incoming_Workshare")
On Error Resume Next
Else
On Error GoTo FolderError:
Set Inbox = Outlook.Application.GetNamespace("MAPI").Folders("#Incoming_Workshare")
On Error Resume Next
End If
'Open Form From Folder (The Inbox =)
Set MyItem = Inbox.Items.Add("IPM.Note.Workflow Sharing 2016")
MyItem.Display
MyItem.Subject = "Automatically Generated Based on Job Information"
'Check Version of VBA and Form to make sure you are using latest macro
If Not MyItem.Mileage = 11 Then
'Check if User wants to copy an existing email to new form
iAnswer = MsgBox(Prompt:="ALERT - Macro has been updated - Select Yes to Update" & vbCrLf & "(Note: Outlook will be restarted)", _
Buttons:=vbYesNo, Title:="Automatic Macro Update")
If iAnswer = vbYes Then
Shell "wscript C:\Macro\UpdateOutlookMacro.vbs", vbNormalFocus
End If
End If
'Copy Selected Emails to New Email if you selected Yes
If AddEmail = True Then
'Check if a there is a reference to the long access time projects in the subject or body to add instructions to also send as attachment (LARGE PROJECTS)
If InStr(1, UCase(ActiveExplorer().Selection.Item(1).Subject), "TUCAN") > 0 Or _
InStr(1, UCase(ActiveExplorer().Selection.Item(1).Subject), "RUDY") > 0 Or _
InStr(1, UCase(ActiveExplorer().Selection.Item(1).Subject), "SARGENT") > 0 Then
MyItem.HTMLBody = "<b>Additional Instructions from Originating Location:</b>" & Chr(11) & "PLEASE SEND BACK HYPERLINKS AND ATTACHMENTS FOR ALL EDITED FILES" & Chr(11) & Chr(11) & Chr(11) & Chr(11) & "---------------------------------------------" & Chr(11) & "Original Banker Email:" & Chr(11)
Else
MyItem.HTMLBody = "<b>Additional Instructions from Originating Location:</b>" & Chr(11) & Chr(11) & Chr(11) & Chr(11) & Chr(11) & "---------------------------------------------" & Chr(11) & "Original Banker Email:" & Chr(11)
End If
MyItem.BodyFormat = olFormatRichText
'Check large job 15MB
If (ActiveExplorer().Selection.Item(1).Size >= 15728640) Then
MsgBox "Alert! The attached original email size is " & Format(ActiveExplorer().Selection.Item(1).Size / 1048576, 0#) & " MBs. There are errors when sending large emails. Please save attachments as links to reduce the filesize.", , Title:="Email Size Too Big"
End If
MyItem.Attachments.Add ActiveExplorer().Selection.Item(1)
'Check if Sender is an autoforward from a mailbox, alerting to be manually updated
MyItem.UserProperties("Clocker") = ActiveExplorer().Selection.Item(1).SenderName + "; " + ActiveExplorer().Selection.Item(1).CC
If MyItem.UserProperties("Clocker") = "OH Mail; " Or MyItem.UserProperties("Clocker") = "NO Mail; " Or MyItem.UserProperties("Clocker") = "LAV Mail; " Or MyItem.UserProperties("Clocker") = "OK Mail; " Or MyItem.UserProperties("Clocker") = "WY Mail; " Then
'MsgBox "Alert! Please populate the Requestor/Clocker field. It cannot be listed as the Advisory Presentation Mailbox"
'MyItem.UserProperties("Clocker") = "" ' Removed Q4
Dim CorrectedClocker1, CorrectedClocker2, CorrectedClocker3 As String
Correctedclocker1 = Trim(SuperMid(ActiveExplorer().Selection.Item(1).body, "From:", "Sent:"))
If InStr(ActiveExplorer().Selection.Item(1).body, "Cc:") > 0 Then
CorrectedClocker2 = Trim(SuperMid(ActiveExplorer().Selection.Item(1).body, "To:", "Cc:"))
CorrectedClocker3 = Trim(SuperMid(ActiveExplorer().Selection.Item(1).body, "Cc:", "Subject:"))
Else
CorrectedClocker2 = Trim(SuperMid(ActiveExplorer().Selection.Item(1).body, "To:", "Subject:"))
CorrectedClocker3 = ""
End If
CorrectedClocker2 = Replace(CorrectedClocker2, "#Completed", "")
CorrectedClocker3 = Replace(CorrectedClocker3, "#Completed", "")
MyItem.UserProperties("Clocker") = CorrectedClocker1 & "; " & CorrectedClocker2 & "; " & CorrectedClocker3
Else
If InStr(MyItem.UserProperties("Clocker"), "[Cvcs]") > 0 Then
Is this running inside Outlook VBA?. Should Attachments.Add line be the following?
MyItem.Attachments.Add Outlook.Application.ActiveExplorer.Selection.Item(1)
Get rid of the "On Error Resume Next" statements - they are hiding runtime errors.
If you want to add a mailbox item as an attachment to a new message.
You need to set the Outlook.OlAttachmentType property to olEmbeddeditem.
You can add a mail item as an attachment by referring to the code below.
Sub ResolveName()
Dim myItem As Object
Dim Item As Object
Dim myFolder As Folder
Set myNamespace = Application.GetNamespace("MAPI")
Set myFolder = myNamespace.GetDefaultFolder(olFolderInbox)
Set myItem = Application.CreateItem(olMailItem)
Set Item = myFolder.Items(2)
'Item.Display
myItem.Attachments.Add Item, Outlook.OlAttachmentType.olEmbeddeditem, 1, "first"
myItem.Display
End Sub