Substitute text in HTMLbody (Creating email from Excel VBA) - vba

I've got the following VBA code to properly create an email using an email template, however I'm trying to change some text in the email body using the Substitute() function. I'm receiving an error and am unsure on how to resolve this, any help would be great!
Run-time error '1004':
Unable to get the Substitute property of the WorksheetFunction class
Here's the code attempting to create the email from my template...
Public Function GenerateEmail(fileName As String)
Application.ScreenUpdating = False
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItemFromTemplate(fileName)
With OutMail
.HTMLbody = WorksheetFunction.Substitute(OutMail.HTMLbody, "%TESTNUM%", "98541")
.Attachments.Add (Application.ActiveWorkbook.FullName)
.Display
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Function

Replace is the correct way to go here as answered by #Brax.
For anyone looking to understand the reason behind this error.
Just to explain why the 1004 happened with substitute, you need to check the parameters when using WorksheetFunction.
Here the issue is the allowed number of characters in a Excel cell. You can only put 32767 characters in the cell. Now, certainly, your HTMLBody has more characters in it, hence the error.
Sub Test()
Dim validString As String
Dim inValidString As String
validString = "a" & Space(32766)
inValidString = "b" & Space(32767)
'/ Works as the string length is valid cell length : < =32767
MsgBox WorksheetFunction.Substitute(validString, "a", "b")
'/ Fails as the string length is invalid in terms of cell length : >32767
MsgBox WorksheetFunction.Substitute(inValidString, "a", "b")
End Sub

You can just use Replace
.HTMLbody = Replace(OutMail.HTMLbody, "%TESTNUM%", "98541")

Related

Insert a default signature with a picture into an email

I'm trying to write the VBA code that will insert the default Outlook signature into an email that has been generated in Excel. There's a few people that might use the Excel template, so I need the VBA code to pick up the default signature of the user that's creating the email.
I've found various helpful things online, however I can't get it to work. I'm new to VBA so still learning.
The code below works for the email I need - expect the signature as I've removed all that code as I couldn't get it to work.
Any help would be greatly appreciated.
Sub EmailCreator()
ActiveWorkbook.Save
Dim olApp As Outlook.Application
Dim olMail As Outlook.MailItem
Dim blRunning As Boolean
blRunning = True
On Error Resume Next
Set olApp = GetObject(, "Outlook.Application")
If olApp Is Nothing Then
Set olApp = New Outlook.Application
blRunning = False
End If
On Error GoTo 0
strBody = "This is my message in HTML format"
Set olMail = olApp.CreateItem(olMailItem)
With olMail
.Subject = "abc"
.Attachments.Add ActiveWorkbook.FullName
.HTMLBody = strBody
.Display
End With
If Not blRunning Then olApp.Quit
Set olApp = Nothing
Set olMail = Nothing
End Sub
Firstly, Outlook will insert the default signature when you call Display if the message body has not been modified yet.
Secondly, once you call Display (and the message body gets populated with the signature), you will need to merge the two HTML strings - not just set the HTMLBody property (which would wipe out the signature), not concatenate the two HTML strings (which cannot produce a valid HTML document), but merge. The easiest would be to look for the position of the "<body" substring, scroll to the next ">" character (to take care of the body tag with attributes), then insert your HTML after that ">" character.

I cannot insert text directly into bookmark via VBA

'Trying to insert text directly into a bookmark via VBA
'tried lots of things, but nothing worked.
'Can someone point out where I am getting this wrong?
Sub AddBookMark()
Dim BMName As String
Dim Contents As String
sText = "BM1"
Contents = "Testing"
With ActiveDocument.Bookmarks
.Add Range.Text:=Contents
.Add Name:=BMName
.DefaultSorting = wdSortByName
.ShowHidden = False
End With
End Sub
'Compile error: syntax error
You cannot add a bookmark to text that doesn't exist already in a document. In other words, you have to first select the text you want to enclose within a bookmark. If the text doesn't exist, then you must insert the text and then you can select it and finally insert the necessary bookmark to surround it.
If you had opened the VBE, Visual Basic Editor, and looked at your code you would see the statement Add Range.Text:=Contents in red and it was causing the syntax error because there are no such properties in the Bookmarks.Add method.
Even with the Bookmarks.Add method corrected your code would still fail because the string variable BMName is never given a value and the BookMark name cannot be blank.
Below is revise code of your routine that you should study:
Sub AddBookMarkRevised()
Dim BMName As String
Dim Contents As String
Dim rng As Range
BMName = "BM1"
Contents = "Testing"
Set rng = Selection.Range
rng.Text = Contents
With ActiveDocument.Bookmarks
.Add BMName, rng
.DefaultSorting = wdSortByName
.ShowHidden = False
End With
End Sub

VBA Excel creating Outlook email subject and body blank

I've got an Excel spreadsheet built by someone else that sends an email to a group via a scheduled task, or at least used to. It recently stopped working. I don't have the time to rebuild his whole Rube Goldberg / Wile E. Coyote system at the moment, so I'm trying to fix it.
In one of the excel documents, this code exists
Set rng = Nothing
On Error Resume Next
Set rng = Sheets("Weight").Range("A2")
On Error GoTo 0
If rng Is Nothing Then
MsgBox "The selection is not a range or the sheet is protected" & _
vbNewLine & "please correct and try again.", vbOKOnly
Exit Sub
End If
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = "eric.lizotte#.com"
.CC = ""
.BCC = ""
.Subject = Sheets("Weight").Range("A1")
.HTMLBody = Convert.ToString(rng)
.Send
End With
whenever I see so many "on error resume next" in something I grit my teeth.
What's happening is that it "works" but the email it sends is blank. In debug I can see that the subject content and body content both exist and have values. I rewrote it to be
OutMail.To = "eric.lizotte#.com"
OutMail.CC = ""
OutMail.BCC = ""
OutMail.Subject = Sheets("Weight").Range("A1")
OutMail.HTMLBody = Convert.ToString(rng)
OutMail.Send
and threw a debug point on the send, and checked the properties of outmail, and the subject and htmlbody have values. I can't figure out why after the send they are blank.
Given you are automating another application you probably should not rely on the default property of the range - just specify the property you want e.g. Value:
OutMail.Subject = Sheets("Weight").Range("A1").Value
OutMail.HTMLBody = rng.Value
You might also try the Text property for the HTMLBody:
OutMail.HTMLBody = rng.Text
You can then be confident that you are assigning a String to the mail properties which is what it expects.

Select from 4th line onwards Word VBA

I am using the following code to copy text and images from Microsoft Word and paste to the body of an Outlook e-mail. I am trying to exclude the first 4 lines from being copied (this code is copying everything in the document). How can I go about doing this?
Sub CopycontentintoOutlook()
Dim oMailItem As Object
Dim oWordApp As Object
Dim oWordDoc As Object
Dim oMailWordDoc As Object
Set oWordApp = CreateObject("Word.Application")
Set oWordDoc = ActiveDocument
oWordDoc.Content.Copy
Set oMailApp = CreateObject("Outlook.Application")
Set oMailItem = oMailApp.CreateItem(0)
With oMailItem
.To = "email"
.Subject = "This email contains Word-formatted text"
.Display
End With
Set oMailWordDoc = oMailApp.ActiveInspector.WordEditor
oMailWordDoc.Application.Selection.Paste
End Sub
I am also wondering if it is possible to use the text in the first line and set this as the email subject?
You can use the GoTo() function with the wdGoToLine value to set the insertion point to a specific line. From there, the MoveEnd() function can set the end of your selection to the end of your document.
' Set start to line 4...
Selection.GoTo What:=wdGoToLine, Which:=wdGoToAbsolute, Count:=4
' Select up to end of document...
Selection.MoveEnd Unit:=wdStory

Macro VBA to get selected text in Outlook 2003

I am trying to use this code snippet to get the selected text in outlook 2003
Sub SelectedTextDispaly()
On Error Resume Next
Err.Clear
Dim oText As TextRange
''# Get an object reference to the selected text range.
Set oText = ActiveWindow.Selection.TextRange
''# Check to see whether error occurred when getting text object
''# reference.
If Err.Number <> 0 Then
MsgBox "Invalid Selection. Please highlight some text " _
& "or select a text frame and run the macro again.", _
vbExclamation
End
End If
''# Display the selected text in a message box.
If oText.Text = "" Then
MsgBox "No Text Selected.", vbInformation
Else
MsgBox oText.Text, vbInformation
End If
End Sub
When running this macro I get the error
---------------------------
Microsoft Visual Basic
---------------------------
Compile error:
User-defined type not defined
Do I need to add any references to fix this up?
#Kusleika, I tried the option you had suggested and still the same errors came up.
Thanks for the help
May be I had not phrased my question in the proper way
Some more googling revealed that its not possible to get the selected text of a mail in preview pane. http://www.eggheadcafe.com/forumarchives/outlookprogram_VisualBasica/Aug2005/post23481044.asp
So I had to adjust the requirement so that I can do an action from an mail item window.
The following code helped me (had to make some changes to suit my needs)
Sub Blue_Code_Highlight()
Dim msg As Outlook.MailItem
Dim insp As Outlook.Inspector
Set insp = Application.ActiveInspector
If insp.CurrentItem.Class = olMail Then
Set msg = insp.CurrentItem
If insp.EditorType = olEditorHTML Then
Set hed = msg.GetInspector.HTMLEditor
Set rng = hed.Selection.createRange
rng.pasteHTML "<font style='color: blue; font-family:Times New Roman; font-size: 10pt;'>" & rng.Text & "</font><br/>"
End If
End If
Set insp = Nothing
Set rng = Nothing
Set hed = Nothing
Set msg = Nothing
End Sub
Source:http://www.outlookcode.com/threads.aspx?forumid=4&messageid=26992
#Kusleika thanks for the help, can I close this thread. Pls let me know.
Just in case someone is using the word editor instead of html, you can also insert this part:
If insp.EditorType = olEditorWord Then
Set hed = msg.GetInspector.WordEditor
Set word = hed.Application
Set rng = word.Selection
rng.Font.Name = "Times New Roman"
rng.Font.Size = 10
rng.Font.Color = wdColorBlack
End If
to get similar when word is the editor. i tried to paste this into a comment on the accepted answer, but it destroyed the formatting and was pretty useless, so posting as an answer.
Dim oText As Range
TextRange is a property of the TextFrame object. It returns a Range object. There is no TextRange object.