How to send worksheet in email body? - vba

Is there any way I can attach as well as send a worksheet as an email body.
The below VBA code sends the worksheet as an attachment.
How can I send a worksheet in the body of email?
Sub Email()
Dim OutApp As Object
Dim OutMail As Object
Dim wbTemp As Workbook
Dim strFilename As String
Dim Sendrng As Range
ThisWorkbook.Worksheets("Test Worksheet").Copy
Set wbTemp = ActiveWorkbook
wbTemp.SaveAs ThisWorkbook.Path & "/" & "TestWb", XlFileFormat.xlOpenXMLWorkbook
strFilename = wbTemp.FullName
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = "test#testdomain.com"
.CC = ""
.BCC = ""
.Subject = "Test Email"
.Body = ""
.Attachments.Add strFilename
.display
End With
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
wbTemp.Close
Kill strFilename
End Sub

Private Sub CommandButton1_Click()
Dim AWorksheet As Worksheet
Dim Sendrng As Range
Dim rng As Range
On Error GoTo StopMacro
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Set Sendrng = Worksheets("Sheet1").Range("A1:g15")
Set AWorksheet = ActiveSheet
With Sendrng
.Parent.Select
Set rng = ActiveCell
.Select
ActiveWorkbook.EnvelopeVisible = True
With .Parent.MailEnvelope
With .Item
.To = "recipient"
.CC = ""
.BCC = ""
.Subject = "My subject"
.Send
End With
End With
rng.Select
End With
AWorksheet.Select
Sheet1.Activate
Range("c2:c3").ClearContents
Range("e2:e3").ClearContents
Range("c5") = ""
Range("B8:b10").ClearContents
Range("c8:c10").ClearContents
Range("d8:d10").ClearContents
Range("e8:e10").ClearContents
Range("f8:f10").ClearContents
Range("g8:g10").ClearContents
Range("b13") = ""
StopMacro:
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
ActiveWorkbook.EnvelopeVisible = False
End Sub
you should add your code that also copies it to this. Forgive all the crap you dont need here, I just copy and pasted one I have been using

Related

Copy Text and Charts into Outlook Email with VBA

I'm trying to copy/paste the text and charts from a worksheet into an Outlook email. This works for the text in the cells, but not the charts (there are currently two charts, but I may add more later). I also noticed that the wEditor object is empty at runtime:
Sub Mail_Selection_Range_Outlook_Body()
Dim rng As Range
Dim OutApp As Object
Dim OutMail As Object
Dim overDueSht As Worksheet
Set overDueSht = Worksheets("Overdue")
lastRowOverDueSht = overDueSht.Cells(Rows.Count, 3).End(xlUp).Row
On Error Resume Next
Set rng = overDueSht.Range("A1", overDueSht.Cells(lastRowOverDueSht, 10))
On Error GoTo 0
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 = "my#email.com"
.CC = ""
.BCC = ""
.Subject = "Overdue Reports"
.HTMLBody = RangetoHTML(rng)
Set wEditor = OutApp.GetInspector.WordEditor
arCharts = Array(1, 2)
For x = 1 To UBound(arCharts)
overDueSht.ChartObjects(arCharts(x)).Activate
ActiveChart.Copy
wEditor.Application.Selection.Start = Len(OutMail.HTMLBody)
wEditor.Paragraphs(1).Range.Paste
wEditor.Application.Selection.End = wEditor.Application.Selection.Start
wEditor.Application.Selection.Paste
Next x
.send
End With
On Error GoTo 0
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
I had similar problem as you and i found out that the remedium is to display message before pasting.
EDIT: Add references: Microsoft Outlook and Microsoft Word. It works for me after changes.
Sub Mail_Selection_Range_Outlook_Body()
Dim rng As Range
Dim OutApp As Outlook.Application
Dim OutMail As Outlook.MailItem
Dim overDueSht As Worksheet
Set overDueSht = Worksheets("Overdue")
lastRowOverDueSht = overDueSht.Cells(Rows.Count, 3).End(xlUp).Row
On Error Resume Next
Set rng = overDueSht.Range("A1", overDueSht.Cells(lastRowOverDueSht, 10))
On Error GoTo 0
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
Set OutApp = New Outlook.Application
Set OutMail = OutApp.CreateItem(olMailItem)
On Error Resume Next
With OutMail
.To = "my#email.com"
.CC = ""
.BCC = ""
.Subject = "Overdue Reports"
.HTMLBody = "gfdgdsgfds"
.Display
Dim weditor As Word.Document
Set weditor = OutMail.GetInspector.WordEditor
For Each char_t In overDueSht.ChartObjects
char_t.Chart.ChartArea.Copy
weditor.Range(0, 0).Paste
Next
.Send
End With
On Error GoTo 0
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
Set OutMail = Nothing
Set OutApp = Nothing
End Sub

Why is this creating two e-mails per workbook?

I am taking a worksheet from a master workbook and creating a separate workbook for each one
These workbooks are then saved into a folder and then each workbook is added to an e-mail.
Each workbook is creating 2 e-mails but I can't see why from the code?
Sub MoveandSaveWorkBooks()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Dim wK As Worksheet
For Each wK In ThisWorkbook.Worksheets
If wK.name = "Master Data" Then
ElseIf wK.name = "Button" Then
Else
wK.Copy
Selection.RowHeight = 84.75
Cells.EntireColumn.AutoFit
ActiveWorkbook.Password = UserInput
ActiveWorkbook.SaveAs ThisWorkbook.Path & "\" & wK.name & ".xlsx"
Dim OlApp As Object
Dim NewMail As Object
Set OlApp = CreateObject("Outlook.Application")
Set NewMail = OlApp.CreateItem(0)
On Error Resume Next
With NewMail
.To = ""
.CC = ""
.BCC = ""
.Subject = ""
.Body = ""
.Attachments.Add ActiveWorkbook.FullName
.display
End With
On Error GoTo 0
Set NewMail = Nothing
Set OlApp = Nothing
ActiveWorkbook.Close True
End If
Next wK
Application.DisplayAlerts = True
Application.ScreenUpdating = True

Send selected range via email with htm signature by vba

I need to send selection range from excell by email and add signature from htm file. I have next code to send selection and it works well:
Sub Send_Selection()
'Working in Excel 2002-2013
Dim Sendrng As Range
Dim strbody As Range
On Error GoTo StopMacro
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'Note: if the selection is one cell it will send the whole worksheet
Set Sendrng = Selection
'Create the mail and send it
With Sendrng
ActiveWorkbook.EnvelopeVisible = True
With .Parent.MailEnvelope
' Set the optional introduction field thats adds
' some header text to the email body.
.Introduction = ""
With .Item
.To = "dg#siz66.ru"
.CC = ""
.BCC = ""
.Subject = "My subject"
.send
End With
End With
End With
StopMacro:
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
ActiveWorkbook.EnvelopeVisible = False
End Sub
Next I have code to generate mail with signature from html file:
Sub Mail_Outlook_With_Signature_Html_2()
' Don't forget to copy the function GetBoiler in the module.
' Working in Office 2000-2013
Dim OutApp As Object
Dim OutMail As Object
Dim strbody As String
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 = "C:\Users\d.gazdovsky\Downloads\sign.htm"
If Dir(SigString) <> "" Then
Signature = GetBoiler(SigString)
Else
Signature = ""
End If
On Error Resume Next
With OutMail
.To = ""
.CC = ""
.BCC = ""
.Subject = "This is the Subject line"
.HTMLBody = strbody & "<br>" & Signature
.display 'or use .Display
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
Function GetBoiler(ByVal sFile As String) As String
Dim fso As Object
Dim ts As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.GetFile(sFile).OpenAsTextStream(1, -2)
GetBoiler = ts.readall
ts.Close
End Function
Now I need only to combine this macros to solve my problem. Please help me with it. Thanks in advance
UPD 1: I try thi code, but it give error..
Sub Mail_Outlook_With_Signature_Html_2()
' Don't forget to copy the function GetBoiler in the module.
' Working in Office 2000-2013
Dim OutApp As Object
Dim OutMail As Object
Dim Sendrng As Range
Dim strbody As Range
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'Note: if the selection is one cell it will send the whole worksheet
Set Sendrng = Selection & Signature
'Create the mail and send it
With Sendrng
ActiveWorkbook.EnvelopeVisible = True
With .Parent.MailEnvelope
' Set the optional introduction field thats adds
' some header text to the email body.
.Introduction = ""
With .Item
.To = "dg#siz66.ru"
.CC = ""
.BCC = ""
.Subject = "My subject"
.send
End With
End With
End With
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
'Change only Mysig.htm to the name of your signature
SigString = "C:\Users\d.gazdovsky\Downloads\sign.htm"
If Dir(SigString) <> "" Then
Signature = GetBoiler(SigString)
Else
Signature = ""
End If
On Error Resume Next
With OutMail
.To = ""
.CC = ""
.BCC = ""
.Subject = "This is the Subject line"
'.HTMLBody = Sendrng & "<br>" & Signature
.display 'or use .Display
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
Function GetBoiler(ByVal sFile As String) As String
Dim fso As Object
Dim ts As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.GetFile(sFile).OpenAsTextStream(1, -2)
GetBoiler = ts.readall
ts.Close
End Function

Sending email with VBA under the same Outlook conversation

I'm using the basic VBA code to send an email with a copy of my spreadsheet on a daily basis. The email subject is always the same.
I want these emails to appear in Outlook as the same conversation, so that they are nested/threaded when using Conversation view. However, these emails always come up as a new conversation.
How can I set a property in the OutMail variable below similar to .subject etc to create my own ConversationID / ConversationIndex that is always identical so that emails appear nested?
VBA code:
Dim Source As Range 'For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
Dim Dest As Workbook
Dim wb As Workbook
Dim TempFilePath As String
Dim TempFileName As String
Dim FileExtStr As String
Dim FileFormatNum As Long
Dim OutApp As Object
Dim OutMail As Object
Set Source = Nothing
On Error Resume Next
Set Source = Range("A1:AQ45").SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If Source Is Nothing Then
MsgBox "The source is not a range or the sheet is protected, please correct and try again.", vbOKOnly
Exit Sub
End If
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Set wb = ActiveWorkbook
Set Dest = Workbooks.Add(xlWBATWorksheet)
Source.Copy
With Dest.Sheets(1)
.Cells(1).PasteSpecial Paste:=8
.Cells(1).PasteSpecial Paste:=xlPasteValues
.Cells(1).PasteSpecial Paste:=xlPasteFormats
.Cells(1).Select
Application.CutCopyMode = False
End With
TempFilePath = "C:\temp\"
TempFileName = "MyReport " & Format(Now, "yyyy-mm-dd hh-mm-ss")
FileExtStr = ".xlsx": FileFormatNum = 51
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With Dest
.SaveAs TempFilePath & TempFileName & FileExtStr, FileFormat:=FileFormatNum
On Error Resume Next
End With
With Dest
With OutMail
.to = "xyz#zyx.com"
.CC = ""
.BCC = ""
.Subject = "Subject Report 1"
.HTMLBody = RangetoHTML(Range("A1:AQ45"))
.Attachments.Add Dest.FullName
.Send
End With
End With
Set OutMail = Nothing
Set OutApp = Nothing
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
With Dest
On Error GoTo 0
.Close savechanges:=False
End With
This is the Outlook code that you can port over to Excel, using the method I suggest in the comments above.
Sub test()
Dim m As MailItem
Dim newMail As MailItem
Dim NS As NameSpace
Dim convo As Conversation
Dim cItem
Dim entry As String 'known conversationID property
Set NS = Application.GetNamespace("MAPI")
'Use the EntryID of a known item
'## MODIFY THIS BASED ON YOUR ENTRYID PROPERTY!! ##
entry = "0000000019EF3F5F49714748915AA379833C20460700D6CCDE850A3B9D41A5B930CCE1E12030000337DBD42F00003C7DFC9FAAF8254DACC71DEEEC1DF0A30003ADA9AF2D0000"
'Get a handle on this item:
Set m = NS.GetItemFromID(entry)
'Get a handle on the existing conversation
Set convo = m.GetConversation
'Get a handle on the conversation's root item:
Set cItem = convo.GetRootItems(1)
'Create your new email as a reply thereto:
Set newMail = cItem.Reply
'Modify the new mail item as needed:
With newMail
.To = ""
.CC = ""
.BCC = ""
.Subject = "Subject Report 1"
.HTMLBody = RangeToHTML(Range("A1:AQ45"))
.Attachments.Add Dest.FullName
.Display
'.Send
End With
End Sub

Send Mail with email address in 4 columns

I send email with Ron de Bruin's script where it has option for sending of email address from column B value.
I have at least 4 columns of email address from column B to E. How can I modify this to send this e-mail?
Example:
Make a list in Sheets("Sheet1") with :
In column A : Names of the people
In column B : E-mail addresses
In column C:Z : Filenames like this: C:\Data\Book2.xls (doesn't have to be Excel files)
The macro will loop through each row in Sheet1 and if there is an e-mail address in column B and file name(s) in column C:Z it will create a mail with this information and send it.
Sub Send_Files()
'Working in Excel 2000-2013
'For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
Dim OutApp As Object
Dim OutMail As Object
Dim sh As Worksheet
Dim cell As Range
Dim FileCell As Range
Dim rng As Range
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
Set sh = Sheets("Sheet1")
Set OutApp = CreateObject("Outlook.Application")
For Each cell In sh.Columns("B").Cells.SpecialCells(xlCellTypeConstants)
'Enter the path/file names in the C:Z column in each row
Set rng = sh.Cells(cell.Row, 1).Range("C1:Z1")
If cell.Value Like "?*#?*.?*" And _
Application.WorksheetFunction.CountA(rng) > 0 Then
Set OutMail = OutApp.CreateItem(0)
With OutMail
.to = cell.Value
.Subject = "Testfile"
.Body = "Hi " & cell.Offset(0, -1).Value
For Each FileCell In rng.SpecialCells(xlCellTypeConstants)
If Trim(FileCell) <> "" Then
If Dir(FileCell.Value) <> "" Then
.Attachments.Add FileCell.Value
End If
End If
Next FileCell
.Send 'Or use .Display
End With
Set OutMail = Nothing
End If
Next cell
Set OutApp = Nothing
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
End Sub
MASSIVE EDIT
As per your comment, the code below is changed. Should be working under the assumption that there is a filename in Column F. The lines to remove/comment out are marked in the code below in case you don't want this requirement.
Private Sub Send_Files()
'Working in Excel 2000-2013
'For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
'--BK201 mod: http://stackoverflow.com/questions/20776481/send-mail-with-email-address-in-4-columns--'
Dim OutApp As Object
Dim OutMail As Object
Dim Sh As Worksheet
Dim FileCell As Range
Dim Rec As Range, RecRng As Range, RecList As Range, RecMail As Range
Dim FileRng As Range
Dim RecStr As String
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
Set Sh = ThisWorkbook.Sheets("Sheet1")
Set RecList = Sh.Range("B:B")
Set OutApp = CreateObject("Outlook.Application")
For Each Rec In RecList
With Sh
Set RecRng = .Range("B" & Rec.Row & ":E" & Rec.Row)
Set FileRng = .Range("F" & Rec.Row)
End With
RecStr = ""
For Each RecMail In RecRng
If RecMail.Value Like "?*#?*.?*" Then
RecStr = RecStr & RecMail.Value & ";"
End If
Next RecMail
If Len(FileRng.Value) > 0 Then '--Comment out if alright to send without attachment.
Set OutMail = OutApp.CreateItem(0)
With OutMail
.to = RecStr
.Subject = "Testfile"
.Body = "Hi " & Rec.Offset(0, -1).Value
On Error Resume Next
For Each FileCell In FileRng
If Trim(FileCell) <> "" Then
If Dir(FileCell.Value) <> "" Then
.Attachments.Add FileCell.Value
End If
End If
Next FileCell
.Display '.Send
End With
Set OutMail = Nothing
Else '--Comment out if alright to send without attachment.
Exit For '--Comment out if alright to send without attachment.
End If '--Comment out if alright to send without attachment.
Next Rec
Set OutApp = Nothing
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
End Sub
Set-up:
Result:
Hope this helps. :)