Get autocomplete address list of Outlook in VBA - vba

I am trying to add all my "autocompleted addresses" to a new contact folder but I can't get those addresses. What I call "autocompleted addresses" are the addresses saved when you send an email to somebody and you type it again in the "To" field of a new email.
I know I can get all the Global Address List by using
Set objOutlook = CreateObject("Outlook.Application")
Set myNameSpace = objOutlook.GetNamespace("MAPI")
Set GAL = myNameSpace.AddressLists("Offline Global Address List")
But how can I get my autocompleted addresses ?
I am using Outlook 2010 and my account is an Exchange Account.
Thank you for your help and your time.
EDIT
My complete code :
Set objOutlook = CreateObject("Outlook.Application")
Set myNameSpace = objOutlook.GetNamespace("MAPI")
Set folder = myNameSpace.GetDefaultFolder(OlDefaultFolders.olFolderInbox)
Set storage = folder.GetStorage("IPM.Configuration.Autocomplete", OlStorageIdentifierType.olIdentifyByMessageClass)
Set propacc = storage.PropertyAccessor
Set got = propacc.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x7C090102")
Problem : got is empty...

instead of
Set got = propertyAcc.GetProperty(yadayada)
Don't use Set... just
got = propertyAcc.GetProperty("http://schemas.microsoft.com/mapi/proptag/0x7C090102")
This will give a zero-based array of the bytes used in the text stream.
got(0) = 13
got(1) = 240
etc etc...
From there, you can analyze each byte to get the text... but it would be very very ugly to parse it all out, when Redemption does that for you. In fact, if you've gotten this far in the post, then you've probably sorted out that it would be a better use of time to figure out how to use Redemption than to build your own parser for this purpose.

Autocomplete (nickname) stream is stored in a hidden (associated) message with the message class of "IPM.Configuration.Autocomplete" in the Inbox folder. Its format is documented at https://msdn.microsoft.com/en-us/library/office/ff625288.aspx. You can access that message using MAPIFolder.GetStorage.
If using Redemption is an option (I am its author), it exposes nicknames through the RDOStore / RDOSession.Nicknames collection.
Also note that in case of Outlook VBA you do need to create an instance of the Outlook.Application object, you already have an intrinsic Application variable pointing to that object.

Related

Reprocessing Outlook Undelivered Mail

I have an Exchange mailbox with a bunch of Outlook ReportItem Undelivered messages. I am attempting to reprocess the undelivered messages via an Outlook VBA script by invoking the "SendAgain" operation on the ReportItem messages. My issue is that the ReportItem does not have a send method, so I have no way of actually sending the reprocessed messages. I am using the following code to go through the messages:
Dim objApp As Outlook.Application
Dim objNameSpace As NameSpace
Dim journalAlertInbox As Folder
Dim objInspector As Inspector
Dim resendItem As ReportItem
Set objApp = CreateObject("Outlook.Application")
Set objNameSpace = objApp.GetNamespace("MAPI")
Set journalAlertInbox = objNameSpace.Stores.Item("thestore").GetDefaultFolder(olFolderInbox)
For Each folderItem In journalAlertInbox.Items
If TypeOf folderItem Is ReportItem Then
folderItem.Display
Set objInspector = folderItem.GetInspector
objInspector.CommandBars.ExecuteMso "SendAgain"
Set resendItem = Application.ActiveInspector.CurrentItem
Set objInspector = resendItem.GetInspector
''how do I send the item that is now displayed?
''resendItem.Close olSave
folderItem.Close olDiscard
End If
Next folderItem
I thought I might be able to save the displayed message as a draft, however If I uncomment the resendItem.close olSave line this results in a message in my Outlook Drafts folder of type ReportItem. I can open up the saved draft message it the Outlook GUI and click the send button, but I do not see a way to actually invoke the send operation programmatically. Examining the message in drafts shows it to be of type ReportItem, which does not have a .Send method.
How can I invoke the "Send" operation on the Report Item? I can clearly see the "Send" button, but there seems to be no programmatic way of actually clicking it.
OOM does not expose any functionality that allows to link a ReportItem object to the original MailItem, and, generally, there might not be any kind of link between the two. The best you can do is to retrieve PR_ORIGINAL_SEARCH_KEY MAPI property (or PR_REPORT_TAG, which includes both the search key and the store/Sent Items folder entry id) using ReportItem.PropertyAccess.GetProperty and try to find a matching message in the Sent Items folder. You can see these properties in OutlookSpy (I am its author).
Keep in mind that OOM does not allow to search on the binary (PT_BINARY) properties in Items.Find/Restrict.
If using Redemption is an option (I am also its author), it exposes RDOReportItem.FindOriginalItem method.
Once you have the original item, you can make a copy and try to send it again.
The ReportItem doesn't represent the original item which is failed to be sent. Also it doesn't contain any relationship with the original mail item, so you will not find any property or method available in the Outlook object model. Your existing solution looks good.
You may also try using the ReportItem.GetConversation method which obtains a Conversation object that represents the conversation to which this item belongs. So, you may try getting the previous item from the conversation, it could be the original item which has been submitted.

How to change a 'Setting" in Visual Basic to Variant or Object Type?

I am trying to build a Addin for Outlook that allows a user to select a folder they want emails moved to when they hit a certain button. I am ussing a project setting called "EmailDestFolder" to define the folder after the user selects it, thats done as follows:
Dim objOutlook As Object
Dim objOlNamespace As Object
objOutlook = CreateObject("Outlook.Application")
objOlNamespace = objOutlook.GetNamespace("MAPI").PickFolder
If objOlNamespace.Name.Length >= 1 Then
My.Settings.EmailDestFolder = objOlNamespace
End If
Issue is this doesnt work when the setting type is set to "String" I tried changing the setting type to: "Microsoft.Office.Interop.Outlook.MAPIFolder" but I get an error saying that settings cannot be an abstract type. Is there a way to change it to something like a Variant or Object type so I can set the folder.
Read the MAPIFolder.EntryID property to a string variable. When you need to open that folder later, use Namespace.GetFolderFromID.

Extract email metadata with VBA script

I have a folder full of emails that are a custom message class (iXOS-Archive, related to OpenText Enterprise Archive). Each email has a custom metadata property, visible within Outlook, called "Document Identifier". I'm trying to extract this from the emails using a VBA script. I found a script that extracts common metadata (To, From, Subject etc.) from the emails and writes it to Excel. This works well.
http://spreadsheetpage.com/index.php/tip/getting_a_list_of_file_names_using_vba/
I've tried debugging the script and looking within the email properties, but I cannot find any collection that contains custom metadata.
Does anyone know how I can access the custom metadata through the VBA script?
You will probably not be able to do this using a FileSystemObject or DIR function (as given in the code you linked to, above).
I am unable to test without a suitable example, but this might work:
Bind Outlook to Excel
Open the MSG file in Outlook
Use the Outlook object model to review the MSG file's .ItemProperties
Practically speaking you will set this up in a loop, similar to your example code, but for the sake of testing, try it out on a single file and see if this will help you.
'Requires reference to Outlook object model
Sub foo()
Dim olApp As Outlook.Application
Dim msg As Outlook.MailItem
Dim properties As Outlook.ItemProperties
Dim p As Long
Set olApp = GetObject(, "Outlook.Application")
Set msg = olApp.CreateItemFromTemplate("C:\your filename.msg")
Set properties = msg.ItemProperties
For p = 0 To properties.Count - 1
Debug.Print properties(p).Name
Next
Set msg = Nothing
Set olApp = Nothing
End Sub
This should print the list of ItemProperties in the Immediate window, scroll through that list and check to see if the one you're looking for -- "Document Identifier" -- is included. If so, then this should work and you can modify as needed to do whatever it is you want to do with that information.
I cannot be of further assistance unless you can provide a test/sample version of this email format.
Cheers.

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")

Open Outlook mail Item using EntryID, StoreID, and / or PR_ENTRYID

NOTE: I'm using VBA and Office 2007. (I would use C#, but the project parameters don't allow this)
I'm attempting to find some method in Outlook, or an API, that will allow me to open an Outlook mail item by providing either the Outlook EntryID or the MAPI "PR_ENTRYID" property from an Access Database. I have found many references to said code, but I have never seen anyone actually post a solution. I have attempted in include references to mapi32.dll and OLMAPI32.dll, but I get the following error: "Can't add a reference to the specified file." I'm guessing this is because those dll's are meant for .NET.
Any help you can give would be greatly appreciated.
Use Namespace.GetItemFromID. Note the second parameter (store id) is optional. You can omit it if the store in question was already touched by Outlook is in the current session. If not, Outlook will raise the "unknown entry id" exception. If the store entry id is specified, Outlook will open it first, and the store provider will have a chance to register its entry ids with the MAPI system.
set App = CreateObject("Outlook.Application")
set NS = App.GetNamespace("MAPI")
NS.Logon
set Msg = NS.GetItemFromID(EntryID)
MsgBox Msg.Subject
For C#:
var ns = OutlookApp.GetNamespace("MAPI");
var item = ns.GetItemFromID(entryId) as MailItem;
Where OutlookApp has Microsoft.Office.Interop.Outlook._Application type.