Outlook VBA - .RTFBody Formatting from Byte Array

Viewed 50

I am developing a VBA / VSTO script that interacts with Outlook.

I have a process that should, essentially, do this:

  1. Read in an .oft file that is in Rich Text Format
  2. Parse the RTFBody array into a String
  3. Replace some elements of the String (so a line that says "%SUBJECT%" will instead be "IMPORTANT MEETING")
  4. Convert that String back into the RTF array format (this uses a Rich Text Box)
  5. Replace the RTFBody with the updated RTF array
  6. Display the finished email

This is all done. Except the finished email is just RTF garbage with no formatting.

So what is meant to be a lovely table is instead this:

{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff37\deff0\stshfdbch0\stshfloch37\stshfhich37\stshfbi37\deflang2057\deflangfe2057\themelang2057\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304

(You can imagine the rest.)

The code is:

Dim objMsg As AppointmentItem
' 1. Read in an .oft file that is in Rich Text Format
objMsg = Application.CreateItemFromTemplate(currentLocation & "\template.oft")

' 2. Parse the RTFBody array into a String
Dim rtfArray = objMsg.RTFBody
Dim Encoding = New System.Text.ASCIIEncoding()
Dim rtfBody = Encoding.GetString(rtfArray)

' 3. Replace some elements of the String (so a line that says "%SUBJECT%" will instead be "IMPORTANT MEETING")
rtfBody = Replace(rtfBody, "%SUBJECT%", "Important Meeting")

' 4. Convert that String back into the RTF array format (this uses a Rich Text Box)
Dim rtb = New System.Windows.Forms.RichTextBox()
rtb.Text = rtfBody
Dim newArray = System.Text.Encoding.ASCII.GetBytes(rtb.Rtf)

'5. Replace the RTFBody with the updated RTF array
objMsg.RTFBody = newArray

'6. Display the finished email
objMsg.Display()

Does anyone have any awareness of what the solution to this problem is?

And before anyone suggests HTML... I would love to! But this is an AppointmentItem so it doesn't support HTMLBody.

1 Answers

To parse the RTFBody array into a string you have dealt with ASCII encoded string:

Dim rtfArray = objMsg.RTFBody
Dim Encoding = New System.Text.ASCIIEncoding()
Dim rtfBody = Encoding.GetString(rtfArray)

But to set the RTFBody you deal with UTF8 for an unknown reason:

Dim newArray = System.Text.Encoding.UTF8.GetBytes(rtb.Rtf)

Try to use the same encoding:

Dim newArray = System.Text.Encoding.ASCII.GetBytes(rtb.Rtf)

Be aware, The Outlook object model supports three main ways of customizing the message body:

  1. The Body property returns or sets a string representing the clear-text body of the Outlook item.
  2. The HTMLBody property of the MailItem class returns or sets a string representing the HTML body of the specified item. Setting the HTMLBody property will always update the Body property immediately. For example:
     Sub CreateHTMLMail() 
       'Creates a new e-mail item and modifies its properties. 
       Dim objMail As Outlook.MailItem 
       'Create e-mail item 
       Set objMail = Application.CreateItem(olMailItem) 
       With objMail 
        'Set body format to HTML 
        .BodyFormat = olFormatHTML 
        .HTMLBody = "<HTML><BODY>Enter the message <a href="http://google.com">text</a> here. </BODY></HTML>" 
        .Display 
       End With 
     End Sub
  1. The Word object model can be used for dealing with message bodies. See Chapter 17: Working with Item Bodies for more information.

Note, the MailItem.BodyFormat property allows you to programmatically change the editor that is used for the body of an item.

Related