I'm trying to move Outlook Items, However the code runs with no error messages but no emails are moved.
This leads me to belief the necessary IF condition
is never being met? However I could be wrong.
Please find code below.
Sub Gatekeeper()
Dim aItem As Object
Dim mail As Object
Dim strTime As String
Dim Items As Outlook.Items
Dim olNs As Outlook.NameSpace
Dim subfolder As Outlook.MAPIFolder
Set olNs = Application.GetNamespace("MAPI")
Set mail = olNs.GetDefaultFolder(olFolderInbox)
Set Items = mail.Items
For Each aItem In Items
strTime = aItem.ReceivedTime
If strTime > #6:00:00 PM# And strTime < #5:30:00 AM# Then
Set subfolder = mail.Folders("Nights")
aItem.Move subfolder
End If
Next aItem
End Sub
You shouldn't use For Each...Next Loop when you are Moving /deleting or modifying collection Items
Use a For Each...Next loop when you want to repeat a set of statements for each element of a collection or array.
Work with For...Next Statement - Down for loop:
For i = Items.Count to 1 step -1
Next
A For...Next Statement works well when you can associate each iteration of a loop with a control variable and determine that variable's initial and final values. However, when you are dealing with a collection, the concept of initial and final values isn't meaningful, and you don't necessarily know how many elements the collection has. In this kind of case, a For Each...Next loop is often a better choice.
Also remember there are objects other than MailItem in your Inbox so check If Items.Class = olMail Then or you will encounter and error on your loop
You may also wanna use Items.Restrict Method (Outlook) to improve your loop
Items.Restrict Method Applies a filter to the Items collection, returning a new collection containing all of the items from the original that match the filter.
The method is an alternative to using the Find method or FindNext method to iterate over specific items within a collection. The Find or FindNext methods are faster than filtering if there are a small number of items. The Restrict method is significantly faster if there is a large number of items in the collection, especially if only a few items in a large collection are expected to be found.
_
Code Example
Option Explicit
Public Sub Example()
Dim olNs As Outlook.NameSpace
Dim Inbox As Outlook.MAPIFolder
Dim Items As Outlook.Items
Dim Item As Object
Dim Filter As String
Dim i As Long
Filter = "[ReceivedTime] >= '" & _
CStr(Date - 1) & _
" 06:00PM' AND [ReceivedTime] < '" & _
CStr(Date) & " 05:30AM'"
Debug.Print Filter
Set olNs = Application.GetNamespace("MAPI")
Set Inbox = olNs.GetDefaultFolder(olFolderInbox)
Set Items = Inbox.Items.Restrict(Filter)
Items.Sort "[ReceivedTime]"
For i = Items.Count To 1 Step -1
DoEvents
If TypeOf Items(i) Is MailItem Then
Debug.Print Items(i) ' Print on Immediate Window (Ctrl+G)
Set Item = Items(i)
Item.Move Inbox.Folders("Nights")
End If
Next
End Sub
Make sure to set your Filter correctly, I'm assuming your looking at yesterdays 06:00PM
CStr(Date - 1) = (today - 1 day)
CStr and Date
The Date type always contains both date and time information. For purposes of type conversion, Visual Basic considers 1/1/0001 (January 1 of the year 1) to be a neutral value for the date, and 00:00:00 (midnight) to be a neutral value for the time. CStr does not include neutral values in the resulting string. For example, if you convert #January 1, 0001 9:30:00# to a string, the result is "9:30:00 AM"; the date information is suppressed. However, the date information is still present in the original Date value and can be recovered with functions such as DatePart.
Instead of iterating over all items in the folder you need to find items that correspond to your conditions and move them to a subfolder (or any other folder) by calling the Move method.
You need to use the Find/FindNext or Restrict methods of the Items
class to find all items that correspond to your conditions (read and sender name). Read more about these methods 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
Then you can use the Move method of the MailItem class to move a Microsoft Outlook item to a new folder. For example:
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
Dim searchCriteria As String
Set myNameSpace = Application.GetNamespace("MAPI")
Set myInbox = myNameSpace.GetDefaultFolder(olFolderInbox)
Set myItems = myInbox.Items
Set myDestFolder = myInbox.Folders("Personal Mail")
Set searchCriteria = "[ReceivedTime] >= '" & CStr(Date - 1) & " 06:00PM' AND [ReceivedTime] < '" & CStr(Date) & " 05:30AM'"
Set myItem = myItems.Find(searchCriteria)
While TypeName(myItem) <> "Nothing"
myItem.Move myDestFolder
Set myItem = myItems.FindNext
Wend
End Sub
You may find the Getting Started with VBA in Outlook 2010 article helpful.