Macro for Loop through outlook unread emails - vba

I am trying adapt this code for use the macro only in unread emails in my Inbox, but I don’t get anything that works. Someone for helping me? THanks in advance.
Public Sub Unread_eMails()
Dim myNameSpace As Outlook.NameSpace
Dim myInbox As Outlook.Folder
Dim myDestFolder As Outlook.Folder
Set myNameSpace = Application.GetNamespace("MAPI")
Set myInbox = myNameSpace.GetDefaultFolder(olFolderInbox)
Set myDestFolder = myInbox.Folders("CHECK")
'For Each MyItem In myInbox
For Each MyItem In Application.ActiveExplorer.**¿?** 'I don't know what type here...
If myInbox.UnReadItemCount <> 0 Then
If InStr(MyItem.Body, "alarm") > 0 Then
MyItem.Move myDestFolder
Else
If InStr(MyItem.Subject, "Urgent") > 0 Then
MyItem.Move myDestFolder
Else
If InStr(MyItem.Body, "Closed") > 0 Then
MyItem.Categories = "Closed"
MyItem.Save
End If
End If
End If
MyItem.UnRead = False
End If
Next MyItem
End Sub

Limit the items to those that are unread with Restrict.
Loop in reverse when moving or deleting.
Option Explicit ' Consider this mandatory
' Tools | Options | Editor tab
' Require Variable Declaration
' If desperate declare as Variant
Public Sub Unread_eMails()
Dim myInbox As folder
Dim myDestFolder As folder
Dim myItem As Object
Dim myItems As Items
Dim myRestrictedItems As Items
Dim i As Long
Set myInbox = Session.GetDefaultFolder(olFolderInbox)
Set myDestFolder = myInbox.Folders("CHECK")
If myInbox.UnReadItemCount <> 0 Then
Set myItems = myInbox.Items
' Restrict to unread items
Set myRestrictedItems = myItems.Restrict("[UnRead] = True")
' Reverse loop when moving or deleting
For i = myRestrictedItems.Count To 1 Step -1
Set myItem = myRestrictedItems(i)
' Note: InStr is case sensitive
If InStr(myItem.body, "alarm") > 0 Then
myItem.Move myDestFolder
ElseIf InStr(myItem.subject, "Urgent") > 0 Then
myItem.Move myDestFolder
ElseIf InStr(myItem.body, "Closed") > 0 Then
myItem.categories = "Closed" ' save required
myItem.Save
myItem.UnRead = False ' save not required
End If
Next
End If
End Sub

Related

Set mails read if they were read in another folder

I'm trying to make an outlook macro, which will 'update' the mails. I have an Inbox folder and an another one. (2 mail accunts)
There is a rule, which is copying the mail from another folder to my inbox.
My goal is to set the mail as read in another folder, if it was read in the Inbox folder.
Sub precitane()
Dim myNameSpace As Outlook.NameSpace
Dim myInbox As Outlook.Folder
Dim myDestFolder As Outlook.Folder
Dim mydeffolder As Outlook.Folder
Dim items As Object
Dim defitems As Object
Set myNameSpace = Application.GetNamespace("MAPI")
Set myDestFolder = myNameSpace.Folders("") 'mymail
Set mydeffolder = myNameSpace.GetDefaultFolder(olFolderInbox)
For Each items In myDestFolder.items
For Each defitems In mydeffolder.items
If TypeOf items Is Outlook.MailItem & TypeOf defitems Is Outlook.MailItem Then
Dim oMail As Outlook.MailItem: Set oMail = items
Dim defMail As Outlook.MailItem: Set defMail = defitems
If oMail.SenderEmailAddress = "" & defMail.SenderEmailAddress = "" & defMail.Body = oMail.Body & defMail.UnRead = False Then
oMail.UnRead = True
oMail.Save
End If
End If
Next
Next
On Error GoTo 0
End Sub
"" contains my mail...
It looks like you tried with code from other than VBA.
I broke the If statement into separate parts as it is easier to follow and to debug.
Option Explicit
Sub precitane()
Dim myDestFolder As Folder
Dim mydeffolder As Folder
Dim item As Object
Dim defItem As Object
Set myDestFolder = Session.Folders("mailAddress2").Folders("Inbox").Folders("Test")
Set mydeffolder = Session.GetDefaultFolder(olFolderInbox).Folders("Test3")
For Each item In myDestFolder.items
If TypeOf item Is MailItem Then
For Each defItem In mydeffolder.items
If TypeOf defItem Is MailItem Then
If item.senderEmailAddress = defItem.senderEmailAddress Then
If item.Body = defItem.Body Then
If item.UnRead = False Then
defItem.UnRead = False
'If necessary
'item.Save
Exit For
End If
End If
End If
End If
Set defItem = Nothing
Next
End If
Set item = Nothing
Next
Debug.Print "Done."
End Sub

Moving emails with specified attachments from shared inbox to a different folder of the same shared mailbox

I created a rule to run a script on all incoming email. The script checks if the email has any attachments and checks their type. Mails which have only .pdf attachments, stay in the inbox, the rest goes to Error folder. The script also ignores hidden attachments.
This works on my own Outlook mailbox. The problem is that it has to work on a shared mailbox.
I modified the rule so it would take into consideration only the messages arriving at a shared mailbox, but it's not working, even if I set up a rule without any script.
I tried to change the script, but the only thing I managed to achieve is moving the pdf-less emails from my inbox to Error folder in shared inbox.
Here is the script that works with my own mailbox:
Sub PDF(Item As Outlook.MailItem)
Const PR_ATTACHMENT_HIDDEN As String = "http://schemas.microsoft.com/mapi/proptag/0x7FFE000B"
Dim myAtt As Outlook.Attachment
Dim allPdf As Boolean
Dim hidNum As Integer
allPdf = True
hidNum = 0
Dim pa As PropertyAccessor
For Each myAtt In Item.Attachments
Debug.Print myAtt.DisplayName
Set pa = myAtt.PropertyAccessor
If pa.GetProperty(PR_ATTACHMENT_HIDDEN) Then
hidNum = hidNum + 1
Else
If Not pa.GetProperty(PR_ATTACHMENT_HIDDEN) And Right(LCase(myAtt.FileName), 4) <> ".pdf" Then
allPdf = False
End If
End If
Next
If allPdf = False Or Item.Attachments.Count = hidNum Then
Item.Move Session.GetDefaultFolder(olFolderInbox).Parent.Folders("Error")
End If
Set myAtt = Nothing
Set pa = Nothing
End Sub
I tried this script, but it's not working:
Sub PDF4(Item As Outlook.MailItem)
Const PR_ATTACHMENT_HIDDEN As String = "http://schemas.microsoft.com/mapi/proptag/0x7FFE000B"
Dim myAtt As Outlook.Attachment
Dim allPdf As Boolean
Dim hidNum As Integer
Dim myNamespace As Outlook.NameSpace
Dim myRecipient As Outlook.Recipient
Set myNamespace = Application.GetNamespace("MAPI")
Set myRecipient = myNamespace.CreateRecipient("test#mailbox.com")
Set objOutlook = CreateObject("Outlook.Application")
Set objNamespace = objOutlook.GetNamespace("MAPI")
Set objInbox = objNamespace.GetSharedDefaultFolder(myRecipient, olFolderInbox)
strFolderName = objInbox.Parent
Set objMailbox = objNamespace.Folders(strFolderName)
Set objFolder = objMailbox.Folders(olFolderInbox)
Set colItems = objFolder.Items
allPdf = True
hidNum = 0
Dim pa As PropertyAccessor
For Each Item In objFolder.Items
For Each myAtt In Item.Attachments
Debug.Print myAtt.DisplayName
Set pa = myAtt.PropertyAccessor
If pa.GetProperty(PR_ATTACHMENT_HIDDEN) Then
hidNum = hidNum + 1
Else
If Not pa.GetProperty(PR_ATTACHMENT_HIDDEN) And Right(LCase(myAtt.FileName), 4) <> ".pdf" Then
allPdf = False
End If
End If
Next
If allPdf = False Or Item.Attachments.Count = hidNum Then
Item.Move objInbox.Folders("Error")
End If
Set myAtt = Nothing
Set pa = Nothing
End Sub
There are two problems:
Is it possible to set up a rule that takes into consideration only the messages which arrive at the shared inbox? The current rule checks only the emails, which arrive at my inbox. (I have no option in Rule Management to "Apply changes to this folder:".)
If not possible, I could always make the script work through macro.
How should the code be written? Maybe it's ok and is not working only because of the rule. Is it possible to make a script that checks the attachments only of the messages that arrive at the shared inbox?
#niton suggested using ItemAdd and it worked. Now the script checks emails in shared inbox.
Thank you for help!
Solution:
It has to be put inside ThisOutlookSession
Option Explicit
Private objNS As Outlook.NameSpace
Private WithEvents objItems As Outlook.Items
Private Sub Application_Startup()
Dim objWatchFolder As Outlook.Folder
Set objNS = Application.GetNamespace("MAPI")
Dim Recip As Outlook.Recipient
Set Recip = objNS.CreateRecipient("test#mail.com")
Set objWatchFolder = objNS.GetSharedDefaultFolder(Recip, olFolderInbox)
Set objItems = objWatchFolder.Items
Set objWatchFolder = Nothing
Set Recip = Nothing
End Sub
Private Sub objItems_ItemAdd(ByVal Item As Object)
Const PR_ATTACHMENT_HIDDEN As String = "http://schemas.microsoft.com/mapi/proptag/0x7FFE000B"
Dim myAtt As Outlook.Attachment
Dim allPdf As Boolean
Dim hidNum As Integer
allPdf = True
hidNum = 0
Dim pa As PropertyAccessor
Dim objWatchFolder As Outlook.Folder
Set objNS = Application.GetNamespace("MAPI")
Dim Recip As Outlook.Recipient
Set Recip = objNS.CreateRecipient("test#mail.com")
Set objWatchFolder = objNS.GetSharedDefaultFolder(Recip, olFolderInbox)
For Each myAtt In Item.Attachments
Debug.Print myAtt.DisplayName
Set pa = myAtt.PropertyAccessor
If pa.GetProperty(PR_ATTACHMENT_HIDDEN) Then
hidNum = hidNum + 1
Else
If Not pa.GetProperty(PR_ATTACHMENT_HIDDEN) And Right(LCase(myAtt.FileName), 4) <> ".pdf" Then
allPdf = False
End If
End If
Next
If allPdf = False Or Item.Attachments.Count = hidNum Then
Item.Move objWatchFolder.Parent.Folders("Error")
End If
Set Item = Nothing
Set myAtt = Nothing
Set pa = Nothing
Set objWatchFolder = Nothing
Set Recip = Nothing
End Sub
I'm sure the code could be more optimized, but "it just works".

How to delete emails from a string of users?

How can I go through this "indefinite 5-10..." list of senders and delete their messages:
mySenders =" Dan Wilson, Tom Hanks, Alisa Milano, Jessica Alba, Torrid, Captain America"
The code below works for a single sender.
Sub MoveItems()
Dim myNameSpace As Outlook.NameSpace
Dim myInbox As Outlook.Folder
Dim myDestFolder As Outlook.Folder
Dim myItems As Outlook.Items
Dim myItem As Object
Set myNameSpace = Application.GetNamespace("MAPI")
Set myInbox = myNameSpace.GetDefaultFolder(olFolderInbox)
Set myItems = myInbox.Items
Set myDestFolder = myNameSpace.GetDefaultFolder(olFolderDeletedItems)
'how to loop here?
Set myItem = myItems.Find("[SenderName] = 'Kmart'")
While TypeName(myItem) <> "Nothing"
myItem.Move myDestFolder
Set myItem = myItems.FindNext
Wend
End Sub
little confuse. but to delete msg from multiple sender, Add a Second While .. Wend and modify it to use myItem.Delete
Example:
Tested on Outlook 2010
Option Explicit
Sub DeleteItems()
Dim myNameSpace As Outlook.NameSpace
Dim myInbox As Outlook.Folder
Dim myItems As Outlook.Items
Dim myItem As Object
Set myNameSpace = Application.GetNamespace("MAPI")
Set myInbox = myNameSpace.GetDefaultFolder(olFolderInbox)
Set myItems = myInbox.Items
'// loop for each sender
Set myItem = myItems.Find("[SenderName] = 'Dan Wilson'")
While TypeName(myItem) <> "Nothing"
myItem.Delete
Set myItem = myItems.FindNext
Wend
'// Loop Next Sender
Set myItem = myItems.Find("[SenderName] = 'Tom Hanks'")
While TypeName(myItem) <> "Nothing"
myItem.Delete
Set myItem = myItems.FindNext
Wend
Set myItem = myItems.Find("[SenderName] = 'Alisa Milano'")
While TypeName(myItem) <> "Nothing"
myItem.Delete
Set myItem = myItems.FindNext
Wend
' More here
End Sub
You could loop through an an array based on mySenders.
Option Explicit
Sub MoveItems()
Dim myNameSpace As Namespace
Dim myInbox As folder
Dim myDestFolder As folder
Dim myItems As Items
Dim myItem As Object
Dim mySenders() As String
Dim i As Long
Set myNameSpace = GetNamespace("MAPI")
Set myInbox = myNameSpace.GetDefaultFolder(olFolderInbox)
Set myItems = myInbox.Items
Set myDestFolder = myNameSpace.GetDefaultFolder(olFolderDeletedItems)
mySenders = Split("Dan Wilson,Tom Hanks,Alisa Milano,Jessica Alba,Torrid,Captain America", ",")
For i = LBound(mySenders) To UBound(mySenders)
Debug.Print i & " - " & mySenders(i)
Set myItem = myItems.Find("[SenderName] = """ & mySenders(i) & """")
While TypeName(myItem) <> "Nothing"
myItem.Move myDestFolder
Set myItem = myItems.FindNext
Wend
Next
End Sub
You will need the exact names.
Sub display_SenderName()
Dim currItem As Object
Select Case ActiveWindow.Class
Case olExplorer
' The active window is a list of messages (folder)
' There might be several selected messages
' Here only one is processed
Set currItem = ActiveExplorer.Selection(1)
Debug.Print currItem.Subject
Debug.Print currItem.senderName
Case olInspector
Set currItem = ActiveInspector.currentItem
Debug.Print currItem.Subject
Debug.Print currItem.senderName
End Select
End Sub

Move selected items to folder

I am using the below function to move selected emails to another folder.
The error says "An object could not be found."
It works the first time, but any subsequent attempts fail on the line:
Set TestFolder = SubFolders.Item(FoldersArray(i))
When the following line executes, when I expand folders in the watch window, no subfolders appear:
Set TestFolder = Application.Session.Folders.Item(FoldersArray(0))
I am calling the function from a sub:
Option Explicit
Private Item As Object, olkItem As Object
Private AutoReply As String
Private myDestFolder As Outlook.Folder, myInbox As Outlook.Folder
Private myNameSpace As Outlook.NameSpace
Sub ReplywithNote2()
Set myNameSpace = Application.GetNamespace("MAPI")
Set myInbox = myNameSpace.GetDefaultFolder(olFolderInbox)
Set myDestFolder = GetFolder("\\PO_Queries\Inbox\Completed")
For Each olkItem In Application.ActiveExplorer.Selection
With olkItem
If .Class = olMail Then
'.Move myDestFolder
End If
End With
Next
End Sub
Function:
Function GetFolder(ByVal FolderPath As String) As Outlook.Folder
Set GetFolder = Nothing
Dim TestFolder As Outlook.Folder
Dim FoldersArray As Variant
Dim i As Integer
'On Error GoTo GetFolder_Error
If Left(FolderPath, 2) = "\\" Then
FolderPath = Right(FolderPath, Len(FolderPath) - 2)
End If
'Convert folderpath to array
FoldersArray = Split(FolderPath, "\")
Set TestFolder = Application.Session.Folders.Item(FoldersArray(0))
If Not TestFolder Is Nothing Then
For i = 1 To UBound(FoldersArray, 1)
Dim SubFolders As Outlook.Folders
Set SubFolders = TestFolder.Folders
Set TestFolder = SubFolders.Item(FoldersArray(i))
If TestFolder Is Nothing Then
Set GetFolder = Nothing
End If
Next
End If
'Return the TestFolder
Set GetFolder = TestFolder
On Error GoTo 0
Exit Function
GetFolder_Error:
Set GetFolder = Nothing
Exit Function
End Function
When I restart Outlook it works. I tried setting several variables to Nothing, executing 'End' in the hope of resetting the relevant variable. What is reset when I restart Outlook?
Edit - I've narrowed it down to the move line. The problem occurs when running the sub after having moved the item.
For Each does not work correctly when moving or deleting.
You either process item one until there are no items left or loop backwards.
For i = Application.ActiveExplorer.Selection.Count to 1 step -1
https://msdn.microsoft.com/en-us/library/office/ff863343%28v=office.15%29.aspx
"To delete all items in the Items collection of a folder, you must delete each item starting with the last item in the folder. For example, in the items collection of a folder, AllItems, if there are n number of items in the folder, start deleting the item at AllItems.Item(n), decrementing the index each time until you delete AllItems.Item(1)."
Edit: 2015 06 16
Unless there is a reason for using GetFolder try this:
Set myDestFolder = myNameSpace.Folders("PO_Queries").Folders("Inbox").Folders("Completed")
Many thanks to niton, I amended my sub to the following, which works:
Sub ReplywithNote2()
Set myNameSpace = Application.GetNamespace("MAPI")
Set myInbox = myNameSpace.GetDefaultFolder(olFolderInbox)
Set myDestFolder = GetFolder("\\PO_Queries\Inbox\Completed")
For i = Application.ActiveExplorer.Selection.Count To 1 Step -1
With Application.ActiveExplorer.Selection.Item(i)
If .Class = olMail Then
.Move myDestFolder
End If
End With
Next
End Sub
The issue still occurs if I move the email back into the original folder manually and try again, but I can live with that!
Thanks again, most grateful.
Sub myMove()
Set myNameSpace = Application.GetNamespace("MAPI")
Set myInbox = myNameSpace.GetDefaultFolder(olFolderInbox)
Set myDestFolder = GetFolder("\\xxx\folder1\folder2\folder3")
Dim i As Long
For Each olkItem In Application.ActiveExplorer.Selection
i = MsgBox("Do you want to move selected emails to folder folder3?", vbYesNo + vbQuestion + vbSystemModal + vbMsgBoxSetForeground, "Confirm Move")
If i = vbNo Then
Cancel = True
End
Else
'Continue moving message
For i = Application.ActiveExplorer.Selection.Count To 1 Step -1
With Application.ActiveExplorer.Selection.Item(i)
If .Class = olMail Then
.Move myDestFolder
End If
End With
Next
End
End If
Next
End:
End Sub

Get email from non default inbox?

I am using the following vba code to get emails from my inbox folder and move them to a sub folder called suppliers. At the moment the emails are moved from my default email inbox, but I have an account called purcashing#hewden.co.uk and I want it to get the emails from this inbox and move it to the subfolder called Suppliers in this account.
can someone show me how I would alter GetDefaultFolder to make this happen. thanks
Sub MoveItems()
Dim myNameSpace As Outlook.NameSpace
Dim myInbox As Outlook.Folder
Dim myDestFolder As Outlook.Folder
Dim myItems As Outlook.Items
Dim myItem As Object
Set myNameSpace = Application.GetNamespace("MAPI")
Set myInbox = myNameSpace.GetDefaultFolder(olFolderInbox)
Set myItems = myInbox.Items
Set myDestFolder = myInbox.Folders("Supplier")
Set myItem = myItems.Find("[Subject] = 'Introduction'")
While TypeName(myItem) <> "Nothing"
myItem.Move myDestFolder
Set myItem = myItems.FindNext
Wend
End Sub
Instead of using Namespace.GetDefaultFolder, retrieve the appropriate store from the Namespace.Stores collection and use Store.GetDefaultFolder.
I just used Dmitry's suggestion and it works like a charm.
Hope it helps \o/
Sub GetEmailFromNonDefaultInbox()
Dim myOlApp As New Outlook.Application
Dim myNameSpace As Outlook.Namespace
Dim myInbox As Outlook.MAPIFolder
Dim myitems As Outlook.Items
Dim strFilter As String
' let the user choose which account to use
Set myAccounts = myOlApp.GetNamespace("MAPI").Stores
For i = 1 To myAccounts.count
res = MsgBox(myAccounts.Item(i).DisplayName & "?", vbYesNo)
If res = vbYes Then
Set myInbox = myAccounts.Item(i).GetDefaultFolder(olFolderInbox)
Exit For
End If
Next
If myInbox Is Nothing Then Exit Sub ' avoid error if no account is chosen
' query emails by subject
strFilter = "#SQL=""urn:schemas:httpmail:subject"" like '%YOUR SUBJECT%'"
Set myitems = myInbox.Items.Restrict(strFilter)
' show some feedback if no email is found
If myitems.count = 0 Then
MsgBox "Nothing found. Try another account."
Exit Sub
End If
' get the most recent email
myitems.Sort "ReceivedTime", True
Set myitem = myitems.GetFirst
If myitem.Class = olMail Then
' and now you can do whatever you want
MsgBox (myitem.Subject)
End If
End Sub