Accessing OlExchangeStoreType from outside Outlook - vba

I'm currently working on a small application that allows me to make some changes to a user's profile, namely add or remove specific PST files and transferring Contacts/Calendars from attached PST files into their primary mailbox. This is for Outlook 2007. After some searching, I found an enumeration in Outlook that I would like to use if possible: OlExchangeStoreType.
I want to use it to help determine which store I'm operating on (eg, public, primary, or PST file). I'm just not sure how I can reach it. I'm using late binding in my code to work around possible problems moving between different versions. Current Binding:
Dim olApp,olNS
On Error Resume Next
olApp = GetObject(, "Outlook.Application")
On Error GoTo 0
If olApp Is Nothing Then
olApp = CreateObject("Outlook.Application")
olNS = olApp.GetNamespace("MAPI")
Else
olNS = olApp.GetNamespace("MAPI")
End If
This works fine. If I try GetObject(, "Outlook") instead, I get "Cannot create ActiveX component."
Is there an interface I can use for Outlook that will give me access to the public enumerations?
And as for why I'm doing it this way, I don't want to have to deal with macro security nor pushing out the macro to multiple users. I'm also new to using VBA so there may be an easier method than what I'm trying to do.
Let me know what you think. Thanks,

Figured it out. I was originally under the impression that the enumeration values were objects of a class, but they're just integers.
I found that
StoreObj.ExchangeStoreType
will return an integer that matches what OlExchangeStoreType uses. I'll just recreate the enum in my class.
Thanks,

Related

What does CreateItem do in VBA for outlook emails?

Why do we use CreateItem to create a MailItem in VBA as opposed to the New keyword? More generally, what’s the difference between the two methods? I noticed that to create an instance of the app we do:
Set OutlookApp = New Outlook.Application
However for the MailItem we do:
Set OutlookEmail = OutlookApp.CreateItem(olMailItem)
Tried the above method and it worked but am wondering why it works like that.
They are entirely different lines of code. In the first case a new Outlook Application instance is created:
Set OutlookApp = New Outlook.Application
That is actually all what you could do with the New operator and Outlook object model. Everything else is retrieved from using methods and properties available in the Outlook object model. For example, there are several ways of creating a new MailItem instance:
Set OutlookEmail = OutlookApp.CreateItem(olMailItem)
And
Set OutlookEmail = folder.Items.Add(olMailItem)
The difference is where the item will be saved when calling Save().
You can read more about possible ways of creating Outlook items in the article which I wrote for the technical blog, see How to create and show a new Outlook mail item programmatically: C#, VB.NET.

Outlook 2003: Connect IMAP server with VBA

Sometimes Outlook (2003) loses the connection to one or more IMAP server. With VBA scripts that are supposed to move mails to these mailboxes, for example, I get this error message:
"Runtime error '-972759285 (c604df0b)':
Connection to server is unavailable. Outlook must be online or connected to complete this operation."
I then first have to click on "File" - "Connect to [MAILBOX...]" to establish this connection manually.
I am looking for a VBA solution to automatically connect to multiple mailboxes (IMAP only), but I don't know what to look for in VBA references.
I tried this:
Sub MyTest()
Dim myNameSpace As Outlook.NameSpace
Set myNameSpace = Application.GetNamespace("MAPI")
Set Application.ActiveExplorer.CurrentFolder = myNameSpace.Folders("C-Interessenten").Folders("Interessenten")
Set myNameSpace = Nothing
End Sub
or this
Sub IsOLOffline()
'Determines whether Outlook is currently offline.
Dim myOlApp As Outlook.Application
Dim myNameSpace As Outlook.NameSpace
Set myOlApp = New Outlook.Application
Set myNameSpace = myOlApp.GetNamespace("MAPI")
Debug.Print myNameSpace.Offline
End Sub
Thank you for an idea.
The Outlook object model doesn't provide anything for that out of the box.
The Offline property of the Namespace class returns valid information only for an Exchange profile. It's not intended for non-Exchange account types such as POP3, IMAPI, and HTTP.
You may try to use SyncObjects property of the Namespace class. It returns a set of SyncObject objects representing the Send/Receive groups for a user.
The OnError event is fired when Microsoft Outlook encounters an error while synchronizing a user's folders using the specified Send\Receive group. So, it could help with detecting such cases and then initiating a new sync.
Public WithEvents mySync As Outlook.SyncObject
Sub Initialize_handler()
Set mySync = Application.Session.SyncObjects.Item(1)
mySync.Start
mySync.Stop
End Sub
Private Sub mySync_OnError(ByVal Code As Long, ByVal Description As String)
MsgBox "Unexpected sync error" & Code & ": " & Description
End Sub
A Send\Receive group lets users configure different synchronization scenarios, selecting which folders and which filters apply.
Use the Item method to retrieve the SyncObject object from a SyncObjects object. Because the Name property is the default property of the SyncObject object, you can identify the group by name.
Thank you for the food for thought. I have already experimented a bit by creating a separate group for each IMAP mailbox. Testing is taking a long time because the connections only break sporadically and I can't trigger the break manually. Nevertheless, I have more and more the impression that the SyncObject does not lead to a solution. Thanks anyway.
Is there perhaps the possibility to call the menu item "File" - "Connect to xxx" via vba, for example via FindControl()?

Outlook VBA not returning CurrentUser Recipient object on some Windows 10 machines

My work have started to roll out a new set of Lenovo ThinkCentre Windows 10 PCs. The issue is that on some models (but not all) my attempt to get the user's email address from Outlook fails due to Application.Session.CurrentUser not containing any information. If I could figure out a solution to this or a different method of obtaining the email address then I would be happy.
Here is the code that worked fine until they started installing new computers a few weeks ago:
Dim outApp As Object, outSession As Object
Set outApp = CreateObject("Outlook.Application")
Set outSession = outApp.Session.CurrentUser ' BREAKS HERE
currentuserEmailAddress = outSession.AddressEntry.GetExchangeUser().PrimarySmtpAddress
Set outApp = Nothing
End Function
On these new systems, attempting to run the code will throw runtime error 287 at the commented line. Adding outApp to the watchlist on a newer system shows that the CurrentUser object is null. On my PC I can expand out the CurrentUser object to see its properties, etc. but on the newer ones it is not expandable and just shows "<>" under the Value column.
I've raised a question with our tech support guys, but I had to explain to them the difference between a VGA cable and a DisplayPort cable the other day, so I'm not holding my breath there.
Try to check out the Accounts collection instead:
Namespace.Accounts.Item(1).SmtpAddress
Anyway, the runtime error 287 states that you triggered a security issue when dealing with the Outlook object model. To bridge the gap with the security issues you can:
Use a low-level API on which Outlook is based on - Extended MAPI. Also, you may consider using any third-party wrappers around this API such as Redemption.
Use components designed for turning off such issues. See Security Manager for Microsoft Outlook.
Set up any valid antivirus software.
Deploy a group policy to suppress such triggers in the OOM.
Application.Session can be null until you log to a profile. Change your code to
Dim outApp As Object, outSession As Object, outNamespace
Set outApp = CreateObject("Outlook.Application")
Set outNamespace = outApp.GetNamespace("MAPI")
outNamespace.Logon
Set outSession = outApp.Session.CurrentUser
Also keep in mind that GetExchangeUser() can return null for a non-Exchange user - your need to check for that.

Send Email from MS Project via Outlook

I am trying to open and populate emails from MS Project via Outlook. I have done this before from Excel, but when I drop the code into Project I get an error.
'Create and Set New Mail Item
Dim OutlookApp As Outlook.Application
Set OutlookApp = CreateObject("Outlook.Application")
Dim OutlookMail As Outlook.MailItem
Set OutlookMail = OutlookApp.CreateItem(OutlookMailItem)
The error triggers on the Dim OutlookApp line and reads, 'User-Defined Type Not Defined'
What am I forgetting here?
I'm not sure I understand the requirement, so I'm sending a blind shot. In Project 2007 you'll see a combo box at the top right of the screen, probably defaulting to "All Tasks". Choose the date range you want with the info you need and send this to your team along with any encouraging words that you need to motivate them.
Will this help?

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.