Error when selected cell range to paste is hidden - excel

I've code to paste specified ranges in different sheets into Outlook email.
I've separate code to hide cells. I only want to paste if there is data in the table.
When the last row of the specific range is hidden, the code fails. If I leave the last row unhidden, it will result in empty rows in the email.
How do I run the code even if the last row within the range is hidden?
Sub Trigger_Email()
'add rng as you add tabs. Remember to add rng under (i) Set rng and also
(ii) With OutMail
Dim rng As Range 'For TAB01 Tab
Dim rng2 As Range 'For TAB02 Tab
Dim rng3 As Range 'For TAB03 Tab
Dim rng4 As Range 'For TAB04 Tab
Dim rng5 As Range 'For TAB05 Tab
Dim OutApp As Object
Dim OutMail As Object
Dim StrBody As String
'Shows what appears at top of email
StrBody = "Hi XXX," & "<br>" & "<br>" & _
"The company provides" & "<br>" & "<br>" & _
"For your consideration& views." & "<br>" & "<br>"
Set rng = Nothing
On Error Resume Next
'This determines range to be printed into email.
'ADD rng(n+1) hear if you increase cover type. Determine range here as well.
Set rng =
Sheets("TAB01").Range("A5:G22").Rows.SpecialCells(xlCellTypeVisible)
Set rng2 =
Sheets("TAB02").Range("A1:F39").Rows.SpecialCells(xlCellTypeVisible)
Set rng3 =
Sheets("TAB03").Range("A1:F50").Rows.SpecialCells(xlCellTypeVisible)
Set rng4 =
Sheets("TAB04").Range("A1:F50").Rows.SpecialCells(xlCellTypeVisible)
Set rng5 =
Sheets("TAB05").Range("A1:F50").Rows.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
'add more rng tabs below to display in body of email.
With OutMail
.To = "TEST#HOTMAIL.COM"
.CC = ""
.BCC = ""
.Subject = "TEST 01" & Cells(5, 1)
.HTMLBody = StrBody & rangetoHTML(rng) & rangetoHTML(rng3) &
rangetoHTML(rng4) & rangetoHTML(rng5) & rangetoHTML(rng2)
.Display
End With
On Error GoTo 0
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
'Ignore this section. It prints excel format into HTML format in email.
Function rangetoHTML(rng As Range)
Dim fso As Object
Dim ts As Object
Dim TempFile As String
Dim TemTAB05B 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 TemTAB05B = Workbooks.Add(1)
With TemTAB05B.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 TemTAB05B.PublishObjects.Add( _
SourceType:=xlSourceRange, _
Filename:=TempFile, _
Sheet:=TemTAB05B.Sheets(1).Name, _
Source:=TemTAB05B.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 TemTAB05B
TemTAB05B.Close savechanges:=False
'Delete the htm file we used in this function
Kill TempFile
Set ts = Nothing
Set fso = Nothing
Set TemTAB05B = Nothing
End Function

Related

Email table range to same addresses

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

RangeToHTML & Image in Cell

Im trying to generate an email using Ron de Bruin's RangeToHTML and its working perfectly so far however one of my cells ("B26") contains an image and this wont copy into the email.
I've tried and succeded in adding in the image before or after the range but I need this image to appear in this specific cell. Any Ideas how I can get this to work if its at all possible?
Sub SendEmail()
Dim OutlookApp As Outlook.Application
Dim MItem As Outlook.MailItem
Dim cell As Range
Dim Subj As String
Dim EmailAddr As String
Dim Recipient As String
Dim rng As Range
Dim rng2 As Range
Dim StrBody As String
Set rng = Sheets("Email Templates").Range("A1:D29")
'Set rng2 = Sheets("Email Templates").Range("A6:D32").SpecialCells(xlCellTypeVisible)
'Create Outlook object
Set OutlookApp = New Outlook.Application
'Operations Contacts
For Each cell In Sheets("Contacts").Columns("A").Cells.SpecialCells(xlCellTypeVisible)
If cell.Value Like "*#*" Then
EmailAddr = EmailAddr & ";" & cell.Value
End If
Next
'Systems Contacts
For Each cell In Sheets("Contacts").Columns("B").Cells.SpecialCells(xlCellTypeVisible)
If cell.Value Like "*#*" Then
EmailAddr = EmailAddr & ";" & cell.Value
End If
Next
Subj = "Systems Notification | System Outage | " & Sheets("Email Templates").Range("C6") & " " & Sheets("Email Templates").Range("C4") & " " & Sheets("Email Templates").Range("C6")
'Create Mail Item and view before sending
Set MItem = OutlookApp.CreateItem(olMailItem)
With MItem
.To = EmailAddr
.Subject = Subj
.HTMLBody = RangetoHTML(rng)
.Display
End With
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
Dim r As Long
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).PasteSpecial xlPasteAllUsingSourceTheme, , False, False
.Cells(1).Select
Application.CutCopyMode = False
On Error Resume Next
.DrawingObjects.Visible = True
.DrawingObjects.Delete
On Error GoTo 0
For r = 1 To rng.Rows.Count
.Rows(r).RowHeight = rng.Rows(r).RowHeight
Next r
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=")
RangetoHTML = Replace(RangetoHTML, "<!--[if !excel]> <![endif]-->", "")
'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
You can achieve it by taking a screenshot(using VBA Code) of the relevant range (Has to be visible in the screen) and then save and import that image in Outlook..
This will get you started. I have added the comments so you should not have a problem understanding it. If you still do then simply ask.
Option Explicit
Sub SaveRngAsImage()
Dim flName As String
Dim ws As Worksheet
Dim shp As Shape
Dim objChart As ChartObject
Dim chrt As Chart
Set ws = ActiveSheet
'~~> Change as applicable
flName = "C:\Users\routs\Desktop\MyRng.jpg"
'~~> Delete the above image
If Dir(flName) <> "" Then Kill flName
'~~> Check if what the user selected is a valid range
If TypeName(Selection) <> "Range" Then
MsgBox "Select a range first."
Exit Sub
End If
'~~> Take a screenshot of the range
Selection.CopyPicture xlScreen, xlBitmap
DoEvents
'~~> Paste the screenshot in the worksheet and assign it to
'~~> a shape object so that we can use it's approx width and
'~~> Height to create the chart object
With ws
.Paste
DoEvents
Set shp = .Shapes(.Shapes.Count)
Set objChart = ActiveSheet.ChartObjects.Add(0, 0, shp.Width, shp.Height)
Set chrt = objChart.Chart
With chrt
shp.Copy '~~> Copy the shape (in case the clipboard is cleared)
.ChartArea.Select
.Paste
'~~> Save the image
.Export ("C:\Users\routs\Desktop\MyRng.jpg")
End With
shp.Delete
objChart.Delete
End With
'~~> Attaching the above image to outlook email body
'https://stackoverflow.com/questions/44869790/embed-picture-in-outlook-mail-body-excel-vba
Dim OutApp As Object
Dim OutMail As Object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With OutMail
.To = "SomeEmail#SomeServer.com"
.Subject = "Attaching an image"
.Attachments.Add flName, 1, 0
.HtmlBody = "<html><p>Dear XYZ</p>" & _
"<img src=""cid:MyRng.jpg"">"
.Display
End With
End Sub
Screenshot

Using VBA in Excel, how to I paste a Table in Outlook then convert the table to text?

I'm currently trying to write a VBA function that will copy a range in Excel and paste it into an Outlook email. I have something created that can successfully copy the table and formatting into Outlook, but the problem is the tables are very hard to read on a phone. I'd like to simply use the outlook "ConvertToText" to change the table into text formatting so it'll be easier to read. I can't figure out a way to do that, though. My code is as follows, using a function and a sub:
Sub Mail_Selection_Range_Outlook_Body()
Dim rng As Range
Dim OutApp As Object
Dim OutMail As Object
Dim SDest As String
Dim i As Integer
Set rng = Nothing
On Error Resume Next
'You can also use a fixed range if you want
Set rng = Sheets("Email").Range("A2:Q400").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
SDest = ""
For i = 1 To WorksheetFunction.CountA(Sheets("Email List").Columns(1))
If SDest = "" Then
SDest = Sheets("Email List").Cells(i, 1).Value
Else
SDest = SDest & ";" & Sheets("Email List").Cells(i, 1).Value
End If
Next i
.To = SDest
.CC = ""
.BCC = ""
.Subject = "Frontside Update"
.HTMLBody = RangetoHTML(rng)
.Display 'or use .Send
End With
On Error GoTo 0
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
a
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
Any help would be greatly appreciated. I'm not sure if I've gone about it wrong and need to start over? Originally I was hoping an HTML table would work well, but later realized it looks terrible on phones (which many of the recipients use) and don't know the best solution.
If you want plain text, then maybe try this: Copy the range to an array. Loop through the array and assemble a string, adding tabs between cell values and returns between rows. (You could also loop through cells on the worksheet, but macros run fast with arrays.)
Dim arrCells(), r, c, strBody
arrCells = Selection
For r = LBound(arrCells, 1) To UBound(arrCells, 1)
For c = LBound(arrCells, 2) To UBound(arrCells, 2)
strBody = strBody & vbTab & arrCells(r, c).Value
Next c
strBody = strBody & vbCrLf
Next r

Populating recipient name in Outlook email

I created a vb macro to send emails to listed people in an excel file with their corresponding data table.
Everything is working fine just one problem! After many efforts I could not get/ write a code to get Name of the recipient after Hello in strbody.
Here is the sample file Click here
Link to RangetoHTML function Click here (it needs to be pasted after end sub in below code)
Below is has been fixed and working now. refer to the sample filefor column arrangement
Sub Credit_Auto()
Dim test1 As Long, test2 As Long
test1 = Timer
Application.ScreenUpdating = False
'This code populates emails to outlook as per the Credit analysts.
Dim OutApp As Object
Dim OutMail As Object
Dim rng As Range
Dim Ash As Worksheet
Dim Cws As Worksheet
Dim Rcount As Long
Dim Rnum As Long
Dim FilterRange As Range
Dim FieldNum As Integer
Dim SigString As String
Dim Signature As String
Dim name_rg As Range
Dim name As String
Set OutApp = CreateObject("Outlook.Application")
'You may want to change the signature file path below to get your signature properly
'C:\Users\<UserName>\AppData\Roaming\Microsoft\Signatures
SigString = Environ("appdata") & _
"\Microsoft\Signatures\Pratik Kumar2.htm"
If Dir(SigString) <> "" Then
Signature = GetBoiler(SigString)
Else
Signature = ""
End If
On Error Resume Next
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
'Set filter sheet, you can also use Sheets("MySheet")
Set Ash = ActiveSheet
'Set filter range and filter column (column with e-mail addresses)
Set FilterRange = Ash.Range("A1:G" & Ash.Rows.Count)
FieldNum = 7
'Add a worksheet for the unique list and copy the unique list in A1
Set Cws = Worksheets.Add
FilterRange.Columns(FieldNum).AdvancedFilter _
Action:=xlFilterCopy, _
CopyToRange:=Cws.Range("A1"), _
CriteriaRange:="", Unique:=True
'Count of the unique values + the header cell
Rcount = Application.WorksheetFunction.CountA(Cws.Columns(1))
'If there are unique values start the loop
If Rcount >= 2 Then
For Rnum = 2 To Rcount
'Filter the FilterRange on the FieldNum column
FilterRange.AutoFilter Field:=FieldNum, _
Criteria1:=Cws.Cells(Rnum, 1).Value
'If the unique value is a mail address create a mail
If Cws.Cells(Rnum, 1).Value Like "?*#?*.?*" Then
With Ash.AutoFilter.Range
On Error Resume Next
Set rng = .SpecialCells(xlCellTypeVisible)
On Error GoTo 0
End With
Set OutMail = OutApp.CreateItem(0)
'Search email address from Cws into Ash ~
Set name_rg = Ash.Columns(7).Find(Cws.Cells(Rnum, 1))
If Not name_rg Is Nothing Then
'input the row index of <name_rg>
'returns the name from col 6 ~
name = Ash.Cells(name_rg.Row, 6)
Else
name = "email not found in Ash"
End If
Set name_rg = Nothing
strbody = "Hello " & name & "," & "<br>" & "<br>" & _
"Please allocate the below account(s) to it's appropriate parent account." & "<br>"
On Error GoTo Cleanup
On Error Resume Next
With OutMail
.to = Cws.Cells(Rnum, 1).Value
.Subject = "Unallocated Credit Account"
.HTMLBody = strbody & RangetoHTML(rng) & "<br>" & Signature
.Send
End With
Set Ws = Nothing
On Error GoTo 0
Set OutMail = Nothing
End If
'Close AutoFilter
Ash.AutoFilterMode = False
Next Rnum
End If
Cleanup:
Set OutApp = Nothing
Application.DisplayAlerts = False
Cws.Delete
Application.DisplayAlerts = True
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
test2 = Timer
MsgBox "All the Credit Analysts have been notified and the entire process took " & Format((test2 - test1) / 86400, "hh:mm:ss") & " Seconds."
End Sub
Function RangetoHTML(rng As Range)
' Changed by Ron de Bruin 28-Oct-2006
' Working in Office 2000-2010
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
Columns("E:G").Select
Selection.Delete Shift:=xlToLeft
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
You could use the Range.Find Method.
Returns a Range object that represents the first cell where that information
is found. https://msdn.microsoft.com/en-us/vba/excel-vba/articles/range-find-method-excel
In your case this code below should do the trick .
Then you could do a loop though all the recipients emails
dim name_rg as range
dim name as string
{...}
' ~ Search email address from Cws into Ash ~
set name_rg = Ash.columns(7).Find(Cws.Cells(Rnum, 1))
If Not name_rg Is Nothing then
' ~ input the row index of <name_rg>
' returns the name from col 6 ~
name = Ash.cells(name_rg.row, 6)
Else
name = "email not found in Ash"
End If
{...}
set name_rg = Nothing

Excel macro to populate table in the email body

I am a beginner in coding and trying to create a macro to send emails to the credit analysts in my team. I am using a sample Excel sheet for the data.
How do I add a 4x2 table in the email body for each credit analyst listed in the sample data? Below is a very basic code which I could create after spending hours.
Sub Credit_Auto()
Dim objOutlook As Object
Dim objMail As Object
Dim Ws As Worksheet
Dim strbody As String
Set objOutlook = CreateObject("Outlook.Application")
Set Ws = ActiveSheet
Dim rCell As Range
For Each rCell In Ws.Range("G2", Ws.Range("G1000").End(xlUp))
Debug.Print rCell.Address
Set objMail = objOutlook.CreateItem(0)
strbody = "Dear " & rCell.Offset(0, -1).Value & "," & "<br>" & "<br>" & _
"Please allocate the below account to it's appropriate parent account." & "<br>" & "<br>" & _
"Regards" & "<br>" & "<br>" & _
"Ankit"
With objMail
.To = rCell.Value
.Subject = "Unalloctaed Credit Profiles"
.HTMLBody = strbody
.Send
End With
Next rCell
Set objMail = Nothing
Set Ws = Nothing
Set objOutlook = Nothing
End Sub
I need the table with just after the second line in strbody (the table should contain data from A to D with headers and the corresponding row of the analyst in column F.)
Here is the sample data Click Here
And the final email should look like below for the first email and so on..
enter image description here
Thanks in advance.
Try the script below. It will let you choose a range to attach to the body of an Outlook email.
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
Notice this: Function RangetoHTML(rng As Range)

Resources