Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
897 views
in Technique[技术] by (71.8m points)

vba - Move items to a specified subfolder inside Outlook based on ReceivedTime

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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.



与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...