Extracting Data Relating To Reminders Snoozed - vba

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.

Related

Email address in vba not displaying correctly

I have everything working to send an email via an Access command button. However, the displayed email address is incorrect.
Private Sub cmdSendEmail_Click()
Dim EmailApp, NameSpace, EmailSend As Object
Set EmailApp = CreateObject("Outlook.Application")
Set NameSpace = EmailApp.GetNamespace("MAPI")
Set EmailSend = EmailApp.CreateItem(0)
EmailSend.To = [emailadd] '[emailadd] is the field on the form where the button is located
EmailSend.Subject = [Forms]![WorkordersVR]![Project] & " - " & [Forms]![WorkordersVR]![JobNumber]
EmailSend.Body = "Hello," & vbCrLf & vbCrLf & _
"The project" & " " & [Forms]![WorkordersVR]![Project] & " " & "is ready for pickup." & vbCrLf & vbCrLf & _
"Thank you!" & vbCrLf & vbCrLf & _
"Person sending email here" & vbCrLf & _
EmailSend.Display
Set EmailApp = Nothing
Set NameSpace = Nothing
Set EmailSend = Nothing
End Sub
What ends up in the displayed email To is:
"fred#aplace.com#fred#aplace.com#"
How do I get fred#aplace.com?
You can use string functions available in VBA to get a substring until the # symbol in the string. For example, the InStr function returns a number specifying the position of the first occurrence of one string within another.
Also I'd suggest using the Recipients property of the MailItem class which returns a Recipients collection that represents all the recipients for the Outlook item. Then I'd suggest using the Recipient.Resolve method which attempts to resolve a Recipient object against the Address Book.
For example:
Sub CreateStatusReportToBoss()
Dim myItem As Outlook.MailItem
Dim myRecipient As Outlook.Recipient
Set myItem = Application.CreateItem(olMailItem)
Set myRecipient = myItem.Recipients.Add("email")
myRecipient.Resolve
If(myRecipient.Resolved) Then
myItem.Subject = "Status Report"
myItem.Display
End If
End Sub

VBA Error Messages interspersed with running as planned

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

Restrict Outlook Items to today's date - VBA

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

How to return task status from a mail item?

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

Adding email attachment name to my report Outlook

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)