Is there any way to know which MailItems satisfy a given Rule?
I mean to move a set of emails by applying a Rule (as a one-off operation), but then know which were these.
You can use the Find/FindNext or Restrict methods to find Outlook items that satisfy to your conditions. Also you may find the AdvancedSearch method of the Application class helpful.
You can either parse the rule conditions (Rule.Conditions) and programmatically check if they apply to a particular message, or you can call Rule.Execute and let it do what it needs to do. You can set up event handler on the target folder (Items.ItemAdd) ahead of time to figure out which items were moved to the target folder.
Related
I am working on a simple Marco that use to download selected emails' attachments.
It was really a simple logic but I am still stuck.
I found out that my for each loop is always stop when it met the meeting request email.
(It almost took my whole day to figure it out that the meeting request is The Barricade.)
The problem can be fixed by deletion of the meeting request.
And yet, it is really annoying for a lazybones like me.
Therefore, I really curious that is there any method can let the for each loop just ignore/auto unselect meeting requests?
And I have already tried detect the email subject/context to seprate the meeting requests and normal mails.
But it seem like it would just exit the for each loop when it encountered the meeting request.
So currently I don't have any idea about how to fixing it.
Firstly, you need to show the relevant snippet of your code.
Secondly, you should not assume that you are only dealing with the MailItem objects - before accessing an of the MailItem-specific properties, check that the Class property (it is exposed by all OOM objects) is 43 (which is olMail).
I have the following rule in outlook:
have server reply using specific reply rule
My aim is now, to change the email text that gets send by the action with a vba script. The data we send out as a respones changes daily, so at the moment we have to change it by hand. I tried now many things, but don't come really to the possibility to change the text with vba.
I'm also not sure if i can get it with olRuleActionServerReply (because it has no item oder similar when i watch this action) or with olRuleActionTemplate...
I'm happy for any hint in this situation. Thank you in advance!
I tried to find anything in the documentation but didn't find anything helpful.
There is no way to use a dynamic reply with a different text used for the message body. You need to set up a different rule for that or handle incoming emails in VBA without rules involved.
For example, you could handle the NewMailEx event of the Application class where you could check the incoming email and prepare the response and send it automatically. This event fires once for every received item that is processed by Microsoft Outlook. The item can be one of several different item types, for example, MailItem, MeetingItem, or SharingItem. The EntryIDsCollection string contains the Entry ID that corresponds to that item. Use the Entry ID to call the NameSpace.GetItemFromID method and process the item.
I have a macro to process my inbox which has 7000 emails (I know, I know) and it takes a while. Naturally, I made a user form to show the progress by settling a label with remaining email count.
During execution however, I noticed that the form would stop updating at random time, probably as outlook goes into non responsive due to the macro execution.
Yesterday I accidentally dragged the now not-updating form aside which revealed another instance of the form beneath it, and that one is being updated correctly!
What is the mechanism behind this? My macro only created one instance of the form.
Edits:
The code is to delete emails with the same subject as the selected email. It was like the following. I added the commented out lines (pb.hide and pb.show) which somewhat solved the problem, although the flicker from hide/show is visually noticeable.
j = myitems.Count \ 20
l = 0
For i = myitems.Count To 1 Step -1
If l < j Then
l = l + 1
Else
l = 0
'pb.Hide
pb.Caption = "Emails to be processed: " & i
'pb.Show
End If
If TypeOf myitems(i) Is Outlook.MailItem Then
If myitems(i).ConversationID = selectedConversationID Then
myitems(i).Move deletedItemsFolder
ElseIf myitems(i).subject = selectedSubject Then
myitems(i).Move deletedItemsFolder
End If
End If
Next i
I have since switched to the Restrict method to get emails with same subject (as well as the GetConversation mehod) which takes seconds so the form is useless now. But they are not foolproof. There are times the selected email itself is not returned. Anyway, no biggie.
VBA is a single-threaded environment not designed for running secondary threads. If you consider creating a COM add-in you could use a low-level code such as Extended MAPI (or any other third-party wrappers around that api such as Redemption) which allows running secondary threads and deal with a store. So, you could move your loop on a secondary thread releasing the UI one (the main thread). Also it makes sense to consider using proper OOM methods and properties that can help to speed up the process of searching for specific items in Outlook. For example, you may consider using the Find/FindNext or Restrict methods of the Items class. They allow getting only items that correspond to the search criteria. 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`
The AdvancedSearch method of the Application class can be helpful as well. The key benefits of using the AdvancedSearch method in Outlook are:
The search is performed in another thread. You don’t need to run another thread manually since the AdvancedSearch method runs it automatically in the background.
Possibility to search for any item types: mail, appointment, calendar, notes etc. in any location, i.e. beyond the scope of a certain folder. The Restrict and Find/FindNext methods can be applied to a particular Items collection (see the Items property of the Folder class in Outlook).
Full support for DASL queries (custom properties can be used for searching too). To improve the search performance, Instant Search keywords can be used if Instant Search is enabled for the store (see the IsInstantSearchEnabled property of the Store class).
You can stop the search process at any moment using the Stop method of the Search class.
I wrote vba script to duplication my main calendar to another calendar, including recurring meeting. All is well except when the organizer do out-of-order modifications to the recurring meeting as meeting exceptions. This triggers error for .GetOccurrence(). The solution I can think of is to reset the recurrence pattern (.Exceptions.Count=0) and redo each and every exceptions again. May I know how can I reset the recurrence pattern so that there is no exception?
Thanks!
May I know how can I reset the recurrence pattern so that there is no exception?
The Outlook object model doesn't provide any method or property for that. You need to re-create an appointment anew and set up a recurrence pattern.
Many thanks for the reply. I re-work my program to avoid the need to reset the recurrence pattern. The key realization for me is the function of Original Date. This is the "key" that link my main calendar and my duplicated calendar. I need to loop through all the exception to find the appointment that matched based on original date. With that, I can then use exception(i).start as the key to GetOccurrence().
If you are getting an error in the GetOccurrence() method, that means you are not passing the right date - you need to trap the exception and use the RecurrencePattern.Exceptions collection instead.
If you still want to reset the pattern and using Redemption (I am its author) is an option for you, it exposes RDOExceptions.Clear method to remove all exceptions from an appointment as well as RDOExceptions.Restore to remove a particular exception
I am building a REST/JSON based service which has in it's API a couple of collections that contain items. All these items are of the same type.
As an example: The service much resembles a TODO list with collections for items that still need to be done, are in the progress of being completed and are finished.
The API would be something like
/todo/new
/todo/inprogress
/todo/finished
So how would one define an instruction to move an item from the /todo/new to the /todo/inprogress ?
Basically both collections are as much responsible to perform the move. Should one of them be responsible? or should I make another API called /todo/item which will receive the move instruction?
Ideally you would use the PATCH method to modify a single item.
PATCH /todos/:id?status=finished
However PATCH is infrequently used and server/client support isn't always present. You may wish to use PUT instead.