...

View Full Version : Outlook VBA Problem: For...Next Loop with Items



ez4me2c3d
07-24-2007, 08:14 PM
I am trying to write a macro that will search through a listing of folders, identify the UNREAD items, and mark them as read.

I have the code written, I'm just stumped as to why the For...Next loop for the Items is limiting itself to three loops??? I have set exactly 5 mail items as unread in each folder, and you can see this from the debug output.

The VBA code:

Sub Mark_All_As_Read()
On Error Resume Next
Set ol = New Outlook.Application
Set olns = ol.GetNamespace("MAPI")
Set oInbox = olns.GetDefaultFolder(olFolderInbox)
Debug.Print "Start of Loop:"
For Each oFolder In oInbox.Folders
Debug.Print " Folder: " & oFolder.Name & " " & oFolder.UnReadItemCount & " UnRead Items | " & oFolder.Items.Restrict("[UnRead]=true").Count & " Real Count"
For Each oItem In oFolder.Items.Restrict("[UnRead] = True")
Debug.Print " Item: " & oItem & " --- UnRead? " & oItem.UnRead
oItem.UnRead = False
Debug.Print " -- Marked item as READ"
Next
Debug.Print " Done with: " & oFolder.Name
Next
Debug.Print "Macro Complete!"
End Sub
And here is the output of the script:

Start of Loop:
Folder: Monitoring 5 UnRead Items | 5 Real Count
Item: [+] : Critical : XXXX : XXXX : [Thresh] Interface Status - (#8)-x.x.202.93 Multilink1 Index 8 --- UnRead? True
-- Marked item as READ
Item: [-] : Critical : XXXX : XXXX : [Thresh] Interface Status - (#8)-x.x.202.93 Multilink1 Index 8 --- UnRead? True
-- Marked item as READ
Item: [+] : Critical : XXXX : XXXX-2801 : [Thresh] SNMP Status - XXXX-2801 --- UnRead? True
-- Marked item as READ
Done with: Monitoring
Folder: Tickets Closed 5 UnRead Items | 5 Real Count
Item: Ticket number 021988 for XXXX -Minneapolis has been closed --- UnRead? True
-- Marked item as READ
Item: Ticket number 022082 for XXXX has been closed --- UnRead? True
-- Marked item as READ
Item: Ticket number 021982 for XXXX Corporation has been closed --- UnRead? True
-- Marked item as READ
Done with: Tickets Closed
Folder: Tickets General 5 UnRead Items | 5 Real Count
Item: SEV 1 escalation XXXX, ID: 022076 --- UnRead? True
-- Marked item as READ
Item: Automated escalation for XXXX Agency Ticket ID: 021933 --- UnRead? True
-- Marked item as READ
Item: Logged time in ticket activities --- UnRead? True
-- Marked item as READ
Done with: Tickets General
Folder: Tickets Opened 5 UnRead Items | 5 Real Count
Item: A ticket for XXXX XXXX priority of Critical Ticket ID: 022084 has been opened --- UnRead? True
-- Marked item as READ
Item: A ticket for XXXX priority of Medium Ticket ID: 022083 has been opened --- UnRead? True
-- Marked item as READ
Item: Ticket number 022083 for XXXX has been opened --- UnRead? True
-- Marked item as READ
Done with: Tickets Opened
Folder: Tickets Unassigned 5 UnRead Items | 5 Real Count
Item: Priority Medium Unassigned Ticket Notification for XXXX --- UnRead? True
-- Marked item as READ
Item: Priority Medium Unassigned Ticket Notification for XXXX --- UnRead? True
-- Marked item as READ
Item: Priority Critical Unassigned Ticket Notification for XXXX XXXX --- UnRead? True
-- Marked item as READ
Done with: Tickets Unassigned
Macro Complete!
After the Macro runs I am left with 2 remaining UNREAD mail items in each folder.

Any VBA gurus out there that can lend a hand?

UPDATE:
I had one of the folders with 36 UnRead Items, and the other folders all had zero UnRead Items. This is the result:

Start of Loop:
Folder: Monitoring 0 UnRead Items | 0 Real Count
Done with: Monitoring
Folder: Tickets Closed 36 UnRead Items | 36 Real Count
Item: Ticket number 021899 for XXXXX has been closed --- UnRead? True
-- Marked item as READ
Item: Ticket number 021903 for XXXXX, Murphy has been closed --- UnRead? True
-- Marked item as READ
Item: Ticket number 021902 for XXXXX (Cincinnati, OH) has been closed --- UnRead? True
-- Marked item as READ
Item: Ticket number 021909 for XXXXX Financial has been closed --- UnRead? True
-- Marked item as READ
Item: Ticket number 021908 for XXXXX - Atlanta has been closed --- UnRead? True
-- Marked item as READ
Item: Ticket number 021904 for XXXXX - Grand Ave St. Paul has been closed --- UnRead? True
-- Marked item as READ
Item: Ticket number 021912 for XXXXX - Duluth, Ga has been closed --- UnRead? True
-- Marked item as READ
Item: Ticket number 021905 for XXXXX has been closed --- UnRead? True
-- Marked item as READ
Item: Ticket number 021910 for XXXXX Software, Inc has been closed --- UnRead? True
-- Marked item as READ
Item: Ticket number 021898 for XXXXX has been closed --- UnRead? True
-- Marked item as READ
Item: Ticket number 021913 for XXXXX has been closed --- UnRead? True
-- Marked item as READ
Item: Ticket number 021907 for XXXXX has been closed --- UnRead? True
-- Marked item as READ
Item: Ticket number 021906 for XXXXX LLC has been closed --- UnRead? True
-- Marked item as READ
Item: Ticket number 021911 for XXXXX has been closed --- UnRead? True
-- Marked item as READ
Item: Ticket number 021900 for XXXXX (formerly Coeus) has been closed --- UnRead? True
-- Marked item as READ
Item: Ticket number 021901 for XXXXX has been closed --- UnRead? True
-- Marked item as READ
Item: Ticket number 021864 for XXXXX has been closed --- UnRead? True
-- Marked item as READ
Item: Ticket number 021860 for XXXXX Inc. has been closed --- UnRead? True
-- Marked item as READ
Done with: Tickets Closed
Folder: Tickets General 0 UnRead Items | 0 Real Count
Done with: Tickets General
Folder: Tickets Opened 0 UnRead Items | 0 Real Count
Done with: Tickets Opened
Folder: Tickets Unassigned 0 UnRead Items | 0 Real Count
Done with: Tickets Unassigned
Macro Complete!
It only marked 18 of the 36 Items as Read. WTF?

UPDATE 2:
I've noticed a pattern. The macro will always only mark HALF of the actual number of UnRead Items.

So when I ran the macro in the above example (with 36 Unread items) this is what happened.

UnRead Items Macro Was Ran Remaining UnRead Items
36 Once 18
18 Twice 9
9 Three times 4 (It marked 4.5 rounded up)
4 Four times 2
2 Five times 1
1 Six times 0

ez4me2c3d
07-24-2007, 10:10 PM
Solution:
So I worked it out further, and it turns out I needed to make a choppy *** macro to get this thing to act like I want it. Which still isn't that great.

Sub Mark_All_As_Read()
On Error Resume Next
Set ol = New Outlook.Application
Set olns = ol.GetNamespace("MAPI")
x = 0
Set oInbox = olns.GetDefaultFolder(olFolderInbox)
For Each oFolder In oInbox.Folders
If oFolder.UnReadItemCount > 0 Then
For i = 1 To oFolder.UnReadItemCount * 1.5
If oFolder.Items.Item(i).UnRead Then
oFolder.Items.Item(i).UnRead = False
x = 0
Else
x = x + 1
If x = 5 Then
Exit For
End If
End If
Next
x = 0
End If
Next
End Sub

So it basically looks at the count of unread items in each folder

If there are 0, then it skips that folder

If there are > 0 then it sets a For...Next loop to the number of unread items * 1.5 (so if there are 20 items, then the loop will go for 30) This accounts for some read items mixed in with unread items

Then it checks each mail item the folder and if it's unread, it marks it as read.

If there are 5 consecutive read mail items, the loop quits and moves to the next folder.

TheShaner
07-24-2007, 10:11 PM
This may not be it, but I'm trying to find a difference in the way you present your unread items:

Change:

For Each oItem In oFolder.Items.Restrict("[UnRead] = True")
To:

For Each oItem In oFolder.Items.Restrict("[UnRead]=true")
You have the version I'm asking you to change to in your "real count" code. That code seems to count all of the items that are marked as unread correctly, so you would want to keep the code identical.

If that doesn't work, try changing your code to the below to see what happens. It will cause more overhead since you're not restricting the items in the For loop to only unread, but it'll either at least work or give you more insight to the problem:

For Each oItem In oFolder.Items
If oItem.UnRead Then
Debug.Print " Item: " & oItem & " --- UnRead? " & oItem.UnRead
oItem.UnRead = False
Debug.Print " -- Marked item as READ"
End If
Next
HTH!

-Shane

ez4me2c3d
07-25-2007, 05:18 AM
My folders have thousands of e-mails in them, and policy dictates I cannot delete them. So I need to limit the result set. Otherwise it can't take several minutes to run.

Thanks for your help though. I do appreciate it.

ez4me2c3d
07-25-2007, 05:23 PM
Another guy made a comment which lead me to the creation of this new VBA code

Sub Mark_All_As_Read()
Set ol = New Outlook.Application
Set olns = ol.GetNamespace("MAPI")
Set oInbox = olns.GetDefaultFolder(olFolderInbox)
For Each oFolder In oInbox.Folders
Do While oFolder.Items.Restrict("[UnRead]=true").Count > 0
oFolder.Items.Restrict("[UnRead]=true").Item(1).UnRead = False
Loop
Next
End Sub
It's a lot cleaner and more compact. It doesn't iterate items that are already read. And! It's much faster than my first attempt.

Thanks for your help.

Now if there was just a method like such: :)

Sub Mark_All_As_Read()
Set ol = New Outlook.Application
Set olns = ol.GetNamespace("MAPI")
Set oInbox = olns.GetDefaultFolder(olFolderInbox)
For Each oFolder In oInbox.Folders
oFolder.MarkAllAsRead
Next
End Sub



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum