How to replace text in the body of an Outlook email message - vba

I have text data that I read from a file; I need to place it in the body of an email message. There are about 50 such data items to be placed into existing text.
It seems I should be able to put a marker (dataItem1, dataItem2, etc.) and replace that with the matching text data from the file.
Searches only turn up replacing field data such as Recipient, Subject, etc., or replacing the entire body. Would I have to generate the entire body in the code? Seems like I should be able to "insert" a data item into existing body text.
Any suggestions will be much appreciated.

Just in case your email is formatted as HTML, and you don't want to lose the formatting, here's what you want to do.
myMessage.HTMLBody = Replace(myMessage.HTMLBody, "dataItem1", "replacement item")

Use the Body property of the MailItem you're working with. Assign it to a variable and you can edit it:
Dim body As String
body = myMessage.Body
body = Replace(body,"dataItem1","your replacement here")
Then assign the variable to the Body:
myMessage.Body = body

Related

.txt file to Rich text box with changes

Im going to try to make this as simple as i possible can. I work in a shipping company, where we email our clients if there is any issues with their orders. I have recently made a vb.net program that standardizes these emails. Now i am rewriting the program so that the templates can be edited from a text file. right now they are hard coded into the program itself.
SO, this is what im wanting to do
Template.txt -> Good afternoon %NAME% your order has shipped.
I want the program to open this text file, Change %NAME% to variable CustName which is entered from a text box, Then show the updated text in a RichTextBox. But i dont want the template.txt to save the changes.
Was wondering if you fine people could help me out with this.
Thanks a lot!
The first answer is on the right track. You just need to store the template text in your file. With this in your text file:
Good afternoon {0} your order has shipped.
you can then do something like this:
Dim name = "someone"
Dim template = File.ReadAllText("TextFile1.txt")
RichTextBox1.Text = String.Format(template, name)
The first argument to String.Format is the template, containing the numbered placeholders. The remaining arguments are the values to replace those placeholders. The first of those arguments will replace every instance of "{0}" in the template, the second will replace "{1}" and so on. You need to make sure that your numbered placeholders always match the order of the values you pass to String.Format.
If you don't want the person editing that template to have to remember what each number means, you can write your own replacement code. For instance, you might store this in the file:
Good afternoon {name} your order has shipped.
and then do this:
Private Function FillTemplate(template As String, name As String) As String
Return template.Replace("{name}", name)
End Function
and this:
Dim name = "someone"
Dim text = FillTemplate(File.ReadAllText("TextFile1.txt"), name)
RichTextBox1.Text = text
You need to add a parameter and a Replace call to FillTemplate for each value you want to insert, e.g.
Private Function FillTemplate(template As String,
name As String,
address As String) As String
Return template.Replace("{name}", name).
Replace("{address}", address)
End Function
I think the syntax you're looking for is something like
String.Format("Good afternoon {0} your order has shipped", name_variable)
If you wanted to change two pieces of information, you could use
String.Format("Good afternoon {0} your order has {1}", name_variable, "shipped")

Put text to clipboard reliably

I added VBA code to ThisOutlookSession to put a mail's subject line and the recipient's name into the mail body. This does not work reliably.
To be variable on where I paste the text, I use a data object of MSforms and it's PutInClipboard function to move the generated text to the Windows clipboard.
This works most of the time but sometimes the clipboard only contains two undefined characters. I am sure the text to be inserted was generated correctly.
// forClip is a string that contains a text line
Set MyData = New MSForms.DataObject
MyData.Clear
MyData.SetText forClip
MyData.PutInClipboard
// the code ended here but as described the clipboard then contains ��
// I added the following lines only to find out where it all goes wrong
MyData.GetFromClipboard
forClip = MyData.GetText(1)
// the string going back to "forClip" only contains the two characters mentioned.
Set MyData = Nothing
The code works most of the time - but if it fails, it will keep failing.
Could it be, that the clipboard interprets the text not as text but as something different? Is there a way to force it to interpret the data as text?

Outlook code for both plain text and html format

Some people advice that it is good idea to sent an e-mail in both format html and plain text together in the same e-mail body as following link explains.
https://litmus.com/blog/reach-more-people-and-improve-your-spam-score-why-multi-part-email-is-important
You can see four code options below.
.BodyFormat = Outlook.OlBodyFormat.olFormatHTML
.BodyFormat = Outlook.OlBodyFormat.olFormatPlain
.BodyFormat = Outlook.OlBodyFormat.olFormatRichText
.BodyFormat = Outlook.OlBodyFormat.olFormatUnspecified
You are able to select one option as following picture shows.
http://www.rocketseed.com/wp-content/uploads/2013/07/Outlook-2010-HTML.jpg
How to sent mixed formatted e-mails even your code must include one option?
I need vb.net code for this.
That link does not apply to Outlook: when a message is saved (or sent) all 3 flavors of the message body (plain, HTML, RTF) are synchronized. You cannot send a message from Outlook with either flavor out of sync. You can send plain text messages, html/plain, or RTF (winmail.dat), but you cannot send with plain text body out of sync of the HTML body.

How to retain Field Codes after Word MailMerge (e.g.{FILENAME} in footer of document)

I have inserted a field {FILENAME} in the footer of my source document.
When I generate a MailMerge with this source document and a data file the resulting document does not show the field code - it has been replaced by hardcoded text representing the current document's filename - 'Document1'. This is the code to show that I am not doing anything particularly fancy:
Call vActiveDocument.MailMerge.OpenDataSource(vDataSourcePath)
vActiveDocument.MailMerge.SuppressBlankLines = True
vActiveDocument.MailMerge.Destination = 0 'Send to new Document
Call vActiveDocument.MailMerge.execute(True)
Call vActiveDocument.Close(False)
Set vActiveDocument = vApplication.activedocument
Am I missing something? I am expecting the code field to remain a code field, even after the mailmerge operation.Is there a way to tell Word 'calculate the MERGEFIELD fields, but do not calculate the other form fields'.
At the moment I am using a clunky search and replace but this is really ugly. ugly ugly ugly. Could even qualify as a hack.
'//get current filename
fileName = vActiveDocument.Name
'//check if we need to replace foooter
If ( replaceFileNameInFooter) then
'//Replacing current document filename with a computed field
'//set view to footer
vApplication.ActiveWindow.ActivePane.View.SeekView = 10
'//Assing footer
Set footer = vApplication.Selection.Range
'//search for current filename -> example: FormLetters1
footer.Find.Text = filename
'//replace with a filename field -> Type 29
While footer.Find.Execute()
Call vApplication.Selection.Fields.Add(footer, 29)
Wend
'//set main document mode
vApplication.ActiveWindow.ActivePane.View.SeekView = 0
End if
As far as I know, the only way you can do this using the field language is another hack, and it's probably an even more difficult one to manage.
Put the field code you want (e.g. { FILENAME \p } in another document, bookmark it, e.g. using "bm_filename_p", then use
{ INCLUDETEXT "the full path+name of the document" bm_filename_p }
in your Mail Merge Main Document.
Post-merge, all the INCLUDETEXT fields are retained, but you will probably need to save the file then update the fields in the footer to get the result you want. At that point, if you want to "fix" the field results you can do it in the usual way (replace the field codes by their results), but if you do not do that, you will always need the included file to be in the specified location.
Although that works with FILENAME, and it will even work with a field such as { SEQ abc } in the body of the Mail Merge Main Document, it doesn't work, for example with { SEQ abc \c } in the footer.
One way you may be able to make the search and replacement task a little easier is to insert a { PAGE } field with an identifier, like this
{ PAGE \#field_filename }
These fields are also retained post-merge and it may be slightly easier to find/replace them (e.g. look for { PAGE } fields and replace "PAGE #field_" with "" , or some such.

How do hard code HTML in VB for the Body of an email?

Sorry if that title wasn't very easy to get the gist of. This is my first post.
Basically within my program is the option to send an email. Its an E-Ticket. I have set 'IsBodyHtml' to true. It sends it fine. No problems at all.
Within the HTML code however I want to insert some fields that are relevant to each customer.
When I put set ETicket.Body = to the HTML Code I get a number of errors because words such as 'Width' and 'Height' etc are being picked up as VB words.
As a short term fix so I could test that the HTML body actually works I put the code into a rich text box and then set ETicket.Body = RichTextBox1.Text . It works, but doesn't have the data in it that I want.
The data relevant to each customer is held in an array. Any idea how I can get the HTML code to be accepted by VB? Or how I can get my data from the array into the relevant position in the rich text box?
Thankyou!
Joe
This will likely be due to the double quotes in the HMTL markup. Try doing a find and replace on the HTML, and replace double quotes (") with single ones (').