Trying to setup VBA code that will take a selection of Excel cells which contain email addresses (with a semi-colon at the end of each address to allow for multiple emails when pasted) and insert those into the "To" field in an new Outlook email. When I execute the below code, it only inserts the email addresses into the Body of the Outlook email, not the "To" field. Is there a way to fix this or will I need to approach this in a completely different fashion?
Here is my code:
Sub Test2()
Dim OutApp As Object
Dim OutMail As Object
Dim Subj As String
Dim oiInsp As Object
Dim wdDoc As Object
Dim oRng As Object
'Copy the email addresses to the clipboard
Range("B2").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
'Create Outlook object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
'Trying to add the email address to the "To" field in the email
With OutMail
.Display
Set olInsp = .GetInspector
Set wdDoc = olInsp.WordEditor
Set oRng = wdDoc.Range
.To = oRng.Paste
'This will resolve all the addresses in the email to ensure they exist in your contacts, otherwise pops up error
If Not .Recipients.ResolveAll Then
For Each Recipient In .Recipients
If Not Recipient.Resolved Then
MsgBox Recipient.Name & " could not be resolved"
End If
Next
End If
End With
On Error GoTo 0
Set OutApp = Nothing
Set OutMail = Nothing
Set olInsp = Nothing
Set wdDoc = Nothing
Set oRng = Nothing
End Sub
Try creating a string of recipients instead - you can't paste a range to the .To like that.
Sub Test2()
Dim OutApp As Object
Dim OutMail As Object
Dim Subj As String
Dim oiInsp As Object
Dim wdDoc As Object
Dim oRng As Object
Dim lastrow As Long, i As Long
Dim recipstring As String
lastrow = Cells(Rows.Count, 2).End(xlUp).Row
For i = 2 To lastrow
If i = 2 Then
recipstring = Range("B" & i).Value
Else
recipstring = recipstring & ";" & Range("B" & i).Value
End If
Next i
'Create Outlook object
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
'Trying to add the email address to the "To" field in the email
With OutMail
.Display
Set olInsp = .GetInspector
Set wdDoc = olInsp.WordEditor
Set oRng = wdDoc.Range
.to = recipstring
'This will resolve all the addresses in the email to ensure they exist in your contacts, otherwise pops up error
If Not .Recipients.ResolveAll Then
For Each Recipient In .Recipients
If Not Recipient.Resolved Then
MsgBox Recipient.Name & " could not be resolved"
End If
Next
End If
End With
On Error GoTo 0
Set OutApp = Nothing
Set OutMail = Nothing
Set olInsp = Nothing
Set wdDoc = Nothing
Set oRng = Nothing
End Sub
Related
I want to use a Excel macro to send a mail to a company. This mail should consist of a piece of text, a table and then the rest of the text.
In the function below I've compiled some code that works the way I want, but I would like to send the e-mail not from my personal account but from a corporate business account (in the code I refer to the latter as myemailadres#outlook.com). I think I have to use the .SendUsingAccount function, but if I implement it like shown below, the e-mail is send using my personal email account and not the one I specify. Can somebody help?
Sub Test()
Dim rng As Range
Dim OutApp As Object
Dim OutMail As Object
Dim TargetSheet As String
Dim i As Long
Dim StrBodybegin As String
Dim StrBodyend As String
Dim Startcell
Dim TargetRow As Integer
TargetSheet = Range("L24").value 'L24 refers to a name of a company, there is also a sheet in the workbook with the exact same name.
With Application.WorksheetFunction 'this I copied from the code from Ron de Bruijn
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
TargetRow = .Match("TOTAAL", ThisWorkbook.Worksheets(TargetSheet).Range("W1:W60"), 0) 'setting range of table I want to copy
Set Startcell = ThisWorkbook.Worksheets(TargetSheet).Range("W15")
Set rng = ThisWorkbook.Worksheets(TargetSheet).Range(Startcell, ThisWorkbook.Worksheets(TargetSheet).Cells(TargetRow + 1, 38))
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
StrBodybegin = "Text 1"
StrBodyend = "Text 2"
On Error Resume Next
With OutMail
.To = ThisWorkbook.Worksheets("Voorblad").Range("L23").value 'L23 refers to email adress
.CC = ""
.BCC = ""
.Subject = "Subject"
.HTMLBody = StrBodybegin & RangetoHTML(rng) & StrBodyend 'using the Ron de Bruin function RangetoHTML to copy in the table defined by the rng
.SendUsingAccount = OutApp.Session.Accounts("myemailadres#outlook.com") 'the line that does not work :(
.Send
End With
On Error GoTo 0
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
Set OutMail = Nothing
Set OutApp = Nothing
End With
End Sub
You can use the property .SentOnBehalfOfName = "user#domain" if you have access to that mailbox or user or whatever. Even if it's not added to your outlook, like this:
Option Explicit
Sub Test()
Dim rng As Range
Dim OutApp As Object
Dim OutMail As Object
Dim TargetSheet As String
Dim i As Long
Dim StrBodybegin As String
Dim StrBodyend As String
Dim Startcell
Dim TargetRow As Integer
TargetSheet = Range("L24").Value 'L24 refers to a name of a company, there is also a sheet in the workbook with the exact same name.
With Application.WorksheetFunction 'this I copied from the code from Ron de Bruijn
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
TargetRow = .Match("TOTAAL", ThisWorkbook.Worksheets(TargetSheet).Range("W1:W60"), 0) 'setting range of table I want to copy
Set Startcell = ThisWorkbook.Worksheets(TargetSheet).Range("W15")
Set rng = ThisWorkbook.Worksheets(TargetSheet).Range(Startcell, ThisWorkbook.Worksheets(TargetSheet).Cells(TargetRow + 1, 38))
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
StrBodybegin = "Text 1"
StrBodyend = "Text 2"
On Error Resume Next
With OutMail
.SentOnBehalfOfName = "user#domain"
.To = ThisWorkbook.Worksheets("Voorblad").Range("L23").Value 'L23 refers to email adress
.CC = ""
.BCC = ""
.Subject = "Subject"
.HTMLBody = StrBodybegin & RangetoHTML(rng) & StrBodyend 'using the Ron de Bruin function RangetoHTML to copy in the table defined by the rng
.SendUsingAccount = OutApp.Session.Accounts("myemailadres#outlook.com") 'the line that does not work :(
.Send
End With
On Error GoTo 0
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
Set OutMail = Nothing
Set OutApp = Nothing
End With
End Sub
Try, please:
.SendUsingAccount = outApp.GetNamespace("MAPI").accounts.Item("myemailadres#outlook.com")
And, when you try debugging, it is recommended to comment the line On Error Resume Next. You can not see where and what error appears. In fact, it should not exist at all, if everything is correct..
Find your account loop through accounts.
Dim outApp As object, outNS as object
Dim accounts As object, account As object, myAccount As object
set outApp =createobject("outlook.application")
set outNS = outApp.GetNamespace("MAPI")
Set accounts = outNS.Accounts
For Each account in accounts
if account.SmtpAddress = "myemailadrs#outlook.com" then
set myAccount = account
Exit For
end if
Next account
With outApp.CreateItem(0)
.to = "someone#abc.com"
'...
Set .SendUsingAccount = myAccount
'....
End With
I copy a range and paste into Outlook email with signature.
I want to reflect the range in center of body of email.
Dim OutApp As Object
Dim OutMail As Object
Dim rng As Range
Set rng = Nothing
Set rng = ThisWorkbook.Sheets("Output").Range("D7:E18")
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With OutMail
.To = ""
.BCC = ""
.Subject = "Subject"
.Display
Dim wdDoc As Object
Dim wdRange As Object
Set wdDoc = OutMail.GetInspector.WordEditor
Set wdRange = wdDoc.Range(0, 0)
wdRange.InsertAfter vbCrLf & vbCrLf
rng.Copy
wdRange.Paste
Set OutMail = Nothing
Set OutApp = Nothing
End With
What the code does is, it centers not only the text but also the table (Excel Range) pasted in the outlook body.
Option Explicit
Const wdAlignRowCenter As Integer = 1
Const wdAlignParagraphCenter As Integer = 1
Sub Sample()
Dim OutApp As Object, OutMail As Object
Dim wdDoc As Object, wdRange As Object
Dim rng As Range
Dim i As Long
Set rng = ThisWorkbook.Sheets("Output").Range("D7:E18")
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
With OutMail
.To = ""
.BCC = ""
.Subject = "Subject"
.Display
Set wdDoc = .GetInspector.WordEditor
Set wdRange = wdDoc.Range(0, 0)
wdRange.InsertAfter vbCrLf & vbCrLf
rng.Copy
wdRange.Paste
DoEvents
Set wdRange = wdDoc.Range(0, wdDoc.Characters.Count)
wdRange.ParagraphFormat.Alignment = wdAlignParagraphCenter
For i = 1 To wdRange.Tables.Count
wdRange.Tables(i).Rows.Alignment = wdAlignRowCenter
Next i
End With
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
Note:
BTW Set wdDoc = .GetInspector.WordEditor will give you error if the default editor is not MS Word...
If there are images in your body then you may have to handle them as well seperately
This is the first time I am trying from Excel to send email using VBA code.
Here is my structure of my Excel. Sometimes the email list will have 1 - 20 or only 1 also
A (col) B C D E F G
Sl.No First Name To Email CC Email Subj File to Send Message
Code:
Option Explicit
Sub SendMail()
Dim objOutlook As Object
Dim objMail As Object
Dim rngTo As Range
Dim rngSubject As Range
Dim rngBody As Range
Dim rngAttach As Range
Set objOutlook = CreateObject("Outlook.Application")
Set objMail = objOutlook.CreateItem(0)
With ActiveSheet
Set rngTo = .Range("C2")
Set rngSubject = .Range("E2")
Set rngBody = .Range("G2")
Set rngAttach = .Range("F2")
End With
With objMail
.To = rngTo.Value
.Subject = rngSubject.Value
.Body = rngBody.Value
.Attachments.Add rngAttach.Value
.Display
End With
Set objOutlook = Nothing
Set objMail = Nothing
Set rngTo = Nothing
Set rngSubject = Nothing
Set rngBody = Nothing
Set rngAttach = Nothing
End Sub
Here is my code this was working perfectly fine but for single emails to send, but not for multiple email.
I am struggling here to find how to send for multiple email with attachment using the tested code.
Maybe Try this:
Option Explicit
Sub SendMail()
Dim objOutlook As Object
Dim objMail As Object
Dim rngTo As Range
Dim rngSubject As Range
Dim rngBody As Range
Dim rngAttach As Range
Dim i As Integer
Set objOutlook = CreateObject("Outlook.Application")
For i = 2 To 21 ' Loop from 2 to 21
With ActiveSheet
Set rngTo = .Range("C" & i)
Set rngSubject = .Range("E" & i)
Set rngBody = .Range("G" & i)
Set rngAttach = .Range("F" & i)
End With
Set objMail = objOutlook.CreateItem(0)
With objMail
.To = rngTo.Value
.Subject = rngSubject.Value
.HTMLBody = "<B><U>" & rngBody.Value & ":</B></U>"
.Attachments.Add rngAttach.Value
.Display
End With
Set objMail = Nothing
Next
Set objOutlook = Nothing
Set rngTo = Nothing
Set rngSubject = Nothing
Set rngBody = Nothing
Set rngAttach = Nothing
End Sub
You can loop through the Range to generate 20 emails.
Update
Added .HTMLBody instead of .Body to make text Bold And Underlined
You can use more HTML commands to make certain portions of the Text Bold and More.
Try it this way.
Make a list in Sheets("Sheet1") with :
In column A : Names of the people
In column B : E-mail addresses
In column C:Z : Filenames like this C:\Data\Book2.xls (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
You need a loop for that. The below code will start with the second row and continue until it finds an empty row.
Option Explicit
Sub SendMail()
Dim objOutlook As Object
Dim objMail As Object
Dim rngTo As Range
Dim rngSubject As Range
Dim rngBody As Range
Dim rngAttach As Range
Set objOutlook = CreateObject("Outlook.Application")
Dim r As Long: For r = 2 To ActiveSheet.Range("C2").End(xlDown).Row
With ActiveSheet
Set rngTo = .Range("C" & r)
Set rngSubject = .Range("E" & r)
Set rngBody = .Range("G" & r)
Set rngAttach = .Range("F" & r)
End With
Set objMail = objOutlook.CreateItem(0)
With objMail
.to = rngTo.Value
.Subject = rngSubject.Value
.Body = rngBody.Value
.Attachments.Add rngAttach.Value
.Display
.Send ' If you want to send it without clicking
End With
Next
End Sub
Also note: These Set x = Nothing lines are superfluous, delete them because they just make the code less readable for humans. Regarding this issue you can also refer to this SO question: Is there a need to set Objects to Nothing inside VBA Functions
Update
Sorry this line has to be inside the loop, I updated the code:
Set objMail = objOutlook.CreateItem(0)
I have a code in Excel that copy a table to a new Email:
Option Explicit
Public Sub TESTEMAIL()
Const olMailItem As Long = 0
Dim StrFile, signature As String
Dim OutApp As Outlook.Application
Dim Outmail As Outlook.MailItem
Set OutApp = CreateObject("Outlook.Application")
Set Outmail = OutApp.CreateItem(olMailItem)
Dim myRecipient As Object
Set OutApp = CreateObject("Outlook.Application")
Set Outmail = OutApp.CreateItem(olMailItem)
Set OutApp = Nothing
Outmail.Display
Dim wordDoc As Word.Document
Set wordDoc = Outmail.GetInspector.WordEditor
Range("A1:E10").Copy
Dim p1 As Picture
Set p1 = ActiveSheet.Pictures.Paste
p1.Cut
With wordDoc.Application.Selection
.Start = Len(Outmail.Body) ' error n° 91
.End = .Start
.PasteSpecial wdPasteBitmap ' Error n° 4605 or Error n°91
End With
End Sub
The code returns an error every first time I use it after starting the computer:
Error Code 91 "Object variable or With block variable not set"
It is most of the time when Outlook wasn't opened before or when no new email was opened before.
Sometimes I also get the error code 4605, saying that the document is locked against modifications.
The 2 Errors are coming at the end and are marked in the code. (error can happen on 2 different lines)
Sometimes everything worked but only when a new email was opened in Outlook before, (event if Outlook is closed).
Any clue why that might be and how to solve the problem?
Is this what you are trying to do?
Example
Option Explicit
Public Sub TESTEMAIL()
Dim OutApp As Outlook.Application
Set OutApp = CreateObject("Outlook.Application")
Dim Outmail As Outlook.MailItem
Set Outmail = OutApp.CreateItem(olMailItem)
Dim wordDoc As Word.Document
Set wordDoc = Outmail.GetInspector.WordEditor
Dim Sht As Excel.Worksheet
Set Sht = ActiveWorkbook.Sheets("Sheet1")
Dim rng As Range
Set rng = Sht.Range("A1:E10")
rng.CopyPicture Appearance:=xlScreen, Format:=xlPicture
With Outmail
.To = "0m3r#email.com"
.CC = ""
.BCC = ""
.Subject = "Hello"
.Display
wordDoc.Paragraphs(1).Range.PasteSpecial Link:=False, _
DataType:=wdPasteBitmap, _
Placement:=wdFloatOverText, _
DisplayAsIcon:=False
wordDoc.Paragraphs(1).SpaceAfter = 20 ' add space to 12 points
wordDoc.Range.InsertBefore "Hello 0m3r" & vbCr
wordDoc.Paragraphs(1).SpaceAfter = 20 ' add space to 12 points
End With
End Sub
Make sure to Reference to Microsoft Word & Outlook xx.x Object Library
MSDN Paragraphs.SpaceAfter property (Word)
MSDN Range.PasteAndFormat method (Word)
MSDN PasteAndFormat Method
MSDN WdPasteDataType enumeration (Word)
This question already has an answer here:
Excel 2010 Paste Range and Picture into Outlook
(1 answer)
Closed 7 years ago.
Pretty simple and straight forward. I am looking to copy a range in a worksheet, open a new email to outlook and paste the range as an image. The following code is what I currently have. Despite my efforts, I have been unable to paste as a photo.
Sub CreateMail()
Dim objOutlook As Object
Dim objMail As Object
Dim rngTo As Range
Dim rngBody As Range
Set objOutlook = CreateObject("Outlook.Application")
Set objMail = objOutlook.CreateItem(0)
With Sheets("Hourly Labor Model")
Set rngBody = .Range(.Range("A6"), .Range("AA99").End(xlDown))
End With
rngBody.Copy
With objMail
.To = "user#useremail.com"
.Subject = "Hourly Dashboard- " & Sheets("Graphs").Range("AA1") & " on " & Format(Now(), "mm/dd/yyyy") & " # " & Format(Time(), "hh:mm:ss")
.display
End With
SendKeys "^({v})", True
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
Please and thank you in advance.
Based on this thread, I think the below would work:
Sub CreateMail()
Dim objOutlook As Object
Dim objMail As Object
Dim rngTo As Range
Dim rngBody As Range
Dim outMail As Outlook.MailItem 'new
Set objOutlook = CreateObject("Outlook.Application")
Set objMail = objOutlook.CreateItem(0)
Set outMail = objOutlook.CreateItem(olMailItem)
With Sheets("Hourly Labor Model")
Set rngBody = .Range(.Range("A6"), .Range("AA99").End(xlDown))
End With
rngBody.Copy
With objMail
.To = "user#useremail.com"
.Subject = "Hourly Dashboard- " & Sheets("Graphs").Range("AA1") & " on " & Format(Now(), "mm/dd/yyyy") & " # " & Format(Time(), "hh:mm:ss")
.Display
'outMail.Display
Dim wordDoc As Word.Document
Set wordDoc = .GetInspector.WordEditor ' or use outMail instead of with()
wordDoc.Range.PasteandFormat wdChartPicture
End With
SendKeys "^({v})", True
On Error GoTo 0
Set outMail = Nothing
Set OutApp = Nothing
End Sub