Insert a default signature with a picture into an email - vba

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.

Related

My attachments lose their original name and are show as ProjectStatus.xlsx

In windows 7 and Office 2007 I have been using a code which opens a new email in Outlook, attach a file and send it. The code it's not mine, I found it somewhere in the internet. The problem is that now I use Windows 10 and Office 2016, and using the same code produce different results as:
The original name of the file, let's say for example "Products.xlsx", is changed to "ProjectStatus.xlsx" (any file name is always changed to "ProjectStatus.xlsx")
If I open the file then Excel opens it and shows the original name of the file ("Products.xlsx")
If I send it, sometimes the recipients see the attached file as "ProjectStatus.xlsx" and sometimes see it as "Products.xlsx". But what always happens is that if they open the file, in excel is seen as "Products.xlsx"
I need the file name always be shown with the original name. How can I do this?
This is the code I use it and is executed from both access 2016 and excel 2016.
Sub MandaMailA(destinatarios As String, copia As String, subject As String, strbody As String, attachment1 As String, Optional attachment2 As String = "", Optional CO As String = "")
Dim OutApp As Object
Dim OutMail As Object
Dim SigString As String
Dim Signature As String
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
'Change only Mysig.htm to the name of your signature
SigString = Environ("appdata") & _
"\Microsoft\Firmas\VBA.htm"
If Dir(SigString) <> "" Then
Signature = GetBoiler(SigString)
Else
Signature = ""
End If
On Error Resume Next
With OutMail
.To = destinatarios
.CC = copia
.BCC = CO
.subject = subject
.HTMLBody = strbody & "<br>" & Signature
.Display 'or use .Display
.Attachments.Add attachment1, olByValue, 1, "ProjectStatus"
.Attachments.Add attachment2, olByValue, 1, "ProjectStatus"
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
I notice that this code includes the word "ProjectStatus" but honestly I have not a deep knowledge of VBA.
Thanks in advance!!
A simple read of the Attachments.Add documentation is all you need, specifically the section on the optional DisplayName parameter:
This parameter applies only if the mail item is in Rich Text format
and Type is set to olByValue : the name is displayed in an Inspector
object for the attachment or when viewing the properties of the
attachment. If the mail item is in Plain Text or HTML format, then the
attachment is displayed using the file name in the Source parameter.
So if you always want to always use the original file name, simply delete the instances of , "ProjectStatus".

Alternatives to automatically images + HTML signatures with body text in emails

I've done a fair bit of research on this topic and I've come to the conclusion that what I'm looking to do is just simply not possible. No matter what method is used from the Outlook object library; it seems that any signature that is automatically populated by functions like .display and .getInspector will always be wiped when .body, .HTMLBody, or .RTFBody are also called afterwards. I've gotten a lot of great advice such as below but it seems like any variation of .body will wipe the signature no matter how the signature is populated.
Dim OutApp As Object
Dim OutMail As Object
Dim signature As String
Set OutApp = CreateObject("Outlook.Application")
OutApp.Session.Logon
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.BodyFormat = olFormatHTML
.HTMLBody = "f"
.Display
End With
signature = OutMail.HTMLBody
I've been thinking lately, would it be possible to take the .htm signature file located in \AppData\Roaming\Microsoft\Signature and render that into the email itself by including it in .body? Does anyone know of any alternatives to using .display and .getInspector to input a signature?
Edit 2:
Dim OutApp As Object
Dim OutMail As Object
Dim signature As String
Set OutApp = CreateObject("Outlook.Application")
OutApp.Session.Logon
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
OutMail.Display
signature = OutMail.HTMLBody
With OutMail
.HTMLBody = "fdA" & signature
'.BodyFormat = olFormatHTML
End With
The body is wiped out because your code explicitly wipes it out. Or, in your particular case, Outlook never applies the signature because it sees that the HTML body was previously set.
Outlook will add the signature when you call Display or GetInspector. In your case, call Display first (at this point the signature is added), then read the HTMLBody property (it will now contain the signature). Merge it with your html body (note that two HTML strings cannot be simply concatenated, you must merge them), then set the HTMLBody property back.

Compile Error When Creating a Submit Button in VBA/Excel 2016

I am trying to create a submit button in Excel 2016 using a macro with the below code
Sub Submitbutton14_Click()
Dim x As Outlook.Application
Dim y As Outlook.MailItem
Set x = CreateObject("Outlook.Application")
Set y = oLapp.CreateItem(0)
With y
.Subject = ""
.CC = ""
.To = "test#email.com"
.Body = ""
.Attachments.Add '(path to the attachment,either hard coded or
' variable)
.Display
End With
Set x = Nothing
Set y = Nothing
'
End Sub
When I run the macro I see a Compile Error: Argument not Optional with Sub Submitbutton14_Click() highlighted in yellow. Can you advise what I am doing wrong? I am completely new to VBA and have found this code online and have modified parts of it to fit my need?
Many Thanks
You need to add an attachment path
https://msdn.microsoft.com/en-us/library/office/ff869553.aspx
Source is required.
Also, you can use new outlook.application, rather than createobject.

Make outlook 2003 macro work when word is the editor?

What I have, is a similar piece of code & i made it work with the outlook editor (hard enough) and I am trying to get it to now work with Word acting as the outlook editor. (Users are used to word mail) I tried: To move the code directly into word under this document and it did nothing. To follow code i saw on: creating an objword objdoc and then pairing it with the outlook class type of deal, with no luck. Here is a sample of code:
Sub SetCategory()
Dim olMessage As Outlook.MailItem
Set olMessage = Application.ActiveInspector.CurrentItem
If olMessage.SenderName = donations Then
olMessage.Categories = "donations"
ElseIf olMessage.SenderName = "Donations" Then
olMessage.Categories = "donations"
End If
With olMessage
.Send
End With
End Sub
When using "word mail" you are not using Outlook. This describes how to invoke Outlook from Word. Once Outlook is open you can use Outlook VBA.
http://www.howto-outlook.com/howto/senddocasmail.htm
Untested, and you will have to remove the parts you do not need.
Sub SendDocAsMail()
Dim oOutlookApp As Outlook.Application
Dim oItem As Outlook.MailItem
On Error Resume Next
'Start Outlook if it isn't running
Set oOutlookApp = GetObject(, "Outlook.Application")
If Err <> 0 Then
Set oOutlookApp = CreateObject("Outlook.Application")
End If
On Error GoTo 0 ' <=== Important to see errors now if there are any
'Create a new message
Set oItem = oOutlookApp.CreateItem(olMailItem)
' --------------------------
'Set oItem = oOutlookApp.ActiveInspector.CurrentItem
If oItem.SenderName = donations Then
oItem.Categories = "donations"
ElseIf oItem.SenderName = "Donations" Then
oItem.Categories = "donations"
End If
' --------------------------
'Allow the user to write a short intro and put it at the top of the body
Dim msgIntro As String
msgIntro = InputBox("Write a short intro to put above your default " & _
"signature and current document." & vbCrLf & vbCrLf & _
"Press Cancel to create the mail without intro and " & _
"signature.", "Intro")
'Copy the open document
Selection.WholeStory
Selection.Copy
Selection.End = True
'Set the WordEditor
Dim objInsp As Outlook.Inspector
Dim wdEditor As Word.Document
Set objInsp = oItem.GetInspector
Set wdEditor = objInsp.WordEditor
'Write the intro if specified
Dim i As Integer
If msgIntro = IsNothing Then
i = 1
'Comment the next line to leave your default signature below the document
wdEditor.Content.Delete
Else
'Write the intro above the signature
wdEditor.Characters(1).InsertBefore (msgIntro)
i = wdEditor.Characters.Count
wdEditor.Characters(i).InlineShapes.AddHorizontalLineStandard
wdEditor.Characters(i + 1).InsertParagraph
i = i + 2
End If
'Place the current document under the intro and signature
wdEditor.Characters(i).PasteAndFormat (wdFormatOriginalFormatting)
'Display the message
oItem.Display
'Clean up
Set oItem = Nothing
Set oOutlookApp = Nothing
Set objInsp = Nothing
Set wdEditor = Nothing
End Sub
Edit: Added, based on comment. This is a step that beginners trip on.
"Since this macro also uses Outlook functionality to create the mail we must add the reference to the project. To do this choose Tools-> References… and select Microsoft Outlook 12.0 Object Library (or 14.0 when using Outlook 2010). After this press OK."
Latest Outlook versions use Word as an email editor by default. There is no need to check out the editor type. The WordEditor property of the Inspector class returns the Microsoft Word Document Object Model of the message being displayed. You can read more about that in the Chapter 17: Working with Item Bodies .
Also you may find the How to automate Outlook and Word by using Visual C# .NET to create a pre-populated e-mail message that can be edited article helpful.

MS Outlook macro to strikeout selected text

The task is to apply strikeout to current font in selected text area.
The difficulty is that Outlook doesn't support recording macros on the fly - it wants code to be written by hand.
For example, the following simple code:
Selection.Font.Strikethrough = True
works for Word, but gives an error for Outlook:
Run-time error '424':
Object required
This assumes that you also have Word installed on your box. If so, you can access most of the Word OM from the Outlook VBE without referencing Word by using the ActiveInspector.WordEditor object.
Sub StrikeThroughinMailItem()
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.Font.Strikethrough = True
End Sub
Here are a few notes on messing around with the open message, there are no checks, it just assumes that you have an open mail item. If you would like to say a little more about what you want to do, and in what version, I may be able to help a little more.
Dim ActiveMessage As MailItem
Dim strHTML As String
Set ActiveMessage = ActiveInspector.CurrentItem
Debug.Print ActiveMessage.Body
Debug.Print ActiveMessage.HTMLBody
strHTML = Replace(ActiveMessage.Body, "This sentence is bold", _
"<STRONG>This sentence is bold</STRONG>")
ActiveMessage.HTMLBody = strHTML
Debug.Print ActiveMessage.HTMLBody
You need to access the Inspector's HTMLEditor or WordEditor. Check the help file for sample code. If you are using WordEditor then you can record macro in Word and incorporate the resultant code into the Outlook macro by using the WordEditor.
Public Sub DoIt()
'must set word as mail editor
'must set reference to word object library
Dim oInspector As Outlook.Inspector
Dim oDoc As Word.Document
Dim oItem As Outlook.MailItem
Set oItem = Outlook.Application.CreateItem(olMailItem)
oItem.BodyFormat = olFormatRichText 'must set, unless default is rich text
Set oInspector = oItem.GetInspector
oInspector.Display 'must display in order for selection to work
Set oDoc = oInspector.WordEditor
'better to use word document instead of selection
'this sample uses selection because word's macro recording using the selection object
Dim oSelection As Word.Selection
Set oSelection = oDoc.Application.Selection
oSelection.TypeText Text:="The task is to apply strikethroughout."
oSelection.MoveLeft Unit:=wdCharacter, Count:=4
oSelection.MoveLeft Unit:=wdCharacter, Count:=7, Extend:=wdExtend
oSelection.Font.Strikethrough = True
End Sub
Jumping off from Todd Main's excellent example above.
I slightly modified the code to work in the inline reply pane as we couldn't find a simple way to add strikethrough to the QAT or ribbon.
I also added an if block to toggle the strikethrough if it was already set.
Sub StrikeThroughinInlineReply()
Dim objOL As Application
Dim objDoc As Object
Dim objSel As Object
Set objOL = Application
Set objDoc = objOL.ActiveExplorer.ActiveInlineResponseWordEditor
Set objSel = objDoc.Windows(1).Selection
If objSel.Font.Strikethrough = False Then
objSel.Font.Strikethrough = True
Else
objSel.Font.Strikethrough = False
End If
End Sub