Macro misses messages in inbox

J

Jacob F.

Greetings everyone,

I'm working on a macro for Outlook 2007 that will move read mail to a
folder. However, for some reason, it seems to be skipping messages in the
inbox. The relevant portion of the code is here:

If TypeOf Item Is MailItem Then
If Not (Item.UnRead Or Item.IsMarkedAsTask) Then
Item.Move ReadFolder
End If
End If
Next Item

When I first ran the macro, it would move most of the messages in a folder,
but not all of them. I ran it through the debugger instead and noticed that
some messages were being skipped. For example, if I have messages 1-10 in my
inbox, it might processs 1, 2, 3, then jump to 7, 8 ,9, 10.

Any idea why this would be happening? Is there some way I can get the
behavior I'm after?

Thanks,
Jacob
 
J

Jacob F.

Sorry about that; my code sample was incomplete:

For Each Item In Inbox.items
If TypeOf Item Is MailItem Then
If Not (Item.UnRead Or Item.IsMarkedAsTask) Then
Item.Move ReadFolder
End If
End If
Next Item

The items are skipped by the 'for' loop. It never gets as far as the 'if'
statements.
 
W

Wei Lu [MSFT]

Hello Jacob,

Per my test, the sample code runs fine on my side.

Could you please let me know the whole function you use?

My function is like this:

Sub MoveItem()
Dim nsp As Outlook.NameSpace
Dim Inbox As Outlook.MAPIFolder 'Inbox
Dim DesFolder As Outlook.MAPIFolder 'Destination Folder

Dim item As MailItem


Set nsp = Application.GetNamespace("MAPI")
Set Inbox = nsp.GetDefaultFolder(olFolderInbox)
Set DesFolder = Inbox.Folders("destinaction folder")


For Each item In mpfInbox.items

If TypeOf item Is MailItem Then
If Not (item.UnRead = Ture Or item.IsMarkedAsTask = False) Then
item.Move DesFolder
End If
End If
Next item

End Sub

Also, I think this move to folder task could be done by the rules.

You could setup a rule in Outlook.

Hope this will be helpful.

Sincerely,

Wei Lu

Microsoft Online Community Support

==================================================

Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.

==================================================
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
J

Jacob F.

Wei Lu,

Thank you for your reply! I've included my full macro below. I am not
running Outlook in cached mode. Could that have an impact on the macro's
performance?

Also, I did consider a rule, but they do not appear to expose the checks I'm
looking for.

Thanks!
Jacob
----------------


Sub SaveReadMail()
On Error GoTo SaveReadMail_err

Dim ns As NameSpace
Dim Inbox As Folder
Dim Item As Object
Dim count As Integer

Set ns = GetNamespace("MAPI")
Set Inbox = ns.GetDefaultFolder(olFolderInbox)
Set ReadFolder = Inbox.folders("Previously Read Mail")
i = 0
j = 0

' At the moment, completed tasks stay in the inbox until explicity moved.
' Also, non-mail items won't be moved
For Each Item In Inbox.items
If TypeOf Item Is MailItem Then
If Not (Item.UnRead Or Item.IsMarkedAsTask) Then
Item.Move ReadFolder
i = i + 1
End If
End If
j = j + 1
Next Item

MsgBox i & " messages moved to " & ReadFolder _
& " and " & j & " messages skipped." _
, vbInformation, "Inbox Cleanup"

SaveReadMail_exit:
Set ns = Nothing
Set Inbox = Nothing
Set ReadFolder = Nothing
Exit Sub

SaveReadMail_err:
MsgBox "An unexpected error has occured." _
& vbCrLf & "Macro Name: SaveReadMail" _
& vbCrLf & "Error Number: " & Err.Number _
& vbCrLf & "Error Description: " & Err.Description, _
vbCritical, "Error!"
Resume SaveReadMail_exit

End Sub
 
J

Jacob F.

I did some more exploring with the debugger and I think I may have sovled the
problem. Inbox.Items appears to be updated in realtime; that is, if an item
is added to removed to the inbox while the script is running, then items
changes. However, it doesn't look like 'for each' is aware of that.

This is what I'm seeing. Assume for a minute we're dealing with messages A,
B, C, and D. If my script moves message B to a new folder, messages C and D
are shifted to the left. However, my 'for each' loop is getting ready to
grab the third item from the list, since it just finished with the second
item. However, now item number 3 is message D. Message C was skipped.

Does that make sense? Any suggestions on how to correct it?
 
S

Steve Rindsberg

Jacob F. said:
Sorry about that; my code sample was incomplete:

For Each Item In Inbox.items
If TypeOf Item Is MailItem Then
If Not (Item.UnRead Or Item.IsMarkedAsTask) Then
Item.Move ReadFolder
End If
End If
Next Item

The items are skipped by the 'for' loop. It never gets as far as the 'if'
statements.

I'm clueless re Outlook but try controlling the loop with:

For x = Inbox.Items.Count To 1 Step -1

For Each is implicitly doing a For X = 1 to Whatever.Count and when you remove
Whatever(2), then Whatever(3) becomes Whatever(2) and never gets tested when
your loop moves on to Whatever(3).
 
J

Jacob F.

Thank you, Steve! That did the trick!

I need to spend some time optimizing (since messages that are unread will be
processed over and over), I'm on the right track now!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top