jpvevo
jpvevo

Reputation: 1

Accessing Text Body of Outlook MailItem Object - HTML and Plaintext

[EDIT] This problem does not appear to exist in C#. See reworked code at the bottom.

This has baffled me for two days now and has finally led me to making my first post on here.

I am coding in the visual basic editor of Excel 2007. I am using the Outlook 2007 object library, from Excel 2007, not Outlook. Not sure if this matters.

I'm writing a program that will run periodically on a mail folder and parse out important information from emails as they arrive. The emails in question look like plain text, but are identified by the VBA Locals window as being olFormatHTML! To test this, I click "reply" for one of the emails and then attempt to paste an Excel range into the body of the email, and Outlook gives me a popup (Compatibility Checker) that gives me the option to "switch to HTML". Looks like plaintext. Further, opening the message, clicking "Other Actions" --> Encoding yields Unicode (UTF-8). So why in the world, when I expand this MailItem object in the Locals window, does Excel think it is an HTML email?

This MailItem's .Body is empty, and this MailItem's .HTMLBody does not contain the actual contents of the email, which are nonempty when viewed through Outlook. Here's what the HTMLBody value is:

"<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><meta name=ProgId content=Word.Document><met"

Code to create Outlook application object, navigate to desired folder and pass MailItem object to the parser (skip if you're familiar with this part):

' Navigate to desired folder and pass information to text analyzer.
Sub AccessInbox(timeStamp As Date)

Dim olApp As Outlook.Application
Dim objNamespace As Outlook.Namespace
Dim objFolder As Outlook.MAPIFolder
Dim sharedFolder As Outlook.MAPIFolder
Set olApp = New Outlook.Application
Set objNamespace = olApp.GetNamespace("MAPI")
' Explicitly went through hierarchy since I'll be using with a shared Mailbox eventually.
Set objMailbox = objNamespace.Folders("Mailbox - My Name")
Set objFolder = objMailbox.Folders("Inbox")
Set sharedFolder = objFolder.Folders("Folder With Stuff")

'mostly irrelevant, see ParseEmailText code below this
Dim emailTimeStamp As Date
For Each Item In sharedFolder.Items
    ' Inbox can contain other kinds of objects than MailItem.
    If TypeOf Item Is MailItem Then
        Dim thisEmail As Object
        Set thisEmail = olApp.CreateItem(MailItem)
        thisEmail = Item
        ' Check to see if email has already been analyzed.
        emailTimeStamp = thisEmail.ReceivedTime
        If emailTimeStamp > timeStamp Then
            ' Send to email text analyzxer.
            ParseEmailText thisEmail
        Else
            Exit For
        End If
    End If
Next

End Sub

Code to parse email body:

Sub ParseEmailText(email As Outlook.MailItem)
    emBody = email.Body
    ' This is the part where I wish I could just access the email's body, but it is empty.
End Sub

[EDIT] I reworked this basic code in C# and the MailItem.Body is NOT blank anymore. In fact it works exactly as expected. Any ideas why VBA sucks so much?

class Parser
{
    //Outlook variables
    Microsoft.Office.Interop.Outlook.Application app = null;
    Microsoft.Office.Interop.Outlook._NameSpace ns = null;
    Microsoft.Office.Interop.Outlook.MailItem item = null;
    Microsoft.Office.Interop.Outlook.MAPIFolder inboxFolder = null;
    Microsoft.Office.Interop.Outlook.MAPIFolder atFolder = null;

    public Parser()
    {

    }

    public void ParseInbox()
    {
        //open outlook
        //Access Outlook (only need to do this once)
        app = new Microsoft.Office.Interop.Outlook.Application();
        ns = app.GetNamespace("MAPI");          //Returns a NameSpace object of the specified type. The only supported name space type is "MAPI".
        ns.Logon(null, null, false, false);     //Namespace.Logon method: Logs the user on to MAPI, obtaining a MAPI session.
        inboxFolder = ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
        atFolder = inboxFolder.Folders["Folder With Stuff"];

        for (int i = atFolder.Items.Count; i > 0; i--)
        {
            item = (Microsoft.Office.Interop.Outlook.MailItem)atFolder.Items[i];

            string emailText = item.Body;
        }
    }
}

Upvotes: 0

Views: 6012

Answers (1)

ChipsLetten
ChipsLetten

Reputation: 2953

You need to use the Set keyword when setting a reference to an object. This line in your code creates a new email object (which is using your default setting of HTML email): Set thisEmail = olApp.CreateItem(MailItem)

And then this line of code isn't using the Set keyword: thisEmail = Item

So your variable isn't referncing the object you think but the new email.

Try using: Set thisEmail = Item

Or, instead, replace both of these lines: Set thisEmail = olApp.CreateItem(MailItem) thisEmail = Item

With this line: Set thisEmail = Item

Upvotes: 1

Related Questions