How To Only Retrieve Top X Items from Outlook Folder - Interop C# - c#

I am writing a C# application where I want to loop through the 500 most recent emails in a given folder. The reason is because getting all the emails takes a long time using the below lines:
MAPIFolder folder = outlookApp.GetNamespace("MAPI").GetDefaultFolder(OlDefaultFolders.olFolderInbox);
List<MailItem> items = folder.Items.OfType<MailItem>().ToList();
However, I know that what I am searching for each time is always going to be a recent email, so there's no need to get an entire year's worth of emails each time (over 8000, and I get less emails than the average employee at my job).
So, is there a way to only retrieve a certain amount of emails from a folder with Microsoft.Office.Interop.Outlook? Thanks in advance.

Iterating over all items in the folder is not really a good idea:
List<MailItem> items = folder.Items.OfType<MailItem>().ToList();
Instead, you need to use the Find/FindNext or Restrict methods of the Items class. They allow getting only items that correspond to your conditions. 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
Instead of getting recent 500 emails you may retrieve emails for a day, few days, week and etc. So, you can process items in bunch. For example:
criteria = "[ReceivedTime] > '" _
& Format$("6/12/20 3:30PM","General Date") & "'"
You may find the Filtering Items Using a Date-time Comparison article helpful.

Related

How to get a collection of emails beginning with the subject line "RE:" in Outlook using C#

Extreme novice with C# here. I'm attempting to get a count for the number of emails that have a subject line that begins with "RE:" that were sent to me within the last month. For example something like below but instead of restricting to emails that only have "RE:" as the subject, I'd like to restrict only to emails that have a subject line beginning with "RE:" and that have a sent date within the last month. Any help would be much much appreciated. Thank you!
Outlook.Items repliedItems = inbox.Items.Restrict(#"[Subject] = ""RE:""");
You can use DASL queries with the ci_startswith or ci_phrasematch operators. For example, the following query performs a phrase match query for RE: in the message subject:
filter = "#SQL=\"http://schemas.microsoft.com/mapi/proptag/0x0037001E\" ci_phrasematch 'RE:'"
Also you'd need to combine another search criteria to the string passed to the Restrict method - items were sent to me within the last month. Use the MailItem.ReceivedTime property which returns a date indicating the date and time at which the item was received. The following articles explains how to use DateTime structures for filtering items in Outlook:
How To: Use Restrict method in Outlook to get calendar items
How To: Retrieve Outlook calendar items using Find and FindNext methods

How to filter all EWS items by excluding those which match Id's from list

I want to be able to apply a SearchFilter based off the Item Id when I find all items in a selection of folders.
I can easily get all items and then using linq apply a where clause like
(w => !uniqueItemIdList.Contains(w.Id.UniqueId))
But the issue is this would be after it's pulled 1000's of mail items instead of during the original find of the items.
My goal is to pull all emails copy them to a db then afterwards to only pull emails that I haven't already copied by excluding emails with matching unique ids.
So far everything indicates that this isn't possible and that I could only search on individual fields like FolderId = "..." or subject that contains "...", with no mention of a list or exclusion.
Any help would be much appreciated.
ItemId isn't a searchable property so what you trying to do with a SearchFilter won't work. SyncFolderItems https://msdn.microsoft.com/en-us/library/office/aa563967(v=exchg.150).aspx does allow an exclusion list based on ItemId (but I would think for a large number of items this wont scale) an easier solution would be just use a SearchFilter based on Item Creation Date.

Slow iterating thru Outlook.Items to find contacts

I am having an issue where I am trying to find at least one contact inside any of the outlook folders. I have a recursive function that iterates thru the items inside a folder and if the item is of type contact then we add it to a list. However, this code runs extremely slow when folders have a large number of records say 4000 items.
Is there any way just to get contacts or is there a way to make this code more efficient?
foreach (var item in folderBase.Items)
{
if (returnFirst && result.Count > 0)
break;
if ((item is Outlook.ContactItem))
{
result.Add((Outlook.ContactItem)item);
}
}
Firstly, storing 4000 live Outlook objects in a list is a bad idea: you will run out of RPC channels in case of online Exchange store at item 255. Store the entry ids and use them to call Namespace.GetItemFromID() when you actuqlly need it; then release it as soon as you are done.
Secondly, use MAPIFolder.GetTable - it will let you retrieve values from multiple items without actually opening them; perfect in your case. Try something like the following (VB script):
set Folder = Application.ActiveExplorer.CurrentFolder
set Table = Folder.GetTable("[MessageClass] = 'IPM.Contact' ")
Table.Columns.Add("EntryID")
while not Table.EndOfTable
set Row = Table.GetNextRow()
vEntryId = Row.Item(1)
Debug.Print vEntryId
wend
You need to use the Find/FindNext or Restrict methods of the Items class instead.
Read more about these methods and see the sample code in the following articles:
How To: Use Restrict method in Outlook to get calendar items
How To: Retrieve Outlook calendar items using Find and FindNext methods
You can use the MessageClass property of Outlook items to get the contact items only.

Retrieve StoreID for MailItem (within Outlook Selection)

I need to iterate through the MailItem items within a Selection and read their EntryID and StoreID values in order to be able to retrieve the mail items again later (for background processing through Redemption). Is there a way of retrieving the StoreID for a MailItem directly?
I know that it may be retrieved through the StoreID property of its parent Folder; however, this seems quite inefficient, since it must instantiate (and release) the COM object for the parent folder for each item. Is there a more efficient way to achieve this?
Edit: I cannot use the Selection.Parent property since it was only introduced in Outlook 2007, and I need to support Outlook 2003. Additionally, Sue Mosher states:
The Parent object of a Selection would be an Explorer, so you could use Selection.Parent.CurrentFolder.Store.
However, when one performs a search across “All Outlook Items”, it seems that CurrentFolder would always point to a search folder within the main store, which is typically the Exchange mailbox:
\\Mailbox - <username>\search folders\All Outlook Items
Since the search may match items in other stores, the CurrentFolder.Store would not necessarily correspond to the store of the selected items, making this approach unreliable.
Instead of getting the parent for each item, could you get the parent once by using Selection.Parent?

Programmatically receive new emails using Lotus Notes

Is there a method or any way to receive or get new emails from the server for the Lotus Notes Domino object in C sharp?
When looping through the Inbox view all I get is existing emails and not new emails. So I am trying to initiate a receive.
"Unread marks" or "Unread email" is a unique function to Lotus Notes that is not exposed as an API in Java or .Net. But you can programmatically emulate it without too much complexity. Is it possible for you to try this:
If your CSharp object can have a "last Checked" date/time value that is set when you traverse the inbox.
Now whilst looping through the inbox, get the created date of each document.
In the case of email in a Lotus Notes database, this is the date the email hit the account. So it should be a fairly reliable means of determining the arrival date of the email.
The created date property is under the NotesDocument object as "created". This should return a date/time value that you can use. Any document that is newer than the "last checked" value would therefore be new mail.
If you have a particularly large inbox to loop through, you can get the inbox object (which can be treated like a view), and also use "GetAllUnreadEntries" method on the NotesView object.
Links to example code is in links above.
If you're running into a situation where new emails are added to the view you are looping through after you've started looping, then you can call the NotesView.Refresh method to update the NotesView object.
Otherwise the NotesView object will contain all the emails in the view. If by "new" you're talking about unread emails, that's a different story. Notes 8.0 introduces a method called GetAllUnreadEntries which would help you navigate through any unread view entries. The backend document itself doesn't store a read/unread property.
Hope this helps!

Categories