I have a table in Excel that I want to send to a distribution list in Outlook with the table in the email body.
Using MVP Ron de Bruin's examples and a few others on here I've got code that keeps some of the table formatting but doesn't copy the cells colour if it is a gradient (please use the images as reference).
Sub DisplayEmailButton_Click()
Mail_Selection_Range_Outlook_Body
End Sub
Sub Mail_Selection_Range_Outlook_Body()
Dim rng As Range
Dim OutApp As Object
Dim OutMail As Object
Set rng = Nothing
On Error Resume Next
Set rng = Sheets("Sheet1").Range("C2:Q18").SpecialCells(xlCellTypeVisible)
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 = "Team01"
.CC = ""
.BCC = ""
.Subject = "Daily Statistics"
.HTMLBody = "Please see attached daily statistics." & vbCrLf &
RangetoHTML(rng)
.Display
End With
On Error GoTo 0
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
Function RangetoHTML(rng As Range)
Dim TempFile As String, ddo As Long
TempFile = Environ$("temp") & "\" & Format(Now, "dd-mm-yy h-mm-ss") & ".htm"
' Temporary publish the rng range to a htm file
ddo = ActiveWorkbook.DisplayDrawingObjects
ActiveWorkbook.DisplayDrawingObjects = xlHide
With ActiveWorkbook.PublishObjects.Add( _
SourceType:=xlSourceRange, _
Filename:=TempFile, _
Sheet:=ActiveSheet.Name, _
Source:=Union(rng, rng).Address, _
HtmlType:=xlHtmlStatic)
.Publish True
.Delete
End With
ActiveWorkbook.DisplayDrawingObjects = ddo
'Read all data from the htm file into RangetoHTML
With
CreateObject("Scripting.FileSystemObject").GetFile(TempFile)
.OpenAsTextStream(1, -2)
RangetoHTML = Replace(.ReadAll, "align=center x:publishsource=", "align=left
x:publishsource=")
.Close
End With
'Delete the htm file we used in this function
Kill TempFile
End Function
As Tim suggested I was expecting way too much from that procedure (Thank you, Tim, for the advice!) so I looked into a workaround. If the range is saved as a picture then it keeps all the formatting and the picture can then easily be attached to an email or displayed in the body of the email.
To save as a picture:
Dim Wb As ThisWorkbook
Dim Ws As Worksheet
Dim Ch As Chart
Set Rng = Ws.Range("A1:G18")
Set Ch = Charts.Add
Ch.Location xlLocationAsObject, "Sheet2"
Set Ch = ActiveChart
ActiveChart.Parent.Name = "StatsTemp"
ActiveSheet.ChartObjects("StatsTemp").Height = Rng.Height
ActiveSheet.ChartObjects("StatsTemp").Width = Rng.Width
Rng.CopyPicture xlScreen, xlBitmap
Ch.Paste
Ch.Export Environ("UserProfile") & "\Desktop" & "\" & Format("TempImage") & ".jpg"
Worksheets("Sheet2").ChartObjects("StatsTemp").Delete
Worksheets("Sheet1").Activate
The above code saves the range as an image "TempImage.JPG" to the users desktop by creating a new chart on sheet 2, pasting the range to the chart then saves the chart as an image and deletes the chart.
To attach the picture to an email in the email body:
Dim StrBody As String
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
StrBody = "Some text here." & "<br>"
On Error Resume Next
With OutMail
.to = "email address"
.CC = ""
.BCC = ""
.Subject = "Email Subject"
.HTMLBody = StrBody & "<img src = '" & Environ("userProfile") &
"\desktop\TempImage.jpg'>"
.Display
End With
On Error GoTo 0
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
Set OutMail = Nothing
Set OutApp = Nothing
The above code creates an email using Microsoft Outlook which contains the saved image file in the email body and displays the email.
The image can be deleted after using:
Kill Environ("UserProfile") & "\Desktop" & "\TempImage.jpg"
Hopefully, this will be of some use to someone!
Credit to Ron de Bruin Microsoft Office MVP for his WinTips!
Related
I am trying to save two worksheets in a workbook as separate files to company network locations and then attach those files to an email.
Sub Test_Module_Peter()
'
Dim OutApp As Object
Dim OutMail As Object
Dim SPpath As String
Dim SCpath As String
Dim SPfilename As String
Dim SCfilename As String
Dim SPFullFilePath As String
Dim SCFullFilePath As String
Dim wb As Workbook
Dim Cell As Range
Application.ScreenUpdating = False
' export a copy of PER SP Form
Sheets("PER SP").Select
Sheets("PER SP").Copy
' Remove formulas from SP sheet
With ActiveSheet.UsedRange
.Cells.Copy
.Cells.PasteSpecial xlPasteValues
.Cells(1).Select
End With
Application.CutCopyMode = False
' Save a copy of the SP PER Form
SPpath = "\\UKRLTD008\Company\...\...\...\2019\"
SPfilename = "TEST - PER SP ABL90_2019 " & Range("M1")
SPFullFilePath = SPpath & SPfilename
ActiveWorkbook.SaveAs filename:=SPpath & SPfilename, FileFormat:=52
ActiveWorkbook.Close SaveChanges = True
' select ABL90 Credit Claim Master Spreadsheet
For Each wb In Application.Workbooks
If wb.Name Like "ABL90 Credit Claim Master*" Then
wb.Activate
End If
Next
' export a copy of PER SC Form
Sheets("PER SC").Select
Sheets("PER SC").Copy
' Remove formulas from SC sheet
With ActiveSheet.UsedRange
.Cells.Copy
.Cells.PasteSpecial xlPasteValues
.Cells(1).Select
End With
Application.CutCopyMode = False
' Save a copy of the SC PER Form
SCpath = "\\UKRLTD008\Company\...\...\...\2019\"
SCfilename = "TEST - PER SC ABL90_2019 " & Range("M1")
SCFullFilePath = SCpath & SCfilename
ActiveWorkbook.SaveAs filename:=SCpath & SCfilename, FileFormat:=52
ActiveWorkbook.Close SaveChanges = True
' Send the SP PER Form to RMED
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With OutMail
.SentOnBehalfOfName = "sales#radiometer.co.uk"
.To = "laura.valenti#radiometer.co.uk"
.CC = ""
.BCC = ""
.Subject = "RLTD PER Forms " & Range("M1")
.Body = "Hi " & vbNewLine & vbNewLine & "Please find attached ABL90 PER's" & vbNewLine & vbNewLine & "Thank you"
.Attachments.Add SPFullFilePath
.Attachments.Add SCFullFilePath
.Display
End With
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
It saves the files, but when I try to add them as attachments to the email, the following error occurs:
Run-time error '-2147024894(80070002)': Cannot find this file. Verify the path and file name are correct.
I tried to save the path and filename together as FullFilePath for each file but it doesn't seem to work, can anyone tell me why?
I want to insert a table of data from Sheet1 of my Excel workbook and my default signature.
I tried using HTMLBody but it displays the signature either before the table is displayed or nothing at all.
I tried changing the positions of the .HTMLBody.
I have to to send a mail of the below format:
To:
CC:
BCC:
Subject:
Body: should contain "Hi Please find below the details"
Then the Excel table with the data of range ("A3:F3)
Then my signature (which is the default signature in Outlook or something which could be created)
and SEND.
The below is the code.
Sub esendtable()
Dim outlook As Object
Dim newEmail As Object
Dim xInspect As Object
Dim pageEditor As Object
Set outlook = CreateObject("Outlook.Application")
Set newEmail = outlook.CreateItem(0)
With newEmail
.To = "avc#123.com"
.CC = ""
.BCC = ""
.Subject = "Data - " & Date
.Body = "Please find below the data"
.Display
Set xInspect = newEmail.GetInspector
Set pageEditor = xInspect.WordEditor
Sheet1.Range("B3:F3").Copy
pageEditor.Application.Selection.Start = Len(.Body)
pageEditor.Application.Selection.End =
pageEditor.Application.Selection.Start
pageEditor.Application.Selection.PasteAndFormat (wdFormatPlainText)
.Display
'.Send
Set pageEditor = Nothing
Set xInspect = Nothing
End With
Set newEmail = Nothing
Set outlook = Nothing
End Sub
You can handle your email's body by
Outlook.CreateItem(olMailItem).GetInspector.WordEditor.Range
So following simple code snippet
preserves the standard signature for a new email
pastes the Excel range as range, picture or plain text
adds text before Excel range and/or between it and signature
With pageEditor.Range
.Collapse 1 ' wdCollapseStart
.InsertBefore "Hi Please find below the details" & vbCrLf
.Collapse 0 ' wdCollapseEnd
.InsertAfter "Text before signature" & vbCrLf
.Collapse 1 ' wdCollapseStart
Sheet1.Range("B3:F3").Copy
.Paste
'.PasteAndFormat 13 ' wdChartPicture
'.PasteAndFormat 22 ' wdFormatPlainText
End With
If you add a reference to "Microsoft Word x.x Object Library" (and "Microsoft Outlook x.x Object Library") for early binding, you can replace the numbers by the corresponding Word ENUM constants.
You can use my code as below
Set outlook = CreateObject("Outlook.Application")
Set newEmail = outlook.CreateItem(0)
With newEmail
.display
signature = newEmail.HTMLBody
sig = HtmlToText(signature)
.To = ""
.CC = ""
.Subject = "Test"
.HTMLBody = "Dear team," & "<br>" & "<br>" & "Please check and fix the issue below. Thank you!"
Set xInspect = newEmail.GetInspector
Set pageEditor = xInspect.WordEditor
wb.Sheets(1).Range("a1:h" & lr).SpecialCells(xlCellTypeVisible).Copy
pageEditor.Application.Selection.Start = Len(.body)
pageEditor.Application.Selection.End = pageEditor.Application.Selection.Start
pageEditor.Application.Selection.PasteAndFormat (wdformatplaintext)
.display
.HTMLBody = .HTMLBody & signature
Set pageEditor = Nothing
Set xInspect = Nothing
End With
This works for me
Sub esendtable()
Dim rng As Range
Dim Outlook As Object
Dim newEmail As Object
Dim SigString As String
Dim Signature As String
Dim xInspect As Object
Dim pageEditor As Object
Set rng = Nothing
On Error Resume Next
' Only send the visible cells in the selection.
Set rng = ActiveSheet.Range("A3:F3")
' You can also use a range with the following statement.
Set rng = Sheets("YourSheet").Range("A3:F3").SpecialCells(xlCellTypeVisible)
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 Outlook = CreateObject("Outlook.Application")
Set newEmail = Outlook.CreateItem(0)
SigString = "C:\Users\chipz\AppData\Roaming\Microsoft\Signatures\chipz_1.htm" ' Change chipz in path and signature file name
If Dir(SigString) <> "" Then
Signature = GetBoiler(SigString)
Else
Signature = ""
End If
On Error Resume Next
With newEmail
.To = "recipient#test.com"
.CC = ""
.BCC = ""
.Subject = "Data - " & Date
.BodyFormat = olFormatHTML
.HTMLBody = RangetoHTML(rng) & "" & Signature
.Display
' In place of the following statement, you can use ".Display" to
' display the e-mail message.
'.Send
End With
On Error GoTo 0
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
Set newEmail = Nothing
Set Outlook = Nothing
Set newEmail = Nothing
Set Outlook = Nothing
End Sub
Function RangetoHTML(rng As Range)
' Ron de Bruin
'
Dim fso As Object
Dim ts As Object
Dim TempFile As String
Dim TempWB As Workbook
TempFile = Environ$("temp") & "\" & Format(Now, "dd-mm-yy h-mm-ss") & ".htm"
'Copy the range and create a new workbook to past the data in
rng.Copy
Set TempWB = Workbooks.Add(1)
With TempWB.Sheets(1)
.Cells(1).PasteSpecial Paste:=8
.Cells(1).PasteSpecial xlPasteValues, , False, False
.Cells(1).PasteSpecial xlPasteFormats, , False, False
.Cells(1).Select
Application.CutCopyMode = False
On Error Resume Next
.DrawingObjects.Visible = True
.DrawingObjects.Delete
On Error GoTo 0
End With
'Publish the sheet to a htm file
With TempWB.PublishObjects.Add( _
SourceType:=xlSourceRange, _
Filename:=TempFile, _
Sheet:=TempWB.Sheets(1).Name, _
Source:=TempWB.Sheets(1).UsedRange.Address, _
HtmlType:=xlHtmlStatic)
.Publish (True)
End With
'Read all data from the htm file into RangetoHTML
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.GetFile(TempFile).OpenAsTextStream(1, -2)
RangetoHTML = ts.readall
ts.Close
RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _
"align=left x:publishsource=")
'Close TempWB
TempWB.Close savechanges:=False
'Delete the htm file we used in this function
Kill TempFile
Set ts = Nothing
Set fso = Nothing
Set TempWB = Nothing
End Function
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
I am using this code to send an e-mail via VBA, but I need to send a table as a Body.
This code sends only a one cell not a range.
How can I paste Range("B5:D10") as a table in mail body?
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = Range("B1").Value
.Cc = Range("B2").Value
.Bcc = Range("B3").Value
.Subject = Range("B4").Value
.Body = Range("B5").Value
.Send
End With
On Error GoTo 0
Set OutMail = Nothing
You can achieve that by setting HTMLBody instead of Body. But then, to have control over formatting of a message, you have to have basic konwledge of HTML.
The idea behind it is as follows: you have to put range content together with HTML tags like this:
Dim rng As Range, cell As Range, HtmlContent As String, i As Long, j As Long
Set rng = Range("B5:D10")
HtmlContent = "<table>"
For i = 5 To rng.Rows.Count + 4
HtmlContent = HtmlContent & "<tr>"
For j = 2 To rng.Columns.Count + 2
HtmlContent = HtmlContent & "<td>" & Cells(i, j).Value & "</td>"
Next
HtmlContent = HtmlContent & "</tr>"
Next
HtmlContent = HtmlContent & "</table>"
Then, to put this table in a message:
With OutMail
'...
.HTMLBody = HtmlContent
'...
End With
You can try like this.
Sub test()
Dim rng As Range
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
Set rng = Selection.SpecialCells(xlCellTypeVisible)
Set rng = Sheets("Sheet1").Range("B5:D10").SpecialCells(xlCellTypeVisible)
On Error Resume Next
With OutMail
.To = Range("B1").Value
.Cc = Range("B2").Value
.Bcc = Range("B3").Value
.Subject = Range("B4").Value
.HTMLBody = RangetoHTML(rng)
.Display
End With
On Error GoTo 0
Set OutMail = Nothing
End Sub
Function RangetoHTML(rng As Range)
Dim fso As Object
Dim ts As Object
Dim TempFile As String
Dim TempWB As Workbook
TempFile = Environ$("temp") & "\" & Format(Now, "dd-mm-yy h-mm-ss") & ".htm"
rng.Copy
Set TempWB = Workbooks.Add(1)
With TempWB.Sheets(1)
.Cells(1).PasteSpecial Paste:=8
.Cells(1).PasteSpecial xlPasteValues, , False, False
.Cells(1).PasteSpecial xlPasteFormats, , False, False
.Cells(1).Select
Application.CutCopyMode = False
On Error Resume Next
.DrawingObjects.Visible = True
.DrawingObjects.Delete
On Error GoTo 0
End With
With TempWB.PublishObjects.Add( _
SourceType:=xlSourceRange, _
Filename:=TempFile, _
Sheet:=TempWB.Sheets(1).Name, _
Source:=TempWB.Sheets(1).UsedRange.Address, _
HtmlType:=xlHtmlStatic)
.Publish (True)
End With
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.GetFile(TempFile).OpenAsTextStream(1, -2)
RangetoHTML = ts.readall
ts.Close
RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _
"align=left x:publishsource=")
TempWB.Close SaveChanges:=False
Kill TempFile
Set ts = Nothing
Set fso = Nothing
Set TempWB = Nothing
End Function
You can't.
Thant body argument accept only Strings.
And there's another problem: formatting.
If I remember well I was in you situation and use something like this to produce html file from range.
Then I used TStream to take the ".html" file and put the result in the body.
Wrapping all this is in a pseudo:
Public Sub Email()
Dim olApp As Outlook.Application
Dim olMail As Outlook.MailItem
Dim FSObj As Scripting.FileSystemObject
Dim TStream As Scripting.TextStream
Dim rngeSend As Range
Dim strHTMLBody As String
'Select the range to be sent
Set rngeSend = Application.Range("B1:G35")
If rngeSend Is Nothing Then Exit Sub 'User pressed Cancel
On Error GoTo 0
'Now create the HTML file
ActiveWorkbook.PublishObjects.Add(xlSourceRange, "C:\sales\tempsht.htm", rngeSend.Parent.Name, rngeSend.Address, xlHtmlStatic).Publish True
'Create an instance of Outlook (or use existing instance if it already exists
Set olApp = CreateObject("Outlook.Application")
'Create a mail item
Set olMail = olApp.CreateItem(olMailItem)
'Open the HTML file using the FilesystemObject into a TextStream object
Set FSObj = New Scripting.FileSystemObject
Set TStream = FSObj.OpenTextFile("C:\sales\tempsht.htm", ForReading)
'Now set the HTMLBody property of the message to the text contained in the TextStream object
strHTMLBody = TStream.ReadAll
olMail.HTMLBody = strHTMLBody
olMail.To = "anybody#anywhere.com"
olMail.Subject = "Email Subject"
olMail.Send
Hope it helps!
The answer from saransh seems to be based on this solution by Ron de Bruin.
However, it has a flaw where cells that have text hidden by other cells will result in that text being cut off in the result.
This is because the html renders this text with style display:none.
A simple solution it to add a line when reading the html file.
After this line:
RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _
"align=left x:publishsource=")
add:
RangetoHTML = Replace(RangetoHTML, "display:none", "")
This will result in the hidden text be displayed and the table to autosize the columns.
You can use this function below so that it return a string of html:
extracttablehtml(thisworkbook.worksheets("whatever"), range("A1:B5"))
Afterwards, you do:
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = "anymail"
.Cc = ""
.Bcc = ""
.Subject = ""
.HTMLBody = extracttablehtml(thisworkbook.worksheets("whatever"), Range("A1:B5")) '<<<< Here it is
.Send
End With
On Error GoTo 0
Set OutMail = Nothing
public function:
Public Function extracttablehtml(ws As Worksheet, rng As Range) As String
Dim HtmlContent As String, i As Long, j As Long
On Error GoTo 0
HtmlContent = "<table>"
For i = 1 To rng.Rows.Count
HtmlContent = HtmlContent & "<tr>"
For j = 1 To rng.Columns.Count
HtmlContent = HtmlContent & "<td>" & ws.Cells(i, j).Value & "</td>"
Next
HtmlContent = HtmlContent & "</tr>"
Next
HtmlContent = HtmlContent & "</table>"
extracttablehtml = HtmlContent
Error_Handler_Exit:
On Error Resume Next
If Not rng Is Nothing Then Set OutMail = Nothing
Exit Function
Error_Handler:
If Alert = True Then
MsgBox "The following error has occurred" & vbCrLf & vbCrLf & _
"Error Number: " & Err.Number & vbCrLf & _
"Error Source: single_prop_write_mail_proposal" & vbCrLf & _
"Error Description: " & Err.Description & _
Switch(Erl = 0, "", Erl <> 0, vbCrLf & "Line No: " & Erl) _
, vbOKOnly + vbCritical, "An Error has Occurred!"
End If
Resume Error_Handler_Exit
End Function
I am new to VBA and have created the following code that sends an email.
My question is how do i copy some cells from my excel sheet that I am currently using to be pasted inside the excel file?
Thanks,
Sub CIR_Save_Email()
Dim objoutlook As Object
Set objoutlook = CreateObject("outlook.application")
Dim objemail As Object
Set objemail = objoutlook.createitem(olmailitem)
Const olFormatHTML As Long = 2
emailbodymessage = "<HTML><BODY>Hi Team," & _
"<br><br>Attached is the Display's CIR for today<br><br>" & _
"<b>Brief overview of CIR</b><br><br>" & _
"<b>Purpose:</b> To get a snapshot of what your current inventory levels by SKU are every day." & _
"<ul style=""list-style-type:circle"">" & _
"<li><b>Unrestricted QTY</b> The total inventory at that DC (i.e.Deliveries Created + Available Qty)</li>" & _
"<li><b>Deliveries Created:</b> Orders that are being processing at that DC (i.e. they will NOT be included in Available Inventory)</li>" & _
"<li><b>Available:</b> How many cases are available to use at that DC </li>" & _
"<li><b>Avail DOS:</b> How many DOS the available cases equate to</li>" & _
"<li><b>IT QTY:</b> How man cases are in transit</li>" & _
"<li><b>Avail +IT DOS:</b> How many DOS the available cases equate to</li>" & _
"</ul> </body> </html>"
emailbodymessage2 = "<html><body><ul style=""list-style-type:circle"">" & _
"<li><b>Future Available:</b> The total DOS of cases Avail + IT</li>" & _
"<li><b>QI QTY:</b> How many cases are on Qualitiy (ie Non-Conformance)</li>" & _
"<li><b>Blocked QTY:</b> How many cases are blocked from ordering due to damages, short dating, expired, etc." & _
"<li><b>CM- months:</b> The forecasts of the months past (CM-1=July)</li>" & _
"<li><b>% to Fcst:</b> How much of your projected forecast has shipped this month</li>" & _
"<li><b>Current SNAP Fcst:</b> This month's projected forecast</li>" & _
"<li><b>CM+ months:</b> The forecasts of the months moving forward (CM+1= September)</li>" & _
"</ul> </body></html>"
With objemail
.To = emaillist
.cc = ""
.Subject = "Display's CIR " & Date
.BodyFormat = olFormatHTML '// 2
.HTMLBody = emailbodymessage & emailbodymessage2
.display
End With
End Sub
You can use the following function (internally uses exporting range into HTML) to convert excel range into html. Then resultant HTML should be included into your generated HTML body.
The function is exporting Range into HTML temporary created file and then strips content to only div (without surrounding HTML tags).
However, I'm not sure if formatting and other details will fit your requirements. Other solution is to construct HTML from cells manually, but it is much more work.
Usage: str = GetHtml("Sheet1","D4:E6")
Public Function GetHtml(ByVal sheetName As String, ByVal rangeName As String) As String
Dim fso As FileSystemObject
Dim fileName As String
Dim txtStream As TextStream
Dim html As String
Dim line As String
Dim readLines As Boolean
Set fso = New FileSystemObject
Dim rng As range
fileName = fso.GetSpecialFolder(2) & "\" & Replace(fso.GetTempName, ".tmp", ".html")
If fso.FileExists(fileName) Then
fso.DeleteFile fileName
End If
Set rng = Sheets(sheetName).range(rangeName)
ActiveWorkbook.PublishObjects.Add(SourceType:=xlSourceRange, fileName:=fileName, Sheet:=rng.Worksheet.Name, Source:=rng.Address, HtmlType:=xlHtmlStatic).Publish
Set txtStream = fso.OpenTextFile(fileName, ForReading, False)
readLines = False
html = ""
Do While Not txtStream.AtEndOfStream
line = txtStream.ReadLine
If InStr(line, "<!--START OF OUTPUT FROM EXCEL PUBLISH AS WEB PAGE WIZARD") > 0 Then
readLines = True
End If
If readLines Then
html = html & vbCrLf & line
End If
If readLines And InStr(line, "<!--END OF OUTPUT FROM EXCEL PUBLISH AS WEB PAGE WIZARD") > 0 Then
readLines = False
End If
Loop
txtStream.Close
Set txtStream = Nothing
If fso.FileExists(fileName) Then
fso.DeleteFile fileName
End If
Set fso = Nothing
GetHtml = html
End Function
You said you want to 'copy some cells from my excel sheet that I am currently using to be pasted inside the excel file'. I think you man copy from Excel and paste into the body of an Email, right.
Sub Mail_Selection_Range_Outlook_Body()
'For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
'Don't forget to copy the function RangetoHTML in the module.
'Working in Excel 2000-2016
Dim rng As Range
Dim OutApp As Object
Dim OutMail As Object
Set rng = Nothing
On Error Resume Next
'Only the visible cells in the selection
Set rng = Selection.SpecialCells(xlCellTypeVisible)
'You can also use a fixed range if you want
'Set rng = Sheets("YourSheet").Range("D4:D12").SpecialCells(xlCellTypeVisible)
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 = "ron#debruin.nl"
.CC = ""
.BCC = ""
.Subject = "This is the Subject line"
.HTMLBody = RangetoHTML(rng)
.Send 'or use .Display
End With
On Error GoTo 0
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
Function RangetoHTML(rng As Range)
' Changed by Ron de Bruin 28-Oct-2006
' Working in Office 2000-2016
Dim fso As Object
Dim ts As Object
Dim TempFile As String
Dim TempWB As Workbook
TempFile = Environ$("temp") & "\" & Format(Now, "dd-mm-yy h-mm-ss") & ".htm"
'Copy the range and create a new workbook to past the data in
rng.Copy
Set TempWB = Workbooks.Add(1)
With TempWB.Sheets(1)
.Cells(1).PasteSpecial Paste:=8
.Cells(1).PasteSpecial xlPasteValues, , False, False
.Cells(1).PasteSpecial xlPasteFormats, , False, False
.Cells(1).Select
Application.CutCopyMode = False
On Error Resume Next
.DrawingObjects.Visible = True
.DrawingObjects.Delete
On Error GoTo 0
End With
'Publish the sheet to a htm file
With TempWB.PublishObjects.Add( _
SourceType:=xlSourceRange, _
Filename:=TempFile, _
Sheet:=TempWB.Sheets(1).Name, _
Source:=TempWB.Sheets(1).UsedRange.Address, _
HtmlType:=xlHtmlStatic)
.Publish (True)
End With
'Read all data from the htm file into RangetoHTML
Set fso = CreateObject("Scripting.FileSystemObject")
Set ts = fso.GetFile(TempFile).OpenAsTextStream(1, -2)
RangetoHTML = ts.readall
ts.Close
RangetoHTML = Replace(RangetoHTML, "align=center x:publishsource=", _
"align=left x:publishsource=")
'Close TempWB
TempWB.Close savechanges:=False
'Delete the htm file we used in this function
Kill TempFile
Set ts = Nothing
Set fso = Nothing
Set TempWB = Nothing
End Function
https://www.rondebruin.nl/win/s1/outlook/bmail2.htm
I use this code to send email from Excel:
Sub Mail_workbook_Outlook_1()
'Working in Excel 2000-2013
'This example send the last saved version of the Activeworkbook
'For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.to = "ron#debruin.nl"
.CC = ""
.BCC = ""
.Subject = "This is the Subject line"
.Body = "Hi there"
.Attachments.Add ActiveWorkbook.FullName
'You can add other files also like this
'.Attachments.Add ("C:\test.txt")
.Send ' <--------------------------------This is causing troubble
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
The problem is that .Send is not recognized as an object (or method).
Other commands are working (i.e. Display, Save).
I believe this error exists because of security systems at my work. I have even tried using CDO and it is not working ether.
Change .Send to .Display and put SendKeys "^{ENTER}" before the With OutMail line.
Try this code.
Sub Email_ActiveSheet_As_PDF()
'Do not forget to change the email ID
'before running this code
Dim OutApp As Object
Dim OutMail As Object
Dim TempFilePath As String
Dim TempFileName As String
Dim FileFullPath As String
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
' Temporary file path where pdf
' file will be saved before
' sending it in email by attaching it.
TempFilePath = Environ$("temp") & "\"
' Now append a date and time stamp
' in your pdf file name. Naming convention
' can be changed based on your requirement.
TempFileName = ActiveSheet.Name & "-" & Format(Now, "dd-mmm-yy h-mm-ss") & ".pdf"
'Complete path of the file where it is saved
FileFullPath = TempFilePath & TempFileName
'Now Export the Activesshet as PDF with the given File Name and path
On Error GoTo err
With ActiveSheet
.ExportAsFixedFormat _
Type:=xlTypePDF, _
Filename:=FileFullPath, _
Quality:=xlQualityStandard, _
IncludeDocProperties:=True, _
IgnorePrintAreas:=False, _
OpenAfterPublish:=False
End With
'Now open a new mail
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = StrToReceipent
.CC = StrCCReceipent
.BCC = StrBCCReceipent
.Subject = StrSubject
.Body = StrBody
.Attachments.Add FileFullPath '--- full path of the pdf where it is saved
.Send 'or use .Display to show you the email before sending it.
.Display
End With
On Error GoTo 0
'Since mail has been sent with the attachment
'Now delete the pdf file from the temp folder
Kill FileFullPath
'set nothing to the objects created
Set OutMail = Nothing
Set OutApp = Nothing
'Now set the application properties back to true
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
MsgBox ("Email has been Sent Successfully")
Exit Sub
err:
MsgBox err.Description
End Sub