Paste cells into Outlook then convert table to text in Excel - excel

I'm trying to build a macro that grabs a selection of cells from an Excel spreadsheet, pastes the cells into a new outlook email, then changes the format of the cells.
Specifically I want to convert the table to text, then change the font to Arial size 10.
The code below does the above, but I haven't been able to figure out how to convert the table to text, then change the text font.
Can anyone help?
Sub Email_test()
Dim rng As Range
Dim OutApp As Object
Dim OutMail As Object
Set rng = Nothing
Set rng = Sheets("Master").Range("A1:B99").SpecialCells(xlCellTypeVisible)
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)
With OutMail
.To = "User#company.com"
.CC = ""
.BCC = ""
.Subject = "Cells as text "
.HTMLbody = RangetoHTML(rng)
' In place of the following statement, you can use ".Display" to
' display the e-mail message.
.Display
End With
End Sub

This will work for you, instead of HTMLbody use body also removed your range to html function
Sub Email_test()
Dim rng As Range
Dim OutApp As Object
Dim OutMail As Object
Set rng = Nothing
Set rng = Sheets("Master").Range("A1:B99").SpecialCells(xlCellTypeVisible)
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
Dim v As Variant: v = rng.Value
Dim tempStr As String: tempStr = ""
For i = LBound(v, 1) To UBound(v, 1)
For j = LBound(v, 2) To UBound(v, 2)
If j = 2 Then
tempStr = tempStr & v(i, j) & vbCrLf
Else
tempStr = tempStr & v(i, j) & " "
End If
Next j
Next i
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With OutMail
.To = "User#company.com"
.CC = ""
.BCC = ""
.Subject = "Cells as text "
.body = tempStr
' In place of the following statement, you can use ".Display" to
' display the e-mail message.
.Display
End With
End Sub
Please mark as an answer if you are satisfied with reply

The Outlook object model provides three main ways for working item bodies:
Body - a string representing the clear-text body of the Outlook item.
HTMLBody - a string representing the HTML body of the specified item.
Word editor - the Microsoft Word Document Object Model of the message being displayed. The WordEditor property of the Inspector class returns an instance of the Document class from the Word object model which you can use to set up the message body.
You can read more about all these ways in the Chapter 17: Working with Item Bodies. It us up to you which way is to choose.

Related

How to make a loop that will incrementally add lines to an email body if a certain condition is met?

So I'm really new to VBA (and by new I mean a couple of days in). I'm looking to make a loop that will incrementally add lines to an email body if a certain condition is met. I apologise in advance if it is horrible to read but it does seem to work so far! If anyone can tell me how I can add something to the loop so that it adds a new line to the email body every time the condition is met, I would appreciate it.
Here's what I have so far:
Sub SendEmailReminder()
Dim x As Integer
Dim Removal As String
Dim RemovalTitle As String
Removal = Removal
RemovalTitle = RemovalTitle
' Set numrows = number of rows of data.
numrows = Range("C2").End(xlDown).row - 1
' Select cell 2.
Range("C2").Select
' Establish "For" loop to loop "numrows" number of times.
For x = 1 To numrows
If ActiveCell = Date - 30 Then
Removal = ActiveCell.Offset(0, -2)
RemovalTitle = ActiveCell.Offset(0, -1)
Dim OutApp As Object
Dim OutMail As Object
Dim strbody As String
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
strbody = Removal & " - " & RemovalTitle & " needs to be removed from New Releases"
On Error Resume Next
With OutMail
.To = ""
.CC = ""
.BCC = ""
.Subject = ""
.Body = strbody
.Display 'or use .Send
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End If
' Selects cell down 1 row from active cell.
ActiveCell.Offset(1, 0).Select
Next
End Sub
You can do this:
Sub SendEmailReminder()
Dim x As Integer
Dim c As Range
Dim OutApp As Object
Dim strbody As String
Set c = Range("C2")
'loop while cell is not empty
Do While Len(c.Value) > 0
If c.Value = Date - 30 Then
'build the message
strbody = strbody & vbCrLf & c.Offset(0, -2) & " - " & _
c.Offset(0, -1) & " needs to be removed from New Releases"
End If
Set c = c.Offset(1, 0) 'next cell
Loop
Set OutApp = CreateObject("Outlook.Application")
On Error Resume Next
With OutApp.CreateItem(0)
.To = ""
.CC = ""
.BCC = ""
.Subject = ""
.Body = strbody
.Display 'or use .Send
End With
On Error GoTo 0
Set OutApp = Nothing
End Sub

Impossible Excel-VBA Email Loop

If someone could help me from going insane, my mother would appreciate it.
I have a long list of email addresses (many repeats) with associated Audit Locations. Basically I need to create one email for each email address and populate said email body with a list of all the associated Audit Locations.
e.g.
Column One (Email Address) | Column 2 (Audit Location)
Yoda1#lightside.org | Coruscant
Yoda1#lightside.org | Death Star
Yoda1#lightside.org | Tatooine
Vader#Darkside.org | Death Star
Vader#Darkside.org | Coruscant
Jarjar#terrible.org | Yavin
So far I have created a CommandButton Controlled vba that takes Column One and makes it unique in a new worksheet.
Then I have another sub that creates an email for each unique email address. But I am stuck on the "If...Then" statement. Essentially, I want to add the information in Column 2 (Audit Location) if the Recipient of the email is the email address in Column One and then continue to append to the email body until the email address no longer equals the recipient email address. Any guidance would be huge.
Private Sub CommandButton1_Click()
Call MakeUnique
Call EmailOut
End Sub
Sub MakeUnique()
Dim vaData As Variant
Dim colUnique As Collection
Dim aOutput() As Variant
Dim i As Long
'Put the data in an array
vaData = Sheet1.Range("A:A").Value
'Create a new collection
Set colUnique = New Collection
'Loop through the data
For i = LBound(vaData, 1) To UBound(vaData, 1)
'Collections can't have duplicate keys, so try to
'add each item to the collection ignoring errors.
'Only unique items will be added
On Error Resume Next
colUnique.Add vaData(i, 1), CStr(vaData(i, 1))
On Error GoTo 0
Next i
'size an array to write out to the sheet
ReDim aOutput(1 To colUnique.Count, 1 To 1)
'Loop through the collection and fill the output array
For i = 1 To colUnique.Count
aOutput(i, 1) = colUnique.Item(i)
Next i
'Write the unique values to column B
Sheets.Add.Name = "Unique"
ActiveSheet.Range("A1").Resize(UBound(aOutput, 1), UBound(aOutput, 2)).Value = aOutput
End Sub
Sub EmailOut()
Dim xOutApp As Object
Dim xOutMail As Object
Dim xMailBody As String
On Error Resume Next
Dim cell As Range
For Each cell In Worksheets("Unique").Columns("a").Cells.SpecialCells(xlCellTypeConstants)
recip = cell.Value
Set xOutApp = CreateObject("Outlook.Application")
Set xOutMail = xOutApp.CreateItem(0)
For Each org In Columns("b").Cells.SpecialCells(xlCellTypeConstants)
If org.Value Like recip Then
xMailBody = "Body content" & vbNewLine & vbNewLine & _
"This is line 1" & " " & cell.Offset(0, 3).Value & vbNewLine & _
[B5] & vbNewLine & _
"This is line 2"
End If
Next org
On Error Resume Next
With xOutMail
.To = recip
.CC = ""
.BCC = ""
.Subject = cell.Offset(0, 2).Value & " " & cell.Offset(0, 3).Value & " " & "Remittance Advice"
.Body = xMailBody
.Display 'or use .Send
End With
On Error GoTo 0
Set xOutMail = Nothing
Set xOutApp = Nothing
Next
End Sub
Based on your example I quickly wrote the following:
Option Explicit
Public Sub SendEmails()
Dim dictEmailData As Object
Dim CurrentWorkBook As Workbook
Dim WrkSht As Worksheet
Dim rngToLookUp As Range
Dim lngLastRow As Long, i As Long
Dim arryEmailData As Variant
Dim objOutlookApp As Object, objOutlookEmail As Object
Dim varKey As Variant
Application.ScreenUpdating = False
Set CurrentWorkBook = Workbooks("SomeWBName")
Set WrkSht = CurrentWorkBook.Worksheets("SomeWSName")
lngLastRow = WrkSht.Cells(WrkSht.Rows.Count, "A").End(xlUp).Row 'Find last row with data
Set rngToLookUp = WrkSht.Range("A2:B" & lngLastRow) 'set range for last row of data
arryEmailData = rngToLookUp.Value2 'Get the email data from the sheet into an array
Set dictEmailData = CreateObject("Scripting.Dictionary") 'set the dicitonary object
On Error GoTo CleanFail
For i = LBound(arryEmailData, 1) To UBound(arryEmailData, 1)
varKey = UCase(Trim(arryEmailData(i, 1)))
If Not dictEmailData.Exists(varKey) Then
dictEmailData(varKey) = vbNewLine & vbNewLine & Trim(arryEmailData(i, 2))
Else
dictEmailData(varKey) = dictEmailData(varKey) & vbNewLine & Trim(arryEmailData(i, 2))
End If
varKey = Empty
Next i
'for each unique key in the dicitonary
'get the corresponding item
'created in the loop above
Set objOutlookApp = CreateObject("Outlook.Application") 'set the outlook object
Dim Msg As String, MailBody As String
For Each varKey In dictEmailData.Keys
Msg = dictEmailData.Item(varKey)
Set objOutlookEmail = objOutlookApp.CreateItem(0)
MailBody = "Dear Colleague," & Msg
With objOutlookEmail
.To = varKey
.Subject = "Remittance Advice"
.Body = MailBody
.Send
End With
Set objOutlookEmail = Nothing
Msg = Empty: MailBody = Empty
Next
MsgBox "All Emails have been sent", vbInformation
CleanExit:
Set objOutlookApp = Nothing
Application.ScreenUpdating = True
Exit Sub
CleanFail:
Resume CleanExit
End Sub
Add the first occurrence of a varKey = email address to the dictionary dictEmailData along with its corresponding item dictEmailData(varKey) = Email body. On the next occurrence of the email address, append to the Email body. Once the dictionary is built, loop through it and send the emails
Printing to the immediate window yields:

Excel macro to send selected cells in email not working

I'm trying to automate a report by being able to send a selected range of cells, that includes hidden cells, by making a macro. When I try to run the macro, it is blank. Please note that the text not written as a code are instructions. Macro is shown below:
Sub SendforApproval()
'
' SendforApproval Macro
'
' Generate Email
Dim OutApp As Object
Dim OutMail As Object
Dim strbody As String
Dim rng As Range
If ActiveWorkbook.Path <> "" Then
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
Set myOlApp = CreateObject("Outlook.Application")
'This is where the body of the email is populated - you can point to cells in your worksheet to pull text from them
strbody = "<font size=""3"" face=""Cambria"">" & _
"Hi " & Range("B5") & ",<br>" & _
"<br>Please note finance request #" & Range("a7") & " has been accepted. Upon review, please use voting buttons to Approve or Send for Rework.<br>"
' The range belows designates which portion of your sheet will be inserted in the body of the email
Set rng = Sheets("SheetName").Range("A7:T22").SpecialCells(xlCellTypeVisible)
'You can also use a fixed range if you want or flex range
'Set rng = Sheets("YourSheet").Range("D4:D12").SpecialCells(xlCellTypeVisible)
'Set rng = Range("f7").Resize(Application.CountA(Range("f7:f" & Rows.Count)), 12)
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)
' This section defines receipants, Subject
On Error Resume Next
With OutMail
.To = Range("D7")
.CC = "yourname#email.com"
.BCC = ""
.Subject = "Finance Request #" & Range("a7")
' This section adds Voting buttons
.Display 'or use .Send to automatically send without giving opportunity to review final product
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
' End of email process
End If
End Sub
you should use "on error resume next" with more caution. You dont see the exception that occurs.
your failure is that you want to get the value of the cells D7 and A7 (string) but you take instead the range (object).
Try the following:
With OutMail
.To = Range("D7").Value
.CC = "yourname#email.com"
.BCC = ""
.Subject = "Finance Request #" & Range("A7").Value
' This section adds Voting buttons
.Display 'or use .Send to automatically send without giving opportunity to review final product
End With

How to send an email to names of people in column A by getting their email address from outlook contact list?

I am trying to send an email to the names listed in column A but I don't have their email addresses. the email addresses are in outlook contacts. I can get it to display their emails in column B but I don't want to do that. I want to look up the email address and append it to the "To" field in the email. How it looks now is that, it only appends the email address for the last person in column A to all the emails for the other people in Column A. as seen in the pic. all the people in the A column are getting the same email address for the last person in their To field.
Option Explicit
Sub GetAddressesAndSendEmail()
Sheet10.Select
Dim o, AddressList, AddressEntry
Dim ToField As String
Dim c As range, r As range, AddressName As String
Set o = CreateObject("Outlook.Application")
Set AddressList = o.Session.AddressLists("Contacts")
Set r = Sheet10.range("A1", range("A1").End(xlDown))
For Each c In r
AddressName = c.Value
For Each AddressEntry In AddressList.AddressEntries
If AddressEntry.Name = AddressName Then
'c.Offset(0, 1).Value = AddressEntry.Address
ToField = AddressEntry.Address
'MsgBox ToField
Exit For
End If
Next AddressEntry
Next c
Dim OutApp As Object
Dim OutMail As Object
Dim cell As range
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
On Error GoTo cleanup
For Each cell In Columns("A").Cells.SpecialCells(xlCellTypeConstants)
If LCase(Cells(cell.Row, "D").Value) <> "" Then
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = ToField
.Subject = "Reminder"
.Body = "Dear " & Cells(cell.Row, "A").Value _
& vbNewLine & vbNewLine & _
"Please contact us to discuss bringing " & _
"your account up to date"
.Attachments.Add ("C:\" & Cells(cell.Row, "D").Value & ".txt")
'.Send
.Display
End With
On Error GoTo 0
Set OutMail = Nothing
End If
Next cell
cleanup:
Set OutApp = Nothing
Application.ScreenUpdating = True
End Sub
Never ever loop through all items in an address book container. If the name can be resolved to a contact, all you need to do is set the MailItem.To property - when the message is sent, Outlook will resolve the name to an address. If you want to do that before sending the message, or if you really want the email address, call Application.Session.CreateRecipient - it will return an instance of the Recipient object. Call Recipient.Resolve and read Recipient.Address property. If the name cannot be resolved (if it is not found or the name is ambiguous), Recipient.Resolve will raise an exception.
Create each mail before you overwrite ToField.
For Each AddressEntry In AddressList.AddressEntries
If AddressEntry.Name = AddressName Then
'c.Offset(0, 1).Value = AddressEntry.Address
ToField = AddressEntry.Address
'MsgBox ToField
Set OutMail = o.CreateItem(0)
With OutMail
.To = ToField
.Subject = "Reminder"
.Body = "Dear " & Cells(cell.Row, "A").Value _
& vbNewLine & vbNewLine & _
"Please contact us to discuss bringing " & _
"your account up to date"
.Attachments.Add ("C:\" & Cells(cell.Row, "D").Value & ".txt")
'.Send
.Display
End With
Set OutMail = Nothing
Exit For
End If
Next AddressEntry
Consider doing it this way.
In column A : Names of the people
In column B : E-mail addresses
In column C:Z : Filenames like this C:\Data\Book2.xls (don't have to be Excel files)
The Macro will loop through each row in "Sheet1" and if there is a 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-2016
'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
https://www.rondebruin.nl/win/s1/outlook/amail6.htm

How to skip current cell in a for each loop

In excel I have the following code which sends out emails for every cell that contains an email address in column K.
This would work except for the header in the table isn't an email address, so it breaks the code. I tried to skip the header by specifying "if cell.value = CONTACT METHOD, which is the header name text, then go to Next cell"
but this causes a "Next without for" error.
Sub Mail_small_Text_Outlook()
'For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
'Working in Office 2000-2013
Dim OutApp As Object
Dim OutMail As Object
Dim cell As Range
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
On Error GoTo cleanup
For Each cell In Columns("K").Cells.SpecialCells(xlCellTypeConstants)
If cell.Value Like "*#*" Then
finaladdress = cell.Value
Else
finaladdress = cell.Value & "#email.smsglobal.com"
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = finaladdress
.Subject = "Reminder"
.Body = "Dear " & Cells(cell.Row, "A").Value _
& vbNewLine & vbNewLine & _
"Please contact us to discuss bringing " & _
"your account up to date"
'You can add files also like this
'.Attachments.Add ("C:\test.txt")
.Display
End With
On Error GoTo 0
Set OutMail = Nothing
End If
Next cell
cleanup:
Set OutApp = Nothing
Application.ScreenUpdating = True
End Sub
If your goal is to skip cell K1 in looping down column K then:
For Each cell In Columns("K2:K" & Rows.Count).Cells.SpecialCells(xlCellTypeConstants)
You can enclose the code within the FOR/EACH loop within a separate IF statement, as below:
Sub Mail_small_Text_Outlook()
'For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
'Working in Office 2000-2013
Dim OutApp As Object
Dim OutMail As Object
Dim cell As Range
Application.ScreenUpdating = False
Set OutApp = CreateObject("Outlook.Application")
On Error GoTo cleanup
For Each cell In Columns("K").Cells.SpecialCells(xlCellTypeConstants)
If cell.Value = "CONTACT METHOD" Then
'Do Nothing, or Enter code here
Else
If cell.Value Like "*#*" Then
finaladdress = cell.Value
Else
finaladdress = cell.Value & "#email.smsglobal.com"
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = finaladdress
.Subject = "Reminder"
.Body = "Dear " & Cells(cell.Row, "A").Value _
& vbNewLine & vbNewLine & _
"Please contact us to discuss bringing " & _
"your account up to date"
'You can add files also like this
'.Attachments.Add ("C:\test.txt")
.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

Resources