I'm trying to open an Outlook template (.oft) file from Excel but without appending the user's signature. I can't get this to work.
I know I need to delete the hidden bookmark "_MailAutoSig" but I can't figure out how. I've tried to follow this guide but it's out of date and doesn't work with Outlook / Excel 2016: https://learn.microsoft.com/en-us/previous-versions/office/developer/office-2007/dd492012(v=office.12)#176-working-with-outlook-signatures
Here is my code
Option Explicit
Sub openEmail()
Dim cfgFromEmail As String
Dim cfgNotice As String
Dim cfgTemplate As String
Dim appOutlook As Outlook.Application
Dim newEmail As Outlook.MailItem
Dim rownum As Integer
Dim colnum As Integer
rownum = 6
cfgFromEmail = Sheets("Email").Range("O5").Value
cfgNotice = Sheets("Email").Cells(rownum, 10) '10 = column J
cfgTemplate = Sheets("Email").Cells(rownum, 11) '11 = column K
Set appOutlook = CreateObject("Outlook.Application")
Set newEmail = appOutlook.CreateItemFromTemplate("\\location\to\template\" & cfgTemplate & ".oft")
'Set template = mailApp.CreateItem(olMailItem) 'Creates a blank email
If cfgNotice <> "null" Then 'If is not blank
MsgBox cfgNotice, vbInformation, "Before you send the email"
End If
With newEmail
.SentOnBehalfOfName = cfgFromEmail
.Display 'Show the email
End With
Set newEmail = Nothing
Set appOutlook = Nothing
End Sub
Any help is greatly appreciated. I have spent several hours searching Google and Stack Overflow to no luck.
If the email template is not too complicated, you may be able to just create a new email and create the template without signature using HTML:
Sub emailgenerator
Dim appOutlook As Outlook.Application
Dim newEmail As Outlook.MailItem
Dim emailBody As String
Set appOutlook = CreateObject("Outlook.Application")
Set newEmail = olApp.CreateItem(olMailItem)
emailBody = "<p>Header</p><br><p>body area or something</p>"
emailBody = emailBody & "<table></table>" ' maybe add tables and whatever is needed
With newEmail
.To = "abc#abc.com"
.CC = "def#def.com"
.Subject = "Test"
.SentOnBehalfOfName = "youremail#youremail.com" ' could disregard this
.HTMLBody = emailBody
.Save
.Close olPromptForSave
End With
End Sub
This will take some looking into HTML but you can probably recreate the template with enough effort.
I believe when I tried this method for another project my signature wasn't getting appended automatically as it would with a template but not sure... best of luck
I have found a solution thanks to this stack overflow post
We need to save our template as HTML, then manually create a new email using the HTML code.
I'm yet to add images to the code but I think this will be easy using a find and replace method.
Final code without images:
Option Explicit
Sub openEmail(rownum As Integer)
Dim cfgFromEmail As String
Dim cfgNotice As String
Dim cfgTemplate As String
Dim appOutlook As Outlook.Application
Dim newEmail As Outlook.MailItem
Dim htmlPath As String
'Dim rownum As Integer
'Dim colnum As Integer
'rownum = 6
cfgFromEmail = Sheets("Email").Range("O5").Value
cfgNotice = Sheets("Email").Cells(rownum, 10) '10 = column J
cfgTemplate = Sheets("Email").Cells(rownum, 11) '11 = column K
htmlPath = "\\shared\drive\path\to\template\goes\here\" & cfgTemplate & ".htm"
Set appOutlook = CreateObject("Outlook.Application")
Set newEmail = appOutlook.CreateItem(olMailItem) 'Creates a blank email
If cfgNotice <> "null" Then 'If is not blank
MsgBox cfgNotice, vbInformation, "Before you send the email"
End If
With newEmail
.SentOnBehalfOfName = cfgFromEmail
.HTMLBody = HTMLtoString(htmlPath)
'Refer to and fill in variable items in template
'.Body = Replace(.Body, "<< clientname >>", Worksheets("Clients").Range(1, 2))
'.HTMLBody = Replace(.HTMLBody, "<< clientname >>", Worksheets("Clients").Range(1, 2))
.Display 'Show the email
End With
Set newEmail = Nothing
Set appOutlook = Nothing
End Sub
Function HTMLtoString(htmlPath As String)
'Returns a string after reading the contents of a given file
HTMLtoString = CreateObject("Scripting.FileSystemObject").OpenTextFile(htmlPath).ReadAll()
End Function
In case anyone's looking for solutions not involving parsing HTML tags, here's a relatively simple one. Make sure to have the Microsoft Word library referenced.
Dim myItem As Outlook.MailItem
Dim myInspector As Outlook.Inspector
Dim myDoc As Word.Document
Set myItem = _
Outlook.Application.CreateItemFromTemplate(TemplateName & ".oft")
.Display
Set myInspector = Application.ActiveInspector
Set myDoc = myInspector.WordEditor
myDoc.Bookmarks("_MailAutoSig").Range.Delete
Related
I am looking for VBA code in excel to reply to a selected mail but the below code creates seperate mail which does not have previous messages in conversation (thread) in body. I searched online, but most of them are old codes which are not working currently. Please help.
Sub Test_template()
Dim emailApplication As Object
Dim emailItem As Object
Set emailApplication = CreateObject("Outlook.Application")
Set emailItem = emailApplication.ActiveExplorer.Selection.Item(1).ReplyAll
emailItem.bcc = "XYZ.com"
emailItem.Body = "Hi, have a nice day "
emailItem.Display
Set emailItem = Nothing
Set emailApplication = Nothing
End Sub
Is this what you are trying? I have commented the code and provided relevant MSDN links. If you still get stuck then simply ask.
Option Explicit
Sub Sample()
Dim OutlookApp As Object
Dim OutlookMail As Object
Set OutlookApp = CreateObject("Outlook.Application")
Set OutlookMail = OutlookApp.ActiveExplorer.Selection.Item(1)
'~~> Get MailItem.GetConversation method (Outlook)
' https://learn.microsoft.com/en-us/office/vba/api/outlook.mailitem.getconversation
Dim OutlookConversation As Object
Set OutlookConversation = OutlookMail.GetConversation
'~~> Conversation.GetTable method (Outlook)
' https://learn.microsoft.com/en-us/office/vba/api/outlook.conversation.gettable
Dim OutlookTable As Object
Set OutlookTable = OutlookConversation.GetTable
'~~> Obtains a 2D array from the Table.
' https://learn.microsoft.com/en-us/office/vba/api/outlook.table.getarray
Dim OutlookAr As Variant
OutlookAr = OutlookTable.GetArray(OutlookTable.GetRowCount)
Dim OutlookReplyToThisMail As Object
Set OutlookReplyToThisMail = OutlookMail.Session.GetItemFromID(OutlookAr(UBound(OutlookAr), 0))
Dim MyMessage As String: MyMessage = "Hi, have a nice day "
With OutlookReplyToThisMail.ReplyAll
.BCC = "XYZ.com"
.HTMLBody = MyMessage & .HTMLBody
.Display
End With
End Sub
.ReplyAll produces the expected result but is overwritten by emailItem.Body = "Hi, have a nice day ".
Option Explicit
Sub Test_template()
Dim emailApplication As Object
Dim emailItem As Object
'Set emailApplication = CreateObject("Outlook.Application")
' mail has to be slelected in Outlook application so it has to be open already
Set emailApplication = GetObject(, "Outlook.Application")
Set emailItem = emailApplication.ActiveExplorer.Selection.Item(1).ReplyAll
emailItem.BCC = "XYZ.com"
'emailItem.Body = "Hi, have a nice day "
emailItem.Body = "Hi, have a nice day " & emailItem.Body
' or
'emailItem.htmlBody = "Hi, have a nice day " & emailItem.htmlBody
emailItem.Display
Set emailItem = Nothing
Set emailApplication = Nothing
End Sub
I am Using windows 10, Excel 2013 and Outlook 2013
I am new to Macro. I need macro to perform below Task:
1) From Excel I want to open Outlook if Outlook is closed and move Point.2, If outlook is already open then move to Point.2
2) Search for a specific email in outlook in all folders and sub folders with criteria “A” and “B”
a) Latest dated received or sent email.
b) With specific Subject contains “Approved”, this to be taken from active cell.
3) Open the found latest mail as per above criteria do “Reply all”.
4) Write a comment and display the mail or send.
Below code was my start, but it has the following issues:
The code search for the exact name, while i need to search for any email contain the word which in active cell.
The code search only in sent emails, while i need to search in both inbox and sent.
The code just open the email, i need to write template comment as well.
Many thanks in advance.
Sub ReplyMail_No_Movements()
' Outlook's constant
Const olFolderSentMail = 5
' Variables
Dim OutlookApp As Object
Dim IsOutlookCreated As Boolean
Dim sFilter As String, sSubject As String
' Get/create outlook object
On Error Resume Next
Set OutlookApp = GetObject(, "Outlook.Application")
If Err Then
Set OutlookApp = CreateObject("Outlook.Application")
IsOutlookCreated = True
End If
On Error GoTo 0
' Restrict items
sSubject = ActiveCell.Value
sFilter = "[Subject] = '" & sSubject & "'"
' Main
With OutlookApp.Session.GetDefaultFolder(olFolderSentMail).Items.Restrict(sFilter)
If .Count > 0 Then
.Sort "ReceivedTime", True
With .Item(1).replyall
.Display
'.Send
End With
Else
MsgBox "No emails found with Subject:" & vbLf & "'" & sSubject & "'"
End If
End With
' Quit Outlook instance if it was created by this code
If IsOutlookCreated Then
OutlookApp.Quit
Set OutlookApp = Nothing
End If
End Sub
It seems work now:
Sub ReplyAllLastEmailFromInboxAndSent()
Dim olApp As Outlook.Application
Dim olNs As Namespace
Dim Fldr As MAPIFolder
Dim objMail As Object
Dim objReplyToThisMail As MailItem
Dim lngCount As Long
Dim objConversation As Conversation
Dim objTable As Table
Dim objVar As Variant
Dim strBody As String
Dim searchFolderName As String
Set olApp = Session.Application
Set olNs = olApp.GetNamespace("MAPI")
Set Fldr = olNs.GetDefaultFolder(olFolderSentMail)
searchFolderName = "'" & Outlook.Session.GetDefaultFolder(olFolderInbox).FolderPath & "','" & Outlook.Session.GetDefaultFolder(olFolderSentMail).FolderPath & "'"
lngCount = 1
For Each objMail In Fldr.Items
If TypeName(objMail) = "MailItem" Then
If InStr(objMail.Subject, ActiveCell.Value) <> 0 Then
Set objConversation = objMail.GetConversation
Set objTable = objConversation.GetTable
objVar = objTable.GetArray(objTable.GetRowCount)
Set objReplyToThisMail = olApp.Session.GetItemFromID(objVar(UBound(objVar), 0))
With objReplyToThisMail.replyall
strBody = "Dear " & "<br>" & _
"<p>Following up with the below. May you please advise?" & _
"<p>Thank you," & vbCrLf
.HTMLBody = strBody & .HTMLBody
.Display
End With
Exit For
End If
End If
Next objMail
Set olApp = Nothing
Set olNs = Nothing
Set Fldr = Nothing
Set objMail = Nothing
Set objReplyToThisMail = Nothing
lngCount = Empty
Set objConversation = Nothing
Set objTable = Nothing
If IsArray(objVar) Then Erase objVar
End Sub
I have code that sends emails using the default Outlook account.
I tried changing the code to send from a specific email. When I run the macro, nothing happens.
Is something wrong with the code, or is it not working due to another issue (with Outlook and the accounts/permissions associated with it)?
Sub CommandButton1_Click()
Dim wb As Workbook
Dim olApp As Outlook.Application
Dim olMail As Outlook.MailItem
Dim q As Long
Dim oAccount As Outlook.Account
Set wb = ThisWorkbook
For Each oAccount In Outlook.Application.Session.Accounts
If oAccount = "theEmailiWantToUse#domain.com" Then
For q = 2 To 3 'LastRow
eName = wb.Sheets(1).Cells(q, 2).Value
Set olApp = New Outlook.Application
Set olMail = olApp.CreateItem(olMailItem)
mailBody = "Hello, "
With olMail
.To = Worksheets("Emails").Cells(q, 4).Value
.Subject = eName
.HTMLBody = "<!DOCTYPE html><html><head><style>"
.HTMLBody = .HTMLBody & "body{font-family: Calibri, ""Times New Roman"", sans-serif; font-size: 14px}"
.HTMLBody = .HTMLBody & "</style></head><body>"
.HTMLBody = .HTMLBody & mailBody & "</body></html>"
Set .SendUsingAccount = oAccount
.Display
' .Send
End With
Next
Else
End If
Next
Set olMail = Nothing
Set olApp = Nothing
End Sub
I know I have access to the email I would like to send emails from, as I can select it from Outlook and it works.
Add this line within the olMail
.SentOnBehalfOfName = "youraddress" 'here change this
please use this routine to find Account number of sender .
Sub Which_Account_Number()
'Don't forget to set a reference to Outlook in the VBA editor
Dim OutApp As Outlook.Application
Dim I As Long
Set OutApp = CreateObject("Outlook.Application")
For I = 1 To OutApp.Session.Accounts.Count
MsgBox OutApp.Session.Accounts.Item(I) & " : This is account number " & I
Next I
End Sub
Then
.SendUsingAccount = olApp.Session.Accounts.Item(5)' whatever account index number you want to send. i have chosen 5
instead of
Set .SendUsingAccount = oAccount
This method works for me . You can further integrate this concept in your programme. Please ensure Reference to Outlook Object Library is set in Tools/References.
I have a template that is stationed in an excel file. Once I click the preview button, this template will be displayed in outlook as well as its subject, to and etc.
I have this code that works fine but is not working in the body field.
Sub previewMail()
Dim objMail, objOutLook As Object
Dim rngTo, rngCC, rngBCC, rngBody As Range
Dim lRow As Long
Dim i As Integer
Set objOutLook = CreateObject("Outlook.Application")
Set objMail = objOutLook.CreateItem(0)
Set main = ThisWorkbook.Sheets("Main")
lRow = main.Cells(Rows.Count, 2).End(xlUp).Row
For i = 11 To lRow
With main
Set rngTo = .Range("B" & i)
Set rngBody = .Range(.Range("C10:N30"), .Range("C10:N30"))
End With
With objMail
.To = rngTo.Value
.Subject = "Sample"
'i like the rngbody to be here
.HTMLBody = RangetoHTML(rngBody)' from Ron de Bruin site
.Display
End With
Next i
End Sub
This is the template stationed in the said range above.
Can anyone please help me figure this out? I have tried this from Ron de Bruin but I can't make it work. This only gives a product that is an "invisible table".
EDIT: OP has indicated text is not in range, but in a textbox in front of range.
Use this code to find the textbox name:
for i = 1 to activesheet.chartobjects.count
debug.print chartobjects(i).name
next i
It will be like Textbox1 or something, then use(untested):
dim strBody as string
Set strBody = activesheet.chartobjects("Textbox1").Value
.HTMLBody = strbody
Try Range.PasteAndFormat wdChartPicture
Example
Option Explicit
Sub previewMail()
Dim objMail, Main, objOutLook As Object
Dim rngTo, rngCC, rngBCC, rngBody As Range
Dim lRow As Long
Dim i As Integer
Dim wordDoc As Word.Document '<---
Set objOutLook = CreateObject("Outlook.Application")
Set objMail = objOutLook.CreateItem(0)
Set Main = ThisWorkbook.Sheets("Main")
Set wordDoc = objMail.GetInspector.WordEditor '<---
lRow = Main.Cells(Rows.count, 2).End(xlUp).Row
For i = 11 To lRow
With Main
Set rngTo = .Range("B" & i)
Set rngBody = .Range(.Range("C10:N30"), .Range("C10:N30"))
rngBody.Copy '<---
End With
With objMail
.To = rngTo.Value
.Subject = "Sample"
.Display
wordDoc.Range.PasteAndFormat wdChartPicture '<---
' Or
'wordDoc.Range.PasteAndFormat wdChartPicture & .HTMLBody = " "
End With
Next i
End Sub
Make sure to set references to the Microsoft Outlook and Microsoft Word Object libraries
Tools > References...
I'm trying to get all the cells from my Excel worksheet in column 1.
My code throws an error.
"object required"
Public Sub emailList()
'Setting up the Excel variables.
Dim olApp As Object
Dim olMailItm As Object
Dim iCounter As Integer
Dim Dest As Variant
Dim SDest As String
'Create the Outlook application and the empty email.
Set olApp = CreateObject("Outlook.Application")
Set olMailItm = olApp.CreateItem(0)
'Using the email, add multiple recipients, using a list of addresses in column A.
With olMailItm
SDest = ""
For iCounter = 1 To WorksheetFunction.CountA(Workbooks("Book1.xls").Sheets(1).Columns(1))
If SDest = "" Then
SDest = Range.Cells(iCounter, 1).Value
Else
SDest = SDest & ";" & Range.Cells(iCounter, 1).Value
End If
Next iCounter
'Do additional formatting on the BCC and Subject lines, add the body text from the spreadsheet, and send.
.BCC = SDest
.Subject = "FYI"
.Body = ActiveSheet.TextBoxes(1).Text
.Send
End With
'Clean up the Outlook application.
Set olMailItm = Nothing
Set olApp = Nothing
End Sub
How do I get a worksheet object?
I tried
Workbooks("Book1.xls").Sheet1.Columns(1)
but this also throws an error.
I'm running the code in Outlook and have an open Excel window.
You will need to add a reference to the Excel object library, which is done in the VBA editor, under Tools / Add References. Just having Excel open isn't enough.