What is the VBA property for: Server folder contains x items? - vba

I like to compare the amount of items in each folder on the Exchange server with the amount of items in my local Outlook file.
In Outlook I can use the following to get the item count per folder
Dim Folder As Outlook.MAPIFolder
Set Folder = objNS.Folders("xxx").Folders("Inbox")
Debug.Print Folder.Items.Count
How do I get the item count on the server like in the following screenshot?

To find out the number of items in a server (online) folder, you will need to open that folder in the online mode.
In Extended MAPI (C++ or Delphi) you would need to use the MAPI_NO_CACHE bit when calling IMAPISession::OpenEntry - you can play with that bit in OutlookSpy (I am its author): click IMAPIFolder button, select PR_ENTRYID property, right click, select IMAPISession::OpenEntry, make sure MAPI_NO_CACHE is checked. One you do that, you can retrieve the count either from the IMAPITable contents table or by reading the PR_CONTENT_COUNT (0x36020003) MAPI property from the folder itself.
Outlook Object Model will not let you override the caching mode on the per folder/message level - the whole profile must have the right connection mode.
In case of languages other than C++ or Delphi, you can use Redemption (I am also its author) - its versions of GetFolderFromID, GetMessageFromID, etc. allow to pass flags to be used by IMAPISession::OpenEntry.
MAPI_NO_CACHE = &H0200
MAPI_BEST_ACCESS = &H0010
set OomFolder = Application.ActiveExplorer.CurrentFolder
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set RdoFolder = Session.GetFolderFromID(OomFolder.EntryID, , MAPI_NO_CACHE Or MAPI_BEST_ACCESS)
MsgBox "Number of items in the online folder: " & RdoFolder.Items.Count

Related

How to bulk export Attachments from emails (which are emails) to another folder within Outlook

I need to extract .msg attachments from emails in a range and save these into another outlook sub-folder. This works currently by dragging the attachment into a sub-folder of 'inbox' but is there a quicker way?
I have searched around a bit and found ways to extract them to a local folder but i need them to be contained within outlook.
I appreciate any help and suggestions.
Thanks.
There are two problems here - first is accessing embedded message attachments without saving them first as MSG file. Second is importing the MSG files back - you can use Application.CreateItemFromTemplate, but the item will be unsent. You can use Namespace.OpenSharedItem, and then use MailItem.Move, but it is still a kludge.
There issn't much much you can do in OOM alone. Extended MAPI would work, but it is C++ or Delphi only. If using Redemption is an option (I am its author), you can use EmbeddeedMsg property exposed by the Redemption RDOAttachment object. You can also use RDOMail.CopyTo and pass a folder as a parameter to copy an embedded message attachment to a folder:
Set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set redItem = Session.GetMessageFromId(OutlookMessage.EntryID)
set redFolder = Session.GetFolderFromId(OutlookFolder.EntryID)
for each attach in redItem.Attachments
if attach.Type = olEmbeddeditem Then
attach.EmbeddedMsg.CopyTo OutlookFolder
End If
next

How to test FileName property of Outlook attachment

Some Outlook VBA code that saves email attachments according to their file names failed on an embedded bitmap image when it tried to access the FileName property of that "attachment."
How can I detect this? The FileName property is supposed to be a String but neither of these tests catches it:
If objAtt.FileName = "" Then ....
If objAtt.FileName = vbNullString Then ....
But every attempt to access this property throws a run-time error:
Outlook cannot perform this action on this type of attachment.
I would prefer not to use the DisplayName property if possible.
Also, it seems that I could filter the attachments according to the value of their FileType properties but I have not been able to find a list associating these Integer values with file types.
Advice is appreciated.
FileName property is only applicable to the regular olByValue type attachments. In your case you are most likely dealing with an olOLE type attachment, which is really a serialized embedded OLE object - the stream stores the bitmap (or metafile) that Outlook uses to represent the image as well as the actual data that the original application that created the data (MSPaint?) can use to edit it.
OLE attachment data is stored in the IStorage interface format. The actual format of the data depends on the application used to create it (MSPaint, Excel, etc.). Outlook Object Model does not let you save such attachments using Attachment.SaveAsFile.
Depending on the language you are using (C++ or Delphi would be best), you will need to open the PR_ATTACH_DATA_OBJ property as IStorage and then extract the data (IAttach::OpenProperty(PR_ATTACH_DATA_OBJ, IID_IStorage, ...)) . Take a look at the message with OutlookSpy (I am its author) - click IMessage button, go to the GetAttachmentTable tab, double click on the OLE attachment, select the PR_ATTACH_DATA_OBJ, right click, IMAPIProp::OpenProperty.
If using Redemption is an option (I am also its author), it extracts the the attachment data for a dozen or so most popular formats (MSPaint, Excel, Word, PDF, etc.):
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set OutlookMsg = Application.ActiveExplorer.Selection.Item(1)
set Msg = Session.GetRDOObjectFromOUtlookObject(OutlookMsg)
for each attach in Msg.Attachments
attach.SaveAsFile "c:\temp\" & attach.FileName
next

Moving an attachment from an email into an Outlook folder

I'm trying to take attachments from mails received and move them into a folder within Outlook.
I can move the entire message, and I've also worked out how to save the attachments to a drive, but neither of these things is what I'm looking for.
I was looking at something along the lines of the below, but I'm guessing there is no Attachment.Move similar to MailItem.Move.
Sub test1()
Dim olFolder As MAPIFolder
Set olFolder = Application.GetNamespace("MAPI").Folders("Mailbox - Test").Folders("Inbox")
Dim Item As Object
For Each Item In olFolder.Items
Set oMail = Item
For Each att In oMail.Attachments
att.Move Application.GetNamespace("MAPI").Folders("Enterprise Connect").Folders("Test")
Next
Next
End Sub
The attachments do not exist as standalone entities in folders - what you see if a message with a single attachment. The item's message class is IPM.Document.* - when you double click on an item like that, Outlook is smart enough to open the attachment instead of showing an inspector. Take a look at such an item with OutlookSpy (I am its author - click IMessage and Item buttons).
Outlook Object Model does not allow to create DocumentItem objects directly. But you can create a regular MailItem object, add an attachment using MailItem.Attachments.Add, then reset the MessageClass property appropriately - e.g. for a ".txt" attachment, look up HKEY_CLASSES_ROOT\.txt registry key, read the default value, append it to message class (IPM.Note.txtfile).
If using Redemption (I am also its author) is an option, it exposes the RDODocumentItem and allows to create document items directly (see the examples).
The Attachment class doesn't provide such methods. You need to save the attached file to the disk and then re-attach it anew to another Outlook item.
You may find the Getting Started with VBA in Outlook 2010 article helpful.

How to get a search folder criteria in Outlook

I am trying to edit a search folder in Outlook. But a search folder is treated as a regular folder:
in this MSDN reference, MS informs that "GetSearchFolders returns a Folders collection". I believe that, once I have the search folder filter, I will have to delete the current, edit the filter and create a new one - but that's the easy part. I have found e.g. here how to create and delete search folders. Everywhere I find create and delete, but nobody seems to know how to edit it or get the filter that applies to it...
Outlook Object Model will not let you edit the search criteria of a Search folder.
You can either use Extended MAPI (C++ or Delphi, you can see the search criteria in OutlookSpy (I am its author) if you select the search folder and click the IMAPIFolder button and go to the GetSearchCriteria tab) or Redemption (any language - I am also its author): it exposes the RDOSearchFolder object (lets you create and manage MAPI search folders) and RDOStore2.Searches collection - it exposes saved searches (backed up by MAPI search folders) visible under the Search Folders node in Outlook.
UPDATE: the following script will print the search criteria of all searches in the default profile:
set Session = CreateObject("Redemption.RDOSession")
Session.MAPIOBJECT = Application.Session.MAPIOBJECT
set Searches = Session.Stores.DefaultStore.Searches
for each Search in Searches
Debug.Print "-------------"
Debug.Print Search.Name & ": "
Debug.Print Search.SearchCriteria.AsSQL
next

lotus notes to VBA

I'm stuck with this problem for days
I have to read a specific mailbox in lotus notes and bring all the content into an excel spread sheet
but so far I have only been able to read the default inbox and have no way of switching to the other mailbox. I 'm really new to VBA can any one help me sort this out
here is the code I 'm using
Set NSession = CreateObject("Notes.NotesSession")
'get the name of the mailfile of the current user
DbLocation = NSession.GETENVIRONMENTSTRING("mail/mailbox", True)
'Get the notesdatabase for the mail.
Set NMailDb = NSession.GETDATABASE("mailboxer", DbLocation)
MsgBox (DbLocation)
I get an empty msgbox poping up
GetEnvironmentString() reads the notes.ini file. I'm not sure that's what you really want to be doing. Just from the syntax, I think you're using "mail/mailbox" as a placeholder for the actual path to the mailbox that you're looking for. E.g., you're really trying to read the mail from something like "mail/jsmith.nsf". (If I'm wrong, and you really do want to be reading the notes.ini file to get the location of the mail file, then your problem is that "mail/mailbox" is not a valid key for an ini file entry.)
My next assumption is that the Domino server where the mailbox lives is called "mailboxer", because that's what you're putting in the first argument of GetDatabase().
If I'm right about these things, then what what you need is
Set NMailDb = NSession.GETDATABASE("mailboxer", "mail/mailbox")
where "mail/mailbox" is replaced with the actual path to the mailbox that you are trying to open.
Some thoughts:
use Lotus.NotesSession if you don't have to interact with the Notes UI (Lotus.NotesSession is COM based, whereas Notes.NotesSession is OLE based)
make sure the user of the Notes client on the workstation running your VBA application has the rights require to open and read the mailbox
As D. Bugger stated, you need to be sure you have the Notes client installed on the same client machine your VB code will run, and you need to be sure the folder with the nnotes.exe file and the folder with the notes.ini file are in your environment path. (If not, you will get a COM error instantiating the Notes.NotesSession object.
If this helps, here is some starter code - not tested, but a rough guide... This walks through all documents in a Notes mailbox database, ignores anything except email documents (which have the form field = "Memo") and grabs some fields from each email.
Public Sub exportNotesMail(MailServer$, MailDBPath$)
Dim mailDb As Object, doc As Object, alldocs As Object, Session As Object
Set Session = CreateObject("Notes.NotesSession")
Set mailDb = Session.GETDATABASE(MailServer, MailDbPath$)
If mailDb.IsOpen = False Then mailDb.OPENMAIL
Set alldocs = mailDb.AllDocuments
Set doc = alldocs.GetFirstDocument
while not (doc is nothing)
If doc.GetItemValue("Form")(0) = "Memo" Then
thisSubject = doc.getItemValue("Subject")(0)
thisFrom = doc.getItemValue("From")(0)
' get more field values
' Export to Excel or wherever
End If
Set doc = alldocs.GetNextDocument(doc)
Next i
' done
End Sub
call exportNotesMail ("MyServer", "mail\myMailFile.nsf")