Programmatically change font properties in email body - vba

I have been successfully programming this in PowerPoint VBA but haven't been able to make it work on Outlook.
I have an email ready to be sent in Outlook 2013
I want to scan the body of the email for bold text (i.e., bold characters) and change its color to red
(nice to have) Exclude from the macro the signature
I tried several attempts with "Substitute", "if"-loop but no success. Thanks a lot for putting me on the right track.
The following code converts the color of the body but does not discriminate for bold words. Any ideas?
Public Sub FormatSelectedText()
Dim objItem As Object
Dim objInsp As Outlook.Inspector
' Add reference to Word library
' in VBA Editor, Tools, References
Dim objWord As Word.Application
Dim objDoc As Word.Document
Dim objSel As Word.Selection
On Error Resume Next
'Reference the current Outlook item
Set objItem = Application.ActiveInspector.CurrentItem
If Not objItem Is Nothing Then
If objItem.Class = olMail Then
Set objInsp = objItem.GetInspector
If objInsp.EditorType = olEditorWord Then
Set objDoc = objInsp.WordEditor
Set objWord = objDoc.Application
Set objSel = objWord.Selection
' replace the With block with your code
With objSel
' Formatting code goes here
'.Font.Size = 18
If .Font.Bold = True Then
.Font.Color = wdColorBlue
End If
.Font.Color = wdColorRed
'.Font.Italic = True
'.Font.Name = "Arial"
End With
End If
End If
End If
Set objItem = Nothing
Set objWord = Nothing
Set objSel = Nothing
Set objInsp = Nothing
End Sub

First of all, I'd suggest starting from the Getting Started with VBA in Outlook 2010 article in MSDN.
You can use the HTMLBody property of Outlook items to get the HTML content of the message body or use the Word object model to get the job done. The WordEditor property of the Inspector class returns an instance of the Document class from the WOM (Word object model). See Chapter 17: Working with Item Bodies for more information.

Related

How to insert a content control checkbox into an Outlook task using Word VBA?

I would like add a working checkbox (content control?) to an existing task, like a list of sub-tasks, that could just be checked off.
Within Outlook I referenced the Microsoft Word 16.0 Object Library, and I have tried the suggestions at http://www.vboffice.net/en/developers/use-word-macro-in-outlook/ and https://www.slipstick.com/developer/word-macro-apply-formatting-outlook-email/ without success.
I tried
Option Explicit
Public Sub Checkbox()
Dim objItem As Object
Dim objInsp As Outlook.Inspector
' Add reference to Word library
' in VBA Editor, Tools, References
Dim objWord As Word.Application
Dim objDoc As Word.Document
Dim objSel As Word.Selection
On Error Resume Next
' Reference the current Outlook item
Set objItem = Application.ActiveInspector.CurrentItem
If Not objItem Is Nothing Then
If objItem.Class = olMail Then
Set objInsp = objItem.GetInspector
If objInsp.EditorType = olEditorWord Then
Set objDoc = objInsp.WordEditor
Set objWord = objDoc.Application
Set objSel = objWord.Selection
' Formatting code goes here
Selection.Range.ContentControls.Add (wdContentControlCheckBox)
End If
End If
End If
Set objItem = Nothing
Set objWord = Nothing
Set objSel = Nothing
Set objInsp = Nothing
End Sub
I have also tried
Public Sub Check2()
Dim Ins As Outlook.Inspector
Dim Document As Word.Document
Dim Word As Word.Application
Dim Selection As Word.Selection
Set Ins = Application.ActiveInspector
Set Document = Ins.WordEditor
Set Word = Document.Application
Set Selection = Word.Selection
Selection.Range.ContentControls.Add (wdContentControlCheckBox)
End Sub
The first one didn't do anything, as I recall.
The second one showed
Run-time error '445'".
Object doesn't support this action
Your VBA code works correctly:
Public Sub Check2()
Dim Ins As Outlook.Inspector
Dim Document As Word.Document
Dim Word As Word.Application
Dim Selection As Word.Selection
Set Ins = Application.ActiveInspector
Set Document = Ins.WordEditor
Set Word = Document.Application
Set Selection = Word.Selection
Selection.Range.ContentControls.Add (wdContentControlCheckBox)
End Sub
You just needed to add a reference to the Word object library (Tools -> References):

VBA to format selected text in Outlook

I want to highlight text in an email and format it to font consolas and indent it once.
I have tried this but get an error:
Sub Code()
Selection.Font.Name = "Consolas"
Selection.Paragraphs.Indent
End Sub
Run-time error '429':
ActiveX component can't create object
You can use WordEditor to edit selected text in mail:
Private Sub Code()
' Mail must be in edit mode - compose, reply, forward
' If reading mail then under Actions | Edit Message
' Select some text
Dim objDoc As Object
Dim objSel As Object
Set objDoc = ActiveInspector.WordEditor
Set objSel = objDoc.Windows(1).Selection
objSel.Font.name = "Consolas"
objSel.Paragraphs.Indent
End Sub
Code with validations:
Sub FormatSelection()
' With extra validation for troubleshooting
' Code in Outlook
' Mail must be in edit mode - compose, reply, forward
' If reading mail then under Actions | Edit Message
' Select some text
Dim myInspector As Inspector
Dim myObject As Object
Dim myItem As mailItem
Dim myDoc As Word.Document
Dim mySelection As Word.Selection
Set myInspector = ActiveInspector
If myInspector Is Nothing Then
MsgBox "No inspector. Open a mailitem and select some text."
GoTo ExitRoutine
End If
If myInspector.EditorType <> olEditorWord Then
'https://msdn.microsoft.com/en-us/vba/outlook-vba/articles/oleditortype-enumeration-outlook
' olEditorWord / 4 / Microsoft Office Word editor
Debug.Print "EditorType: " & myInspector.EditorType
MsgBox "Editor is not Microsoft Office Word editor"
GoTo ExitRoutine
End If
' Probably not needed. EditorType should be enough
'If myInspector.IsWordMail = False Then
' MsgBox "myInspector.IsWordMail = False"
' GoTo ExitRoutine
'End If
On Error Resume Next
Set myObject = myInspector.currentItem
On Error GoTo 0
If myObject Is Nothing Then
MsgBox "Open a mailitem and select some text."
GoTo ExitRoutine
End If
If myObject.MessageClass = "IPM.Note" Then
'Should be equivalent to If myObject.Class = olMail Then
Set myItem = myObject
Set myDoc = myInspector.WordEditor
Set mySelection = myDoc.Application.Selection
Debug.Print "Selected text is: " & mySelection
MsgBox "Selected text is: " & vbCr & vbCr & mySelection
mySelection.Font.name = "Consolas"
mySelection.Paragraphs.Indent
Else
MsgBox "Not a mailitem. Open a mailitem and select some text."
GoTo ExitRoutine
End If
ExitRoutine:
Set myInspector = Nothing
Set myObject = Nothing
Set myItem = Nothing
Set myDoc = Nothing
Set mySelection = Nothing
End Sub
Looks like you are trying to mix the Word object model with Outlook. The Selection class in Outlook is not the same as the Selection class from the Word object model. Moreover, there is no such shortcuts in Outlook. You must retrieve it each time you need it.
The Outlook object model provides three main ways for working with item bodies:
The Body property. A raw text.
The HTMLBody property. The body is represented by the html markup.
The Word object model. The WordEditor property of the Inspector class returns and instance of the Word Document class which represents the body.
You can read more about this in the Chapter 17: Working with Item Bodies article in MSDN. It describes all these properties in depth.

Programmatically change properties in email body in Outlook with VBA

I have an email ready to be sent in Outlook 2013
I want to scan the body of the email for bold text (i.e., bold characters) and change its color to red
(nice to have) Exclude from the macro the signature
I put together the code below but still not working. Any ideas?
Public Sub FormatSelectedText()
Dim objItem As Object
Dim objInsp As Outlook.Inspector
' Add reference to Word library
' in VBA Editor, Tools, References
Dim objWord As Word.Application
Dim objDoc As Word.Document
Dim objSel As Word.Selection
On Error Resume Next
'Reference the current Outlook item
Set objItem = Application.ActiveInspector.CurrentItem
If Not objItem Is Nothing Then
If objItem.Class = olMail Then
Set objInsp = objItem.GetInspector
If objInsp.EditorType = olEditorWord Then
Set objDoc = objInsp.WordEditor
Set objWord = objDoc.Application
Set objSel = objWord.Selection
Set objChar = Characters.Selection
' replace the With block with your code
With objChar
' Formatting code goes here
'.Font.Size = 18
If .Font.Bold = True Then
.Font.Color = wdColorBlue
End If
.Font.Color = wdColorRed
'.Font.Italic = True
'.Font.Name = "Arial"
End With
For Each Char In Characters.Selection
If Char.Font.Bold Then
Char.Font.Color = RGB(0, 0, 255) 'TextRGBTmp
End If
Next Char
For Each Char In Characters.Selection
If Not Char.Font.Bold And Char.Font.Color = RGB(0, 0, 255) Then
Char.Font.Color = RGB(0, 0, 0)
End If
Next Char
End If
End If
End If
Set objItem = Nothing
Set objWord = Nothing
Set objSel = Nothing
Set objInsp = Nothing
End Sub
This is a follow up to question: Programmatically change font properties in email body
first of all: don't use On Error Resume Next when you're trying to debug your code. It makes your life harder.
second: use Option Explicit at the beginning of the module. With that option enabled, VBA will show you every variable that's not initialized (some bugs only occur from misspellings).
I've corrected your code, so it works for me:
Public Sub FormatSelectedText()
Dim objOutlook As Outlook.Application ' i used this because im working in MS Access
Dim objItem As Object
Dim objInsp As Outlook.Inspector
' Add reference to Word library
' in VBA Editor, Tools, References
Dim objWord As Word.Application
Dim objDoc As Word.Document
Dim objSel As Word.Selection
Dim objChar As Object
Dim Char As Object
'Reference the current Outlook item
Set objOutlook = GetObject(, "Outlook.Application")
Set objItem = objOutlook.ActiveInspector.CurrentItem
If Not objItem Is Nothing Then
If objItem.Class = olMail Then
Set objInsp = objItem.GetInspector
If objInsp.EditorType = olEditorWord Then
Set objDoc = objInsp.WordEditor
Set objWord = objDoc.Application
Set objSel = objWord.Selection
Set objChar = objSel.Characters ' this wasn't initialized
' replace the With block with your code
' With objChar ' you don't Need this block because objChar is an array and it throws an error when you try to use this code on the whole objChar object
' ' Formatting code goes here
' '.Font.Size = 18
' If .Font.Bold = True Then
' .Font.color = wdColorBlue
' End If
' .Font.color = wdColorRed
' '.Font.Italic = True
' '.Font.Name = "Arial"
' End With
For Each Char In objSel.Characters
If Char.Font.Bold Then
Char.Font.color = rgb(255, 0, 0) 'TextRGBTmp (the rgb was filled backwards, so the text became blue. i fixed it.
End If
Next Char
' the code of the second For Each was not neccessary.
End If
End If
End If
Set objItem = Nothing
Set objWord = Nothing
Set objSel = Nothing
Set objInsp = Nothing
End Sub

VBA Outlook How to add hyperlink into email body

This macro adds hyperlink to email :
Sub test_add_hyperlink()
Dim NewMail As Outlook.MailItem
Set NewMail = Application.ActiveInspector.CurrentItem
NewMail.HTMLBody = "<HTML><BODY><A href=http://www.someaddress.com>URL_TEXT</A></BODY></HTML>" & NewMail.HTMLBody End Sub
but how to add hyperlink in place where active cursor is ? I ask beacause I would like to add hyperlink not at the front of message, but where my currently writing message.
The hyperlink I would like to add is the hyperlink to file which is currently copied to Windows' clipboard, this part I've written, but I can't figure out how to place it not at the front of email, but in place where active cursor is. I think that macro based emulation of Windows' keypressing is one of the directions to follow.
This describes how to paste at the selection.
http://www.slipstick.com/developer/code-samples/paste-formatted-text-vba/
Sub PasteFormattedClipboard()
Dim objItem As Object
Dim objInsp As Outlook.Inspector
Dim objWord As Word.Application
Dim objDoc As Word.Document
Dim objSel As Word.Selection
Set objItem = Application.ActiveInspector.CurrentItem
Set objInsp = objItem.GetInspector
Set objDoc = objInsp.WordEditor
Set objWord = objDoc.Application
Set objSel = objWord.Selection
objSel.PasteAndFormat (wdFormatOriginalFormatting)
Set objItem = Nothing
Set objInsp = Nothing
Set objDoc = Nothing
Set objWord = Nothing
Set objSel = Nothing
End Sub
Sub InsertHyperlinkAtCursorPositon()
On Error GoTo finish
strLink = "http://www.outlookcode.com"
strLinkText = "Get Outlook code samples here"
Set objInsp = Application.ActiveInspector
Set objMsg = objInsp.CurrentItem
Set objDoc = objInsp.WordEditor
Set objSel = objDoc.Windows(1).Selection
If objMsg.BodyFormat <> olFormatPlain Then
objDoc.Hyperlinks.Add objSel.Range, strLink, _
"", "", strLinkText, ""
Else
objSel.InsertAfter strLink
End If
finish:
End Sub

Remove space before and after in Outlook

I'm attempting to write a macro for Outlook (never written a macro, or VBA for that matter) that will remove the space before and after the text that I have selected.
This is what I've cobbled together from examples that I've found:
Sub FixParagraphSpacing()
Dim objOL As Application
Dim objDoc As Object
Dim objSel As Object
Set objOL = Application
Set objDoc = objOL.ActiveInspector.WordEditor
Set objSel = objDoc.Windows(1).Selection
objSel.ParagraphFormat.SpaceBefore = 0
objSel.ParagraphFormat.SpaceAfter = 0
Set objOL = Nothing
Set objDoc = Nothing
Set objSel = Nothing
End Sub
The problem is that the code executes and almost nothing happens. The body of the email isn't affected, but I'm not able to remove the spacing before and after manually anymore because Outlook thinks it's already been done.
What am I missing here?
Update
Here is my updated code, based on #KevinPope's answer:
Sub FixParagraphSpacing()
Dim objOL As Application
Dim sel As Object
Set objOL = Application
Set sel = objOL.ActiveInspector().WordEditor.Application.Selection
For Each para In sel.Paragraphs
para.SpaceBefore = 0
para.SpaceAfter = 0
Next para
End Sub
Before I run the code, here's what I see under Line and Paragraph Spacing:
And here's what I see after I run the macro:
Unfortunately, other than this, no visible change is made in the body of the email.
Screenshot of text per request:
I too faced the same problem.
When running the macro, it does seem to update the values (space before/after to 0), but doesnt apply the settings to the selected text.
But then adding the SpaceBeforeAuto = False worked...
Sub FixParagraphSpacing()
Dim objOL As Application
Dim objDoc As Object
Dim objSel As Object
Set objOL = Application
Set objDoc = objOL.ActiveInspector.WordEditor
Set objSel = objDoc.Windows(1).Selection
objSel.ParagraphFormat.SpaceBefore = 0
objSel.ParagraphFormat.SpaceBeforeAuto = False
objSel.ParagraphFormat.SpaceAfter = 0
objSel.ParagraphFormat.SpaceAfterAuto = False
Set objOL = Nothing
Set objDoc = Nothing
Set objSel = Nothing
End Sub
Try using "Selection.WholeStory" before you set the paragraph formatting. It worked for me.
Something like this should sort out the line spacing before and after a selected Paragraph:
Sub Test()
Dim objOL As Application
Dim sel As Object
Set objOL = Application
Set sel = objOL.ActiveInspector().WordEditor.Application.Selection
sel.Paragraphs(1).SpaceBefore = 0
sel.Paragraphs(1).SpaceAfter = 0
End Sub
Let me know if this doesn't work and we can iterate on it.