I have a VBA code that is copying a range in Excel and pasting into the body of an Outlook email. The code works on several of my colleagues computers but not mine. The code gets as far as creating the .temp file, populating the To:, CC: and Subject but nothing appears in the body. I am trying to paste HTML. I am thinking it's a setting or something like that, but I'm not sure where to start. Any help on this would be greatly appreciated.
Sub CreateEmail()
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
datestr = Date
sbj = "***"
toStr = "****"
Ccstr = "*****"
Dim rng As Range
Set rng = Nothing
Set rng = Range("Flash")
On Error Resume Next
With OutMail
.To = toStr
.Display
.CC = Ccstr
.BCC = ""
.Subject = sbj & datestr
.HTMLBody = RangetoHTML(rng)
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
Function RangetoHTML(rng As Range)
Dim fso As Object
Dim ts As Object
Dim TempFile As String
Dim TempWB As Workbook
Application.ScreenUpdating = False
TempFile = Environ$("temp") & "/" & "temp" & ".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
Application.ScreenUpdating = True
End Function
I opted to used this method instead. This pastes a range of excel, but not the HTML version. I did not need to use HTML. This works just as good, but without colors and such.
Sub SendFlash()
Dim rng As Range
Dim OutApp As Object
Dim OutMail As Object
Set rng = Nothing
On Error Resume Next
Set rng = Range("K4:L8").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
toStr = "*"
Ccstr = "*"
sbj = "Tran"
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = toStr
.CC = Ccstr
.BCC = ""
.Subject = sbj & Date
.Body = TableRangeToTabDelim(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 TableRangeToTabDelim(TableRange As Range) As String
Dim TableCols As Integer
Dim TableRows As Integer
Dim ReturnString As String
TableCols = TableRange.Columns.Count
TableRows = TableRange.Rows.Count
i = 1
j = 1
Do While i <= TableRows
Do While j <= TableCols
ReturnString = ReturnString & TableRange.Cells(i, j).Value
If j <> TableCols Then
ReturnString = ReturnString & Chr(9)
End If
j = j + 1
Loop
j = 1
If i <> TableRows Then
ReturnString = ReturnString & Chr(10)
End If
i = i + 1
Loop
TableRangeToTabDelim = ReturnString
End Function
Related
A group of teachers (I am one) is using a spreadsheet to track missing assignments of students. The students' names are in column A, and missing assignments expand in columns to the right.
When an assignment is missing, the teacher puts their initial in the cell and right-clicks to add a comment about the assignment.
When the student submits the assignment, the teacher changes the cell's fill from nothing (xlNone) to yellow or grey.
We'd like Excel to send us a daily email that lists only the students with missing assignments in cells filled with xlNone along with the initial of the teacher or teachers.
This code does not error. The email object is constructed, but there is no data in the body of the email.
Sub Mail_Selection_Range_Outlook_Body()
'Thanks to code by Tim Williams and Ron de Bruin
Dim rng As Range
Dim OutApp As Object
Dim OutMail As Object
On Error Resume Next
Dim cell As Range
Dim ci As Long
Set rng = Nothing
For Each cell In Sheet1.Range("C4:Z100").Cells
ci = cell.Interior.ColorIndex
If (ci = -4142 Or ci = 2 Or ci = 15 Or ci = 16) And Not IsNumeric(cell.Value) Then
If rng Is Nothing Then
Set rng = cell
Else
Set rng = Application.Union(rng, cell)
End If
End If
Next cell
If Not rng Is Nothing Then rng.Select
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = "teacher1#school.org, teacher2#school.org"
.CC = ""
.BCC = ""
.Subject = "This is the list of students with missing work"
.HTMLBody = RangetoHTML(rng)
.Send
End With
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
Function RangetoHTML(rng As Range)
' Thanks to Ron de Bruin's page
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 paste 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
I commented On Error Resume Next out as suggested and get an error
'Type Mismatch'
Looking at the sheet, the various cells are highlighted.
Hello middleschoolteacher,
UPDATED ANSWER
Sub Mail_Selection_Range_Outlook_Body()
'Thanks to code by Tim Williams and Ron de Bruin
' Dim rng As Range
Dim OutApp As Object
Dim OutMail As Object
' On Error Resume Next
Dim cell As Range
Dim ci As Long
' Set rng = Nothing
Dim str As String
str = Empty
For Each cell In Sheet1.Range("C4:Z100").Cells
ci = cell.Interior.ColorIndex
If (ci = -4142 Or ci = 2 Or ci = 15 Or ci = 16) And Not IsNumeric(cell.value) Then
'****************************************************************************
' If rng Is Nothing Then
' Set rng = cell
' Else
' Set rng = Application.Union(rng, cell)
' End If
str = str & CStr(cell.value) & " "
'****************************************************************************
End If
Next cell
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
' On Error Resume Next
With OutMail
.To = "teacher1#school.org, teacher2#school.org"
.CC = ""
.BCC = ""
.Subject = "This is the list of students with missing work"
'****************************************************************************
Dim wdDoc As Object
Dim olinsp As Object
Set wdDoc = CreateObject("Word.Document")
Set olinsp = .GetInspector
Set wdDoc = olinsp.WordEditor
If Not IsEmpty(str) Then
wdDoc.Range.InsertBefore str
.Display
.Send
Else
MsgBox prompt:="No cells meet the criteria"
Exit Sub
End If
'****************************************************************************
End With
Set OutMail = Nothing
Set OutApp = Nothing
Set wdDoc = Nothing
Set olinsp = Nothing
End Sub
So, I'm not sure this gives you the intended result, however after testing with a test worksheet I successfully displayed the email with all the relevant cell values separated by a space (you can choose whatever you want to separate the values, you just need to replace the " " on the line containing str = str & CStr(cell.value) & " " .
I changed where the .Send method is on the code so that no email is sent if there are no relevant cells.
I fail to understand how are you going to know which student hasn't yet submitted the assignment as the relevant cells contain only the initial of the teacher? Or am I getting this wrong?
If you need to include the student's name also for each cell value then the code can be easily modified to do that, however I'm not sure that I fully understand what is the desired output is here.
Anyways let me know how it goes.
ADDITION
You can output a single line like this: studentA_J studentB_F studentC_W , J F and W being the initials of the teachers. In order to achieve that you need only the the line containing str = str & CStr(cell.value) & " " and change it to str = str & Sheet1.Cells(cell.row,j) & "_" & CStr(cell.value) & " " , where j needs to be the index of the column where the student's name is.
If I remember correctly you can even write it using the letter of the column, for example if the students names are in column A then you can also replace the above line of code also by str = str & Sheet1.Cells(cell.row,"A") & "_" & CStr(cell.value) & " "
UPGRADED CODE
Sub Mail_Selection_Range_Outlook_Body()
'Thanks to code by Tim Williams and Ron de Bruin
Dim OutApp As Object
Dim OutMail As Object
Dim cell As Range, studentCell As Range
Dim ci As Long
Dim str As String
str = Empty
With Application
.calculation = xlCalculationManual
.DisplayStatusBar = False
.enableEvents = False
.screenUpdating = False
.Interactive = False
.DisplayAlerts = False
.AskToUpdateLinks = False
End With
For Each cell In Sheet1.Range("C4:Z100").Cells
ci = cell.Interior.ColorIndex
If (ci = -4142 Or ci = 2 Or ci = 15 Or ci = 16) And Not IsNumeric(cell.value) Then
'****************************************************************************
Set studentCell = Sheet1.Cells(cell.Row, "A")
With cell
If Not .CommentThreaded Is Nothing Then
str = str & studentCell.value & "_" & CStr(.value) & "_" & .CommentThreaded.Text & vbCrLf
Else
str = str & studentCell.value & "_" & CStr(.value) & vbCrLf
End If
End With
'****************************************************************************
End If
Next cell
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With OutMail
.To = "teacher1#school.org, teacher2#school.org"
.CC = ""
.BCC = ""
.Subject = "This is the list of students with missing work"
'****************************************************************************
Dim wdDoc As Object
Dim olinsp As Object
Set wdDoc = CreateObject("Word.Document")
Set olinsp = .GetInspector
Set wdDoc = olinsp.WordEditor
If Not IsEmpty(str) Then
wdDoc.Range.InsertBefore str
Else
MsgBox prompt:="No cells meet the criteria"
GoTo SafeExit
End If
'****************************************************************************
.Display
.Send
End With
SafeExit:
With Application
.calculation = xlCalculationAutomatic
.DisplayStatusBar = False
.enableEvents = False
.screenUpdating = False
.Interactive = False
.DisplayAlerts = False
.AskToUpdateLinks = False
End With
Set OutMail = Nothing
Set OutApp = Nothing
Set wdDoc = Nothing
Set olinsp = Nothing
End Sub
If you use this upgraded code then it will run much faster.
I want to send template emails based on selections in an Excel worksheet.
I want to choose which email template and subject line from a dropdown selection in the worksheet. If empty, I want to skip.
The range with the dropdown options.
Dim cellrange As Range, cell As Range
Set cellrange = Range("H3:H500")
I use PowerShell and other scripting languages regularly. My VBA exposure is limited.
I created variables for the different email templates and the subject lines. I also found code that will send the emails. That part seems ok.
I receive one email instead of looping through however many emails based on the selections in the sheet.
I set the email templates and subject line in a range in a different sheet and created variables for them.
Set delivery = Sheets("EmailTemplates").Range("A5:A40")
Set address = Sheets("EmailTemplates").Range("A50:A90")
Set deliverysub = Sheets("EmailTemplates").Range("B2")
Set addresssub = Sheets("EmailTemplates").Range("B50")
I will also create this for the Meeting template and subject line. I've been trying to get it to work with these two first and getting varied results.
Sub Mail_Selection_Range_Outlook_Body()
Dim rng As Range
Dim OutApp As Object
Dim OutMail As Object
Dim delivery As Range
Dim shipping As Range
Dim meeting As Range
Dim address As Range
Dim deliverysub As Range
Dim shippingsub As Range
Dim meetingsub As Range
Dim addresssub As Range
Dim template As Range
Set delivery = Sheets("EmailTemplates").Range("A5:A40")
Set address = Sheets("EmailTemplates").Range("A50:A90")
Set deliverysub = Sheets("EmailTemplates").Range("B2")
Set addresssub = Sheets("EmailTemplates").Range("B50")
Set rng = Nothing
On Error Resume Next
Dim cellrange As Range, cell As Range
Set cellrange = Range("H3:H500")
For Each cell In cellrange
If cell.Value = "" Then
Next cell
ElseIf cell.Value = "Delivery" Then
Set rng = delivery
Set SubjectLine = deliverysub
ElseIf cell.Value = "Shipping" Then
Set rng = address
Set SubjectLine = addresssub
ElseIf cell.Value = "Meeting" Then
Set rng = meeting
Set SubjectLine = meetingsub
End If
Next cell
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 = "myemail#email.com"
.CC = ""
.BCC = ""
.Subject = SubjectLine
.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)
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 rng = Nothing
Set ts = Nothing
Set fso = Nothing
Set TempWB = Nothing
End Function
End Sub
More like this:
Sub Mail_Selection_Range_Outlook_Body()
Dim rng As Range
Dim OutApp As Object
Dim OutMail As Object
Dim ws As Worksheet, wsTemplates As Worksheet
Dim cell As Range, subj As String
Set ws = ActiveSheet
Set wsTemplates = ThisWorkbook.Worksheets("EmailTemplates")
Set OutApp = CreateObject("Outlook.Application")
For Each cell In ws.Range("H3:H500").Cells
'What type of template are we using?
Select Case cell.Value
Case "Delivery"
Set rng = wsTemplates.Range("A5:A40")
subj = wsTemplates.Range("B2")
Case "Shipping"
Set rng = wsTemplates.Range("A50:A90")
subj = wsTemplates.Range("B50")
Case "Meeting"
'etc etc
Case Else
Set rng = Nothing 'not sending anything
End Select
If Not rng Is Nothing Then 'sending?
Set OutMail = OutApp.CreateItem(0)
With OutMail
.To = "myemail#email.com"
.CC = ""
.BCC = ""
.Subject = subj
.HTMLBody = RangetoHTML(rng)
.SEND 'or use .Display
End With
End If
Next cell
End Sub
So currently my code works almost to what I like it too.
It currently groups the same emails together and emails that range to the person.
But in the email I'm trying to not include column A which is their email.
For Each cell In WS.Columns("A").Cells.SpecialCells(xlCellTypeConstants)
If cell.Value Like "?*#?*.?*" Then
'check if this email address has been used to generate an outlook email or not
If dict.exists(cell.Value) = False Then
dict.Add cell.Value, "" 'add the new email address
Set OutMail = OutApp.CreateItem(0)
Set rng = WS.UsedRange.Rows(1)
'find all of the rows with the same email and add it to the range
For Each cell2 In WS.UsedRange.Columns(1).Cells
If cell2.Value = cell.Value Then
Set rng = Application.Union(rng, WS.UsedRange.Rows(cell2.Row))
End If
Next cell2
I tried modifying the above code but can't seem to work it out.. Can anyone help me out?
full code:
Option Explicit
Sub Test1()
Dim OutApp As Object
Dim OutMail As Object
Dim dict As Object 'keep the unique list of emails
Dim cell As Range
Dim cell2 As Range
Dim rng As Range
Dim i As Long
Dim WS As Worksheet
Dim Signature As String
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
Set dict = CreateObject("scripting.dictionary")
Set WS = ThisWorkbook.Sheets("Sheet1") 'Current worksheet name
On Error GoTo cleanup
For Each cell In WS.Columns("A").Cells.SpecialCells(xlCellTypeConstants)
If cell.Value Like "?*#?*.?*" Then
'check if this email address has been used to generate an outlook email or not
If dict.exists(cell.Value) = False Then
dict.Add cell.Value, "" 'add the new email address
Set OutMail = OutApp.CreateItem(0)
Set rng = WS.UsedRange.Rows(1)
'find all of the rows with the same email and add it to the range
For Each cell2 In WS.UsedRange.Columns(1).Cells
If cell2.Value = cell.Value Then
Set rng = Application.Union(rng, WS.UsedRange.Rows(cell2.Row))
End If
Next cell2
On Error Resume Next
With OutMail
.SentOnBehalfOfName = ""
.GetInspector ' ## This inserts default signature
Signature = .HTMLBody ' ## Capture the signature HTML
.To = cell.Value
.CC = ""
.Subject = "Reminder"
.HTMLBody = "<BODY style=font-size:12pt;font-family:Calibri><font color=#000000>Hi " & WorksheetFunction.Proper(RemoveNumbers(Left((cell.Value), InStr((cell.Value), ".") - 1))) & ", " & "<br><br>" & "Please see your trip numbers and estimated cost below:" & vbNewLine & vbNewLine & RangetoHTML(rng) & Signature & "</font></BODY>"
.Display
End With
On Error GoTo 0
Set OutMail = Nothing
End If
End If
Next cell
cleanup:
Set OutApp = Nothing
Application.ScreenUpdating = True
End Sub
Function RemoveNumbers(Txt As String) As String
With CreateObject("VBScript.RegExp")
.Global = True
.Pattern = "[0-9]"
RemoveNumbers = .Replace(Txt, "")
End With
End Function
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"
'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
One option is to use Intersect and Resize.
After the loop that creates rng but before passing rng to RangetoHTML:
With WS.UsedRange
Set rng = Intersect(rng, .Columns(2).Resize(,.Columns.Count - 1))
End With
I have to send an email that includes a table, in the body, that was copied from a filter table.
The filter table's name is "ds" in this code.
I use function RangetoHTML (code below) but it only copies the format, not the contents of the table:
Sub Email_Syndicate()
Dim OutApp As Object
Dim OutMail As Object
Dim EmailSubject As String
Dim EmailSendTo As String
Dim MailBody As String
Dim cell As Range
Dim Signature As String
Dim ds As Range
Set rng = Range(Range("B2"), Range("B" & Rows.Count).End(xlUp))
For Each cell In rng
rw = cell.Row
If cell.Value <> "" Then
EmailSendTo = cell.Value
Nme = cell.Offset(0, 3).SpecialCells(xlCellTypeVisible)
xCC = cell.Offset(0, 1)
att = cell.Offset(0, 4).Value
EmailSubject = cell.Offset(0, 2)
lr1 = Sheet3.Cells(Rows.Count, 1).End(xlUp).Row
Sheet3.Range("A1:N" & lr1).AutoFilter field:=6, Criteria1:=Sheet4.Range("F2").Value
lr = Sheet3.Cells(Sheet3.Rows.Count, 1).End(xlUp).Row
Set ds = Sheet3.Range("A1:N" & lr).SpecialCells(xlCellTypeVisible)
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(o)
With OutMail
.Display
End With
Signature = OutMail.HTMLBody
'On Error Resume Next
With OutMail
.Subject = EmailSubject
.To = EmailSendTo
.CC = xCC
'.Body = MailBody
.HTMLBody = RangetoHTML(ds)
.Display
.send
End With
Set OutMail = Nothing
Set OutApp = Nothing
MailBody = ""
End If
With Application
.EnableEvents = 1
.Calculation = xlCalculationAutomatic
End With
Set OutMail = Nothing: Set OutApp = Nothing
Next
End Sub
Function RangetoHTML(rng As Range)
Dim fso As Object, ts As Object, TempWB As Workbook, TempFile As String
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:=xlPasteAll
.Cells(1).PasteSpecial xlPasteValues, , False, False
.Cells(1).PasteSpecial xlPasteColumnWidths, , False, False
.Cells(1).PasteSpecial xlPasteFormats, , False, False
.Cells(1).Select
Application.CutCopyMode = False
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 0
Kill TempFile
Set ts = Nothing: Set fso = Nothing: Set TempWB = Nothing
End Function
How can I copy a filter table containing full content to the email body?
Sub SendEmail_1()
Dim outlook As Object
Dim newEmail As Object
Dim xInp As Object
Dim pgEdit As Object
Dim pos As Integer
Set outlook = CreateObject("Outlook.Application")
Set newEmail= outlook.Createitem(o)
'construction email
With newEmail
.Recipients.Add ("person#email.com")
.Subject = "Subject goes here"
Set xInp = newEmail.GetInspector 'gets you into the test editor
Set pgEdit = xInp.WordEditor 'returns a word document object you can edit
'selects data we want to copy into email
Sheets("your Sheet").Range("your Range").Copy
'pastes the excel range over the indicator
pgEdit.Range(Start:=0, End:=1).PasteSpecial Placement:=wdInLine
Application.CutCopyMode = True
.display
.send
End With
End Sub
This is the sample email which is saved in Excel worksheet.
Hi All,
This is the test email
Regards,
Xyz
I want to copy this email as it is & paste it to Outlook.
With the help of online forums I have written a code but the output is not the same as the input.
Global Email_Subject, Email_Send_From, Email_Send_To, _
Email_Cc, Email_Bcc, Email_Body As String
Global Mail_Object, Mail_Single As Variant
Global wb As Workbook
Sub India_BB()
Dim i As Integer
Dim ShtToSend As Worksheet
Dim strSendTo, strbody As String
Dim strSheetName As String
Dim strSubject As String
Dim rng As Range
Set Mail_Object = CreateObject("Outlook.Application")
Set Mail_Single = Mail_Object.CreateItem(0)
For i = 1 To ThisWorkbook.Sheets.Count
If Sheets(i).Name = "India_BB" Then
Sheets(i).Select
Set rng = Nothing
strSheetName = Sheets(i).Name
strSendTo = Sheet1.Range("A1").Text
strSubject = Sheet1.Range("B1").Text
Set rng = Sheets(strSheetName).Range("body").SpecialCells(xlCellTypeVisible)
With Mail_Single
.To = strSendTo
.CC = ""
.BCC = ""
.Subject = strSubject
.HTMLBody = RangetoHTML(rng)
.Display
End With
End If
Next i
End Sub
Function RangetoHTML(rng As Range)
' By 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 xlPasteAll, , 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
Below is the Output I am getting with above code.
Link for excel file : https://drive.google.com/open?id=0Byy709uTvWRoTnRYaVJQNWNNR1E
Use GetInspector.WordEditor
See Example...
Sub India_BB()
Dim i As Integer
Dim ShtToSend As Worksheet
Dim strSendTo, strbody As String
Dim strSheetName As String
Dim strSubject As String
Dim rng As Range
' add ref - tool -> references - > Microsoft Word XX.X Object Library
Dim wdDoc As Word.Document '<=========
Set Mail_Object = CreateObject("Outlook.Application")
Set Mail_Single = Mail_Object.CreateItem(0)
Set wdDoc = Mail_Single.GetInspector.WordEditor '<========
For i = 1 To ThisWorkbook.Sheets.Count
If Sheets(i).Name = "India_BB" Then
Sheets(i).Select
Set rng = Nothing
strSheetName = Sheets(i).Name
strSendTo = Sheet1.Range("A1").Text
strSubject = Sheet1.Range("B1").Text
Set rng = Sheets(strSheetName).Range("body").SpecialCells(xlCellTypeVisible)
rng.Copy
With Mail_Single
.To = strSendTo
.CC = ""
.BCC = ""
.Subject = strSubject
' .HTMLBody = RangetoHTML(rng)
.Display
wdDoc.Range.PasteAndFormat wdChartPicture & .HTMLBody = " " '<=======
End With
End If
Next i
End Sub