?
Solved

Outlook VBA not moving emails

Posted on 2010-01-10
14
Medium Priority
?
602 Views
Last Modified: 2012-05-08
I am running the following code to move all emails with the category 'File' to another specified folder.  The issue I am experiencing is that when the code is executed, not all of the emails within the folder (inbox) are moved, even though the FOR loop is run through all the objects within the 'inbox' folder.

Once the code is executed several times, it does move the desired emails.  Any suggestions on why this is occurring?

Set objFolder = Outlook.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox)

For Each objItems In objFolder.Items
  If (objItems.Class = olMail) Then
    If (objItems.Categories = "File") Then
      objItems.move objDest
    End If
  End If
Next

Open in new window

0
Comment
Question by:Cmitch
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 6
  • 2
14 Comments
 
LVL 10

Expert Comment

by:bromy2004
ID: 26280482
In your macro, is there any setting changes made?
i.e it changes the Category to something else?
or removes the category?
0
 

Author Comment

by:Cmitch
ID: 26280565
No changes are made, it simply moves the emails with category 'File' to another destination folder.
0
 
LVL 59

Accepted Solution

by:
Chris Bottomley earned 2000 total points
ID: 26280827
Hello Cmitch,

The issue is if you imagine there are three items, the loop processes 1 and when complete there are only two items in the folder.  It now processes the second and there is only 1 item in the folder ... where is the third item for it to process?

When deleting or moving items you need to work backwards i.e.:

Regards,

chris_bottomley
Set objFolder = Outlook.GetNamespace("MAPI").GetDefaultFolder(olFolderInbox)
dim itmCount as integer

For itmcount = objFolder.Items.count to 1 step -1
  set objitems = objFolder.Items(itmCount)
  If (objItems.Class = olMail) Then
    If (objItems.Categories = "File") Then
      objItems.move objDest
    End If
  End If
Next

Open in new window

0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 10

Expert Comment

by:bromy2004
ID: 26283114
Chris,
I was under the impression that he was using For Each, not For i = x to y,
You only need to Work backwards, If you are deleting AND using a count.
0
 
LVL 59

Expert Comment

by:Chris Bottomley
ID: 26283324
bromy2004:

Wrong i'm afraid, that is the fundamental issue with for each you think it's ok but it sure isn't.  i.e. as you move an item the collection reduces so the loop stops halpway through each time.

You should always do delete and move by a reverse count ... in my experience and since I do make mistakes I did a quick test with the following code and as I suggested only half the existing files move each time.

Chris


Sub copyeach()
Dim src As Object
Dim tgt As Object
Dim itm As Object

    Set src = Application.Session.GetDefaultFolder(olFolderInbox).folders("chris").folders("Test")
    Set tgt = Application.Session.GetDefaultFolder(olFolderInbox).folders("chris").folders("Test2")
    For Each itm In src.items
        itm.Move tgt
    Next
End Sub

Open in new window

0
 

Author Closing Comment

by:Cmitch
ID: 31675334
Thanks, certainly a lesson learnt with FOR EACH.
0
 
LVL 10

Expert Comment

by:bromy2004
ID: 26288482
I use the Attached macro (Prior to 2010) and it always goes through every item.
unless its a failed delivery message ect.

should it not be working?
Sub MoveSelectedMessagesToFolder()

On Error Resume Next
  Dim objFolder As Outlook.MAPIFolder, objInbox As Outlook.MAPIFolder
  Dim objNS As Outlook.NameSpace, objItem As Outlook.MailItem
  Dim objSecFolder As Outlook.MAPIFolder

  Set objNS = Application.GetNamespace("MAPI")
  Set objInbox = objNS.GetDefaultFolder(olFolderInbox)
  Set objFolder = objInbox.Folders("Done")
  Set objSecFolder = objInbox.Folders("Experts Exchange")
  
  'Assume this is a mail folder
  If objFolder Is Nothing Then
    MsgBox "This folder doesn't exist!", vbOKOnly + vbExclamation, "INVALID FOLDER"
  End If
  
 'Check Second Folder
 If objSecFolder Is Nothing Then
    MsgBox "This folder doesn't exist!", vbOKOnly + vbExclamation, "INVALID FOLDER"
  End If
  
  
  
  Dim a, b As Variant
  Dim SenderDomain As String
  
  a = Application.ActiveExplorer.Parent.Panes.Class
  b = Application.ActiveExplorer.Caption
  If Application.ActiveExplorer.Selection.Count = 0 Then
    'Require that this procedure be called only when a message is selected
    Exit Sub
  End If
  For Each objItem In Application.ActiveExplorer.Selection
    If objFolder.DefaultItemType = olMailItem And objItem.Class = olMail Then
      'clear categories
      objItem.Categories = ""
      'mark item as read
      objItem.UnRead = False
        'Clear Flag
        If objItem.FlagStatus = 2 Then
          objItem.TaskCompletedDate = Date
          Else
        End If
      objItem.UnRead = False 'Move to Designated Folder
    
    SenderDomain = objItem.SenderEmailAddress
    SenderDomain = InStr(1, objItem.SenderEmailAddress, "@", vbTextCompare)
    Select Case SenderDomain
      Case "experts-exchange.com"
      objItem.Move objSecFolder
      Case Else
      objItem.Move objFolder
    End Select
    End If
  Next

  Set objItem = Nothing
  Set objFolder = Nothing
  Set objInbox = Nothing
  Set objNS = Nothing
End Sub

Open in new window

0
 
LVL 59

Expert Comment

by:Chris Bottomley
ID: 26290551
bromy2004:

FWIW I cannort see a delete or move of an email in this script therefore yes it will work it is only when the collection is reduced dynamically that for each is a problem.

Cmitch's script was deleting files therefore the collection was reducing and hence the half split with every run.

Chris
0
 
LVL 10

Expert Comment

by:bromy2004
ID: 26290576
Lines 45-54 are the Move
    Select Case SenderDomain
      Case "experts-exchange.com"
      objItem.Move objSecFolder
      Case Else
      objItem.Move objFolder
    End Select
0
 
LVL 59

Expert Comment

by:Chris Bottomley
ID: 26290595
ok missed that and in that case it will fail ... perhaps mails other than the selection are processed because I most certainly would expect it to fail when moving every mail item in the folder.

And it's a general issue with collections as far as I am aware not just outlook mail items.

Chris
0
 
LVL 10

Expert Comment

by:bromy2004
ID: 26290618
??
I'm a bit confused now.
I tested with Deleting and Moving (Separate Macros) all items in a Folder...and it worked fine.
0
 
LVL 59

Expert Comment

by:Chris Bottomley
ID: 26290741
Tis still the case that it works as I mentioned in Vista and office 2007 - what are you using?

Chris
0
 
LVL 10

Expert Comment

by:bromy2004
ID: 26290747
I've got XP and Office 2010 Beta.

Nathan
0
 
LVL 59

Expert Comment

by:Chris Bottomley
ID: 26290830
I've had a pootle but unfortunately cannot see a reference to model changes ... perhaps it is fixed in Office 2010 then.

Not that i'll be upgrading any time soon!

Chris
0

Featured Post

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Large Outlook files lead to various unwanted errors and corruption issues. Furthermore, large outlook files can also make Outlook take longer to start-up, search, navigate, and shut-down. So, In this article, i will discuss a method to make your Out…
If you troubleshoot Outlook for clients, you may want to know a bit more about the OST file before doing your next job. IMAP can cause a lot of drama if removed in the accounts without backing up.
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
CodeTwo Sync for iCloud (http://www.codetwo.com/sync-for-icloud?sts=6554) automatically synchronizes your Outlook 2016, 2013, 2010 or 2007 folders with iCloud folders available via iCloud Control Panel. This lets you automatically sync them with…
Suggested Courses

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question