To paste plain text into an Outlook email body using VBA, you must use the Word Editor object model and explicitly set the Format property of the Selection to wdFormatPlainText. This approach ensures that any clipboard content is stripped of rich formatting before insertion, preventing layout issues in your final message.
Understanding the Outlook Object Model
When automating Microsoft Outlook with VBA, it is crucial to understand that the email body is not a simple text box. Since Outlook 2007, the email editor has been powered by Microsoft Word. This means that when you create or modify an email item, you are actually interacting with a hidden instance of the Word application. To manipulate the body content programmatically, you cannot simply assign a string to the Body or HTMLBody property if you want to preserve complex clipboard operations or specific formatting states. Instead, you need to access the underlying Word document associated with the mail item.
This architectural detail explains why standard copy-paste methods often fail or carry over unwanted styles from Excel. By targeting the Word Editor directly, we gain full control over the selection range. We can simulate user actions like pressing Ctrl+V but enforce a strict plain text output. This method is robust because it relies on the native capabilities of the Word automation engine rather than trying to parse HTML strings manually.
Setting Up References for Early Binding
For the most reliable development experience, especially during the coding phase, it is recommended to use early binding. This allows the Visual Basic Editor to provide IntelliSense and autocomplete features, which significantly speeds up debugging. To enable this, open your VBA editor by pressing Alt + F11. Navigate to the Tools menu and select References.
In the references dialog box, scroll down and check the following libraries:
- Microsoft Outlook xx.x Object Library: Provides access to Outlook-specific objects like
Application,MailItem, andInspector. - Microsoft Word xx.x Object Library: Essential for accessing the Word Editor,
Selectionobject, and constants likewdFormatPlainText.
Replace xx.x with the version number installed on your machine (e.g., 16.0). Using these references ensures that the compiler knows exactly what properties and methods are available, reducing runtime errors caused by typos or missing definitions. If you prefer late binding to avoid reference dependencies on different machines, you would need to declare all objects as generic Object types and define constant values manually, but early binding is preferred for clarity and error checking during development.
Implementing the Plain Text Paste Function
The core logic involves creating a new mail item, activating its inspector window to expose the Word editor, and then executing a paste operation with a specific format flag. The following code demonstrates this process step-by-step. It assumes you have already copied some data to the Windows clipboard, either from Excel or another application.
Sub SendPlainEmail()
Dim olApp As Outlook.Application
Dim olMail As Outlook.MailItem
Dim wdDoc As Word.Document
Dim wdSel As Word.Selection
' Create Outlook Application Instance
Set olApp = New Outlook.Application
Set olMail = olApp.CreateItem(olMailItem)
' Activate the Inspector to get the Word Document Object
olMail.Display
Set wdDoc = olMail.GetInspector.WordEditor
Set wdSel = wdDoc.Windows(1).Selection
' Clear existing content if necessary
wdSel.WholeStory
wdSel.Delete
' Paste as Plain Text
wdSel.PasteSpecial Link:=False, _
DataType:=wdPasteText, _
Placement:=wdInLine, _
DisplayAsIcon:=False
' Optional: Set subject and recipients
olMail.Subject = "Report Data"
olMail.To = "[email protected]"
' Show the email for review before sending
olMail.Display
End Sub
In this script, olMail.Display is critical. Without displaying the item first, the GetInspector method may return nothing or cause an error because the Word editor is not yet instantiated. Once the inspector is active, GetInspector.WordEditor returns the actual Word document object. We then define a selection range within that document. The PasteSpecial method is where the magic happens. By setting DataType:=wdPasteText, we force Word to interpret the clipboard data as unformatted text, ignoring fonts, colors, and table structures from the source.
Handling Errors and Cleanup
While the basic script works, production-ready code should include error handling. Outlook interactions can fail if the user cancels the display window or if security prompts appear. You should wrap the execution in an On Error GoTo block to ensure that objects are properly released. Always set your object variables to Nothing at the end of the subroutine to free up memory. This practice prevents lingering Outlook processes in the background, which can slow down your system.
Additionally, consider adding a check to see if Outlook is already running. Creating a new instance every time might spawn multiple Outlook windows if the user already has one open. Using GetObject for existing instances and CreateObject only when necessary is a more efficient strategy. However, for simple automation tasks, New Outlook.Application is usually sufficient and less prone to connectivity issues.
Alternative Approaches
If you do not need to interact with the clipboard and simply want to insert a string variable into the email body, you can skip the Word Editor entirely. You can assign a plain string directly to the Body property of the MailItem. This is faster and does not require the Word library reference. However, this method does not support pasting complex data structures or preserving line breaks from Excel ranges as effectively as the Word Editor approach. For simple text messages, direct assignment is cleaner.
Another alternative is using HTML bodies. You can construct an HTML string in VBA and assign it to the HTMLBody property. This gives you full control over styling but requires manual construction of tags. It is useful when you need precise formatting that plain text cannot provide, such as hyperlinks or colored text. Yet, for the specific requirement of stripping formatting from external data, the PasteSpecial method remains the most straightforward solution.
For users dealing with large datasets, consider optimizing the clipboard content before pasting. Ensure that the source data is formatted as plain text or CSV in Excel before copying. This reduces the chance of Word interpreting cell borders or fill colors as part of the document structure. Combining clean source data with the PasteSpecial technique yields the most predictable results.
Frequently Asked Questions
Why does my email still show bold text after using PasteSpecial?
The PasteSpecial method strips formatting from the clipboard source, but it does not remove existing formatting in the destination document. If the Word editor already contains styled text, pasting plain text will insert unformatted characters next to styled ones. To fix this, clear the entire selection or document body before pasting, as shown in the example code.
Can I send the email automatically without displaying it?
Yes, but you must be careful with the Word Editor. If you do not call Display, the inspector may not initialize immediately, causing GetInspector to fail. A safer approach for silent sending is to build the HTML body string in VBA and assign it to HTMLBody, then call Send directly. Avoid manipulating the Word Editor for silent sends unless you have handled the initialization sequence correctly.
How do I handle line breaks from Excel cells?
Excel uses Alt+Enter for line breaks within cells, which translates to vbCrLf in VBA. When you copy a range and paste it as plain text, Word typically preserves these line breaks. If they are lost, ensure the source range is copied correctly. You can also manually insert line breaks in your VBA string using Chr(10) if constructing the text programmatically.
What if I get a Compile Error: User-defined type not defined?
This error occurs when you use early binding but forget to add the required reference library. Check the Tools > References menu in the VBA editor and ensure that both the Outlook and Word Object Libraries are checked. If you cannot add references, switch to late binding by declaring variables as Object and defining constants like wdPasteText manually with their numeric values.
Is there a way to paste without using the clipboard?
No, the PasteSpecial method inherently relies on the Windows clipboard containing the data you wish to insert. If you want to avoid clipboard interference, you must construct the text string in VBA using concatenation or array joining, and then assign that string to the Body or HTMLBody property. This bypasses the need for clipboard operations entirely.