Send mails in bulk rather than sending each mail immediately upon completion - vba

I've a loop to send about 75 emails, each with an individual attachment for each individual recipient. This works, but I'm wondering how to create all these, and send them all in one go, instead of feeding them through one at a time.
I know I can use .display instead of .send to have the email show in Outlook, but is there any way to use VBA to temporarily disable sending emails, and then enable it once all mails are created?
My code looks something like this -
Dim employee_name As Variant
Dim file_path As String
Dim file_ext As String
Dim AGENT_FILE As String
Dim e As Variant
Dim email As Variant
Dim a As Integer
a = "0"
Sheets("EMAILS").Select
employee_name = Range("A1:A76").Value
file_path = "H:\Email TEST\"
file_ext = ".xlsx"
Dim OutApp As Object
Dim OutMail As Object
Dim distributionList As String
Set OutApp = CreateObject("Outlook.Application")
For Each e In employee_name
If e <> "" Then
Set OutMail = OutApp.CreateItem(0)
With Sheets("EMAILS").Select
a = a + 1
email = Range("B" & a).Value
AGENT_FILE = file_path & e & file_ext
On Error Resume Next
With OutMail
.To = email
.CC = ""
.BCC = ""
.Subject = "Daily Stats"
.Body = "Hello ," & vbCrLf & _
vbCrLf & _
"Attached are your daily stats." & vbCrLf & _
vbCrLf & _
"Regards, " & vbCrLf & _
"Oliver Lockett"
.Attachments.Add AGENT_FILE
.send
End With
End With
Set OutMail = Nothing
End If
Next
Set OutApp = Nothing

I had similar kind of stuff years ago...
I preferred using .save instead of .send. Because of this all emails where saved under drafts....once all Emails are saved....I had a macro in Outlook to send all drafts...
This can be acheived here
http://www.techrepublic.com/forum/questions/101-309127/send-all-mails-from-my-drafts-folder-at-one-go-in-outlook-2003

Why would you want to do that? Send is asynchronous, it will not block your code.

Related

How to assign a recipient to .To?

I convert a worksheet into a PDF and am trying to have that PDF emailed to me and copied to another person. All of this will be assigned to an action button/trigger.
Option Explicit
Sub SendExcelFileAsPDF()
Dim OutlookApp As Outlook.Application
Dim emItem As Object
Dim Receipt As String, Subject As String
Dim Message As String, Fname As String
Dim Recipient As Outlook.Recipient
Recipient = "xxxxx.xxxxx#fedex.com"
Subject = "Weekly Critical Items" & " " & Range("L1")
Message = Range("D2") & Range("J2") & "Weekly Critical Items submitted" &
Range("L1") & " " & "in PDF Format"
Message = Message & vbNewLine & vbNewLine & "Offload Ops"
Fname = Application.DefaultFilePath & "/" & ActiveWorkbook.Name & ".pdf"
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=Fname
Set OutlookApp = New Outlook.Application
Set emItem = OutlookApp.CreateItem(olMailItem)
With emItem
.To = Recipient = "xxxxx.xxxxx#fedex.com"
.Subject = Subject
.Body = Message
.Attachements.Add Fname
.Send
End With
Set OutlookApp = Nothing
End Sub
The recipient line is where I am having issues. When I run the debugger, it's giving
Run-Time error '91: Object variable or with block variable not set
I would dim recipient as string and update the .to assignment:
Change
Dim Recipient As Outlook.Recipient
.To = Recipient = "dennis.aikens#fedex.com"
to
Dim Recipient As string
.To = Recipient
This line
.To = Recipient = "dennis.aikens#fedex.com"
Should be just
.To = Recipient

"Save As" document link won't open, with error message ".. can't find .. correct location or web address"

I have an Excel Document in a Template. Users input information and Save As a new genericized number. They then hit a button that auto populates an email to one of 5 people using Vlookup and based on the cost margin.
The file is Save As'd but the e-mail recipient cannot open the file, it reads invalid location. I can close and reopen the new renamed sheet and drag it into an e-mail. I need to link to the newly saved file's name that appears in the email.
Sub Email_created_Workbook()
Dim OutApp As Object
Dim OutMail As Object
Dim Mess As Object, Recip
Recip = [Sheet1!B28].Value & "; " & [Sheet1!B27].Value
Dim strbody As String
If ActiveWorkbook.Path <> "" Then
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
strbody = "<font size=""3"" face=""Calibri"">" & _
"Hello,<br><br>" & _
"There is a New PO awaiting your approval :<br><B>" & _
ActiveWorkbook.Name & "</B> is created.<br>" & _
"Click on this link to open the file : " & _
"<A HREF=""file://" & ActiveWorkbook.FullName & _
""">Link to Workbook</A>" & _
"<br><br>Regards," & _
"<br><br>Automated Approval System</font>"
On Error Resume Next
With OutMail
.To = Recip
.CC = ""
.BCC = ""
.Subject = ActiveWorkbook.Name
.HTMLBody = strbody
.Display 'or use .Send
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
Else
MsgBox "The ActiveWorkbook does not have a path, Save the file first."
End If
End Sub
The file name does adapt in my e-mail, from PO Template, but will not open.
I believe this will help you with your current issue (closing and reopening your file before sending). I've removed the the two lines of your code where you set the Outlook objects to Nothing. To reopen the current file you can use the OnTime function like so:
Sub Email_created_Workbook()
Dim OutApp As Object
Dim OutMail As Object
Dim Mess As Object, Recip
Recip = [Sheet1!B28].Value & "; " & [Sheet1!B27].Value
Dim strbody As String
If ActiveWorkbook.Path <> "" Then
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
strbody = "<font size=""3"" face=""Calibri"">" & _
"Hello,<br><br>" & _
"There is a New PO awaiting your approval :<br><B>" & _
ActiveWorkbook.Name & "</B> is created.<br>" & _
"Click on this link to open the file : " & _
"<A HREF=""file://" & ActiveWorkbook.FullName & _
""">Link to Workbook</A>" & _
"<br><br>Regards," & _
"<br><br>Automated Approval System</font>"
On Error Resume Next
With OutMail
.To = Recip
.CC = ""
.BCC = ""
.Subject = ActiveWorkbook.Name
.HTMLBody = strbody
.Display 'or use .Send
End With
Application.OnTime Now + TimeValue("00:00:10"), "SendEmail"
ThisWorkbook.Close True 'True= yes, save changes
Else
MsgBox "The ActiveWorkbook does not have a path, Save the file first."
End If
End Sub
Sub SendEmail()
Dim OutApp As Object: Set OutApp = GetObject(, "Outlook.Application") 'Grab current instance of Outlook since we already opened the instance prior to restarting Excel
Dim oInspector As OutApp.Inspector: Set oInspector = OutApp.ActiveInspector
Dim NewMail As OutApp.MailItem: Set NewMail = oInspector.CurrentItem 'Grab currently open New/Compose Mail window
NewMail.Send 'Send Email
End Sub
Let me know if this helps resolve your issue.

Using VBA to send emails based on adjacent conditions

I'm a new VBA user and am trying to accomplish what I've described in the title using the code below.
I think it has something to do with creating dims specifically for cc/bcc/and to, but I'm not quite sure. in one column is a list of emails that have been filtered for based on specific conditions and in the column right next to it is either "" "cc" or "bcc". If it's blank, then it goes into "to" if it's cc" it goes into the .CC field etc. etc.
Sub SendList()
'DIM
Dim olApp As Outlook.Application
Dim olMail As MailItem
Dim CurrFile As String
Dim emailRng As Range, cl As Range
Dim sTo As String
'SET
Set emailRng = ActiveSheet.Range("E3:E100").SpecialCells(xlCellTypeVisible)
For Each cl In emailRng
sTo = sTo & ";" & cl.Value
Next
sTo = Mid(sTo, 2)
Set olApp = New Outlook.Application
Set olMail = olApp.CreateItem(olMailItem)
'UPDATE WORKBOOK BEFORE SENDING
ActiveWorkbook.Save
CurrFile = ActiveWorkbook.Path & "\" & ActiveWorkbook.Name
'Need to find a way to automate to TO CC and BCC
With olMail
.To = sTo
.CC = ""
.BCC = ""
.Subject = "Audit Report XYZ" & " " & "-" & " " & Date
.Body = .Body & "Test" & vbCrLf & "Test2" & vbCrLf & "Test3"
.Attachments.Add "C:\Users\uq050e\Downloads\anyfile.xlsx" 'An audit report
.Display '.Send
End With
Set olMail = Nothing
Set olApp = Nothing
End Sub
It looks like the problem is not with Outlook VBA, but with reading the Excel's content. I'd suggest learning VBA and Excel a bit first, see Getting Started with VBA in Excel 2010.
You can use the Text property of the Range class to get the text for the specified object/cell.

How do I insert a linebreak when sending an email using VBA Access

Using the object "Outlook.Application", I send an e-mail using VBA Access. In the body, I put a string like this:
Email = "Random things" & Chr(13) _
& "More random things" & Chr(13) _
If I show the string Email in a MsgBox it is displayed correctly, but when I send it, the linebreaks are deleted.
I've tried with:
Chr(13)
vbCrLf
vbCr
But all three have the same result:
Try This:
Sub OutlookEmail()
Dim AppOutlook As Outlook.Application
Set AppOutlook = CreateObject("Outlook.application")
Dim Mail As MailItem
Set Mail = AppOutlook.CreateItem(olMailItem)
Dim Email As String
Email = "Random things" & vbNewLine _
& "More random things" & vbNewLine
'Generate Email
Mail.Subject = "Test Subject"
Mail.To = "Test#test.com"
Mail.Body = Email
Mail.Display
Set Mail = Nothing
Set AppOutlook = Nothing
End Sub
Tested it my self appears to work correctly on my PC.
The code below display the email in Outlook. To send, change .Display to .Send
Sub SendDisplayEmail(strEmailFrom As String, strEmailTo As String, strEmailCC As String, strEmailBCC As String, strSubject As String)
Dim OutApp As Object
Dim OutMail As Object
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0) ' olMailItem
Debug.Print ("From: " & strEmailFrom & ", To: " & strEmailTo & ", cc: " & strEmailCC & ", bcc: " & strEmailBCC & ", file: " & xFile)
On Error Resume Next
OutMail
With OutMail
.to = strEmailTo
.CC = strEmailCC
.BCC = strEmailBCC
.Subject = strSubject
'.Body = "Random things" _
' & vbCrLf & vbCrLf & "More random things." _
.BodyFormat = 2 ' olFormatHTML
.HTMLBody = "<html>Random things<br>More random things.</html>"
'.Body = strBody
'.Save
.Display
'.Send 'or use .Display
End With
On Error GoTo 0
Set OutMail = Nothing
Set OutApp = Nothing
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
You can use the HTMLBody (with .BodyFormat = 2) for a nice formated e-mail or .Body for the plain text e-mail. Note that %0D%0A and dont work in HTMLBody because Outlook parse it.

Userform variables to E-mail

I have a Userform which has 3 buttons on it and based on the click the respective text needs to be inserted in the body of the email, for this e-mail the To, CC, Subject, will be taken from Listview box in Sheet1 which inturn extracts the values stored in Sheet2 and paste it in To, CC, Subject of the email.
When i paste the code in the buttonclick () command the variables are not getting passed from the maincode to the userform code where it shows the To, CC and Subject as blanks.
Here's the code:
Sub Worksheet_Activate()
Dim rngCell As Range
ListView41.ListItems.Clear
For Each rngCell In Worksheets("MFRs Contacts").Range("A2:A400")
If Not rngCell = Empty Then
With ListView41.ListItems.Add(, , rngCell.Value)
.ListSubItems.Add , , rngCell.Offset(0, 1).Value
.ListSubItems.Add , , rngCell.Offset(0, 2).Value
End With
End If
Next rngCell
End Sub
Sub ListView41_DblClick()
Dim strName As String
Dim strEmail As String
Dim strEmail1 As String
Dim OutApp As Object
Dim OutMail As Object
Dim Singlepart As String
Dim SigString As String
Dim Signature As String
Dim strbody As String
Dim SigFilename
strName = ListView41.SelectedItem.Text
strEmail = ListView41.SelectedItem.ListSubItems(1).Text
strEmail1 = ListView41.SelectedItem.ListSubItems(2).Text
check = MsgBox("Send e-mail, To : " & strName & " - " & strEmail & "?" & vbNewLine & _
"CC : " & strEmail1, vbYesNo)
If check <> vbYes Then Exit Sub
Singlepart = MsgBox("For Single Part or Multiple Parts ? " & vbNewLine & vbNewLine & _
"Single Part = Yes" & vbNewLine & _
"Multiple Parts = No", vbYesNo)
If Singlepart = vbYes Then
' For Single Part Numbers
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
strbody = "<H3><B>Dear Customer Ron de Bruin</B></H3>" & _
"Please visit this website to download the new version.<br>" & _
"Let me know if you have problems.<br>" & _
"Ron's Excel Page" & _
"<br><br><B>Thank you</B>"
'Signature of User
SigString = Environ("appdata") & _
"\Microsoft\Signatures\Rohith UTAS.htm"
If Dir(SigString) <> "" Then
Signature = GetBoiler(SigString)
Else
Signature = ""
End If
On Error Resume Next
Userform1.Show
'With Outlook
With OutMail
.Display
.To = strEmail
.CC = strEmail1
.BCC = ""
.Subject = strName & "_Request for Product Information"
.HTMLBody = strbody & vbNewLine & Signature
.Display 'or .Display if you want the user to view e-mail and send it manually
End With
Else
Set OutMail = Nothing
Set OutApp = Nothing
End Sub
Can you please help me on this.
Your variables you need to access on your form (I'm assuming strName, strEmail, and strEmail1) only have scope in Sub ListView41_DblClick(). If you need to use them in your form, you'll have to pass them as parameters (my preferred way to do it) or give them global scope.
A UserForm is a class, so you can give it properties like any other class - i.e. in UserForm1:
Private mEmail As String
Public Property Let Email(inputVal As String)
mEmail = inputVal
End Property
Public Property Get Email() As String
Email = mEmail
End Property
Then you would call it like any other object:
Dim nameless_form As UserForm1
Set nameless_form = New UserForm1
nameless_form.Email = strEmail
nameless_form.Show