send each sheet to each persons via outlook - excel

I have a master sheet and a code to split it into separate sheet based on reviewer names, now i need to send all the splitted sheet to each of the reviewers based on sheet names, example: sheet named raj must be sent to raj#gmail.com, sheet named ravi must be sent to ravi#gmail.com I managed to find a code to send a single sheet via mail, i need help to send all the sheets to respective persons via outlook.
Attaching the code to send a single sheet.
Sub EmailWithOutlook()
Dim oApp As Object
Dim oMail As Object
Dim WB As Workbook
Dim FileName As String
Dim wSht As Worksheet
Dim ShtName As String
Dim CurrDate As String
CurrDate = format(Date, "MM-DD-YY")
Application.ScreenUpdating = False
' Make a copy of the active worksheet
' and save it to a temporary file
Sheets("raj").Activate
ActiveSheet.Copy
Set WB = ActiveWorkbook
FileName = WB.Worksheets(1).Name & " " & CurrDate
On Error Resume Next
Kill "C:\Users\Desktop\workfiles\" & FileName
On Error GoTo 0
WB.SaveAs FileName:="C:\Users\Desktop\workfiles\" & FileName
'Create and show the Outlook mail item
Set oApp = CreateObject("Outlook.Application")
Set oMail = oApp.CreateItem(0)
With oMail
'Uncomment the line below to hard code a recipient
.To = "raj#gmail.com"
'Uncomment the line below to hard code a subject
.Subject = "Subject Line"
'Uncomment the lines below to hard code a body
.body = "Hi Raj" & vbCrLf & vbCrLf & _
"Please find the attached file for work"
.Attachments.Add WB.FullName
.Display
End With
'Delete the temporary file
'WB.ChangeFileAccess Mode:=xlReadOnly
'Kill WB.FullName
'WB.Close SaveChanges:=False
'Restore screen updating and release Outlook
Application.ScreenUpdating = True
Set oMail = Nothing
Set oApp = Nothing
End Sub

You can iterate over all worksheets in the workbook in the following way to compose an email for each recipient individually:
Set oApp = CreateObject("Outlook.Application")
For i = 1 To WB.Sheets.Count
Set oMail = oApp.CreateItem(0)
With oMail
.To = WB.Sheets(i).Name & "#gmail.com"
.Subject = "Subject Line"
'Uncomment the lines below to hard code a body
.body = "Hi Raj" & vbCrLf & vbCrLf & _
"Please find the attached file for work"
.Attachments.Add WB.FullName
.Send
End With
Next i
You can read more about that in the following articles that I wrote for the technical blog:
How To: Create and send an Outlook message programmatically
How To: Fill TO,CC and BCC fields in Outlook programmatically
How to create and show a new Outlook mail item programmatically: C#, VB.NET

Related

How to send one email to list of email addresses in Excel workbook?

I want to send to a list of email addresses in my workbook.
How would I go about that with what I have for the mailing section of my code?
I want to have column R named mailing list and it will send to whatever email addresses are inserted into that column/list all together.
Sub SendReminderMail1()
Dim wb1 As Workbook
Dim wb2 As Workbook
Dim TempFilePath As String
Dim TempFileName As String
Dim FileExtStr As String
Dim OutApp As Object
Dim OutMail As Object
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Set wb1 = ActiveWorkbook
TempFilePath = Environ$("temp") & "\"
TempFileName = "Copy of " & wb1.Name & " " & Format(Now, "dd-mmm-yy h-mm-ss")
FileExtStr = "." & LCase(Right(wb1.Name, Len(wb1.Name) - InStrRev(wb1.Name, ".", , 1)))
wb1.SaveCopyAs TempFilePath & TempFileName & FileExtStr
Set wb2 = Workbooks.Open(TempFilePath & TempFileName & FileExtStr)
wb2.Worksheets(1).Range("A1").Value = "Copy created on " & Format(Date, "dd-mmm-yyyy")
wb2.Save
Set OutApp = CreateObject("Outlook.Application")
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.To = " "
.CC = ""
.BCC = ""
.Subject = "Rotations needed for ."
.Body = "Hey there, equipment needs to be rotated."
.Attachments.Add wb2.FullName
.Display 'or use .Send to send with display proof reading
End With
On Error GoTo 0
wb2.Close savechanges:=False
Kill TempFilePath & TempFileName & FileExtStr
Set OutMail = Nothing
Set OutApp = Nothing
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
MsgBox "Your Automated Email for BP Rotations was successfully ran at " & TimeValue(Now), vbInformation
End Sub
In your code I've you set the recipients fields to empty strings:
With OutMail
.To = " "
.CC = ""
.BCC = ""
Instead, you need to read values from the column R and add recipients for the email. To add recipients I'd recommend using the Recipients collection which can be retrieved using the corresponding property of the MailItem class.
Dim recipients As Outlook.Recipients = Nothing
Set recipients = mail.Recipients
' now we add new recipietns to the e-mail
recipientTo = recipients.Add("Eugene")
recipientTo.Type = Outlook.OlMailRecipientType.olTo
recipientCC = recipients.Add("Dmitry")
recipientCC.Type = Outlook.OlMailRecipientType.olCC
recipientBCC = recipients.Add("eugene.astafiev#somedomain.com")
recipientBCC.Type = Outlook.OlMailRecipientType.olBCC
recipients.ResolveAll()
Read more about that in the How To: Fill TO,CC and BCC fields in Outlook programmatically article.
Mail Merge not your cup of tea huh...
Maybe what you need is a Do while Loop where it references a cell in a Table of people, then moves down each step till the E-mail is blank just chugging through Row after Row of E-mails driving that sweet CPU usage up.
Like a user programmed Mail Merge but in Excel and not in a Word Processor... Like Mail Merge... In Word, but not in Word, In Excel In VBA...

Attaching PDF file to Outlook email

I would like to add a .pdf file in my Outlook email, which is sent via VBA Excel.
My full Excel code looks pretty much like this:
Sub Confirmationemail()
MsgBox ("The confirmation email will be sent now")
Dim OutlookApp As Outlook.Application
Dim OutlookMail As Outlook.MailItem
Dim fs As Worksheet, bs As Worksheet
Dim Filename As String, Name As String, Name2 As String, Name3 As String, Reason As String
Dim Cost As String, PathFileName As String
Dim linecount2 As Long
ChDir ThisWorkbook.Path & "\"
Set fs = Sheets("Frontsheet")
Set bs = Sheets("BoM")
linecount2 = 1
Name = fs.Range("D10")
Name2 = fs.Range("D18")
Name3 = fs.Range("D38")
If fs.Range("D38").Value = 3 Then
Reason = fs.Range("K8")
ElseIf fs.Range("D38").Value = 4 Then
Reason = fs.Range("P4")
Else
Reason = fs.Range("K4")
End If
Filename = Name & "_" & Name2
Set OutlookApp = New Outlook.Application
Set OutlookMail = OutlookApp.CreateItem(olMailItem)
With OutlookMail
.BodyFormat = olFormatHTML
.Display
.HTMLBody = "The job is ready. See the PDF version in the attachment"
.To = "xxx#xxx.co.uk; yyy#yyy-is.co.uk "
PathFileName = ThisWorkbook.Path & "\" & Filename & ".pdf"
.CC = "zzz#z-is.co.uk; www#wx-c.co.uk;"
.BCC = "yxks#ug.co.uk"
.Subject = Filename & "- Audit"
'.Attachments.Add PDFFile
myattachments.Add PathFileName
'.Attachments.Add Application.ActiveWorkbook.FullName
'.Send
End With
End Sub
The best hint I found:
How to attach exported pdf file to Outlook mail using Excel VBA? but it refers to attaching the already exported PDF document. Incorporating some pieces of code was unsuccessful.
Some solution here:
Attach PDF and send email via Outlook but it refers to the specified cells only.
Other hints I found:
Excel VBA attaching print area as PDF.
Attach both pdf and excel files to an email on single click in VBA.
https://answers.microsoft.com/en-us/msoffice/forum/msoffice_excel-mso_winother-mso_2010/attaching-a-pdf-file-in-vba-generated-email-in/527de6b4-66e6-4aa5-85b8-267a59ea6a7f
It’s not myattachments.Add PathFileName it should be .Attachments.Add PathFileName
See Attachments.Add method (Outlook)

Send sheet via email

I have a workbook called Status report which contains several sheets. I need to send sheet8 (Called tables) via email.
I generated code but it is giving me errors.
Location of file is on desktop.
Option Explicit
Sub EmailWithOutlook()
Dim oApp As Object
Dim oMail As Object
Dim WB As Workbook
Dim FileName As String
Dim wSht As Worksheet
Dim shtName As String
Application.ScreenUpdating = False
ActiveSheet.Copy
Set WB = ActiveWorkbook
FileName = WB.Worksheets(1).Name
Kill "C:\Users\Default\Desktop" & "Status report.xlsm"
On Error GoTo 0
WB.SaveAs FileName:="C:\Users\Default\Desktop" & "Status report.xlsm"
Set oApp = CreateObject("Outlook.Application")
Set oMail = oApp.CreateItem(0)
With oMail
.To = "sleepyyx#gmail.com"
.Subject = "Test workbook"
.body = "Hello, could you please check workbook" & vbCrLf & vbCrLf & _
"I attached you file"
.Attachments.Add WB.FullName
.Display
End With
WB.ChangeFileAccess Mode:=xlReadOnly
Kill WB.FullName
WB.Close SaveChanges:=False
Application.ScreenUpdating = True
Set oMail = Nothing
Set oApp = Nothing
End Sub
Before you kill a File in Kill "C:\Users\Default\Desktop\" & "Status report.xlsm", you need to check if the file exists :
~~> Check if file exists
If Dir("C:\Users\Default\Desktop\" & "Status report.xlsm") <> "" Then
Kill "C:\Users\Default\Desktop\" & "Status report.xlsm"
End If
And you forget the backslash
You probably are trying to use Filename from the cell.
Consider using a variable for consistency and in case it changes, and make sure you include the backslash between the path and filename.
FileName = WB.Worksheets(1).Name
Dim sFullFile As String
sFullFile = "C:\Users\Default\Desktop\" & FileName
If Dir(sFullFile) <> "" Then Kill sFullFile
WB.SaveAs FileName:=sFullFile
Another thing to note is that if you are saving it as an XLSM then the original format also has to be XLSM, or the SaveAs will error if you don't specify the File Format.
XlFileFormat Enumeration Documentation

How to insert a table after body of e-mail and before signature?

I am using a below code that is pasting a table from excel to the outlook file. However, right now the table is pasted on the very bottom of the email - after the signature.
What I would like to achieve is to have the table inserted after a word "region." and before "Regards" - so before signature.
Dim FileExtStr As String
Dim FileFormatNum As Long
Dim Sourcewb As Workbook
Dim Destwb As Workbook
Dim sh As Worksheet
Dim DateString As String
Dim FolderName As String
Dim myOutlook As Object
Dim myMailItem As Object
Dim mySubject As String
Dim myPath As String
Dim i As Integer
With Application
.ScreenUpdating = False
.EnableEvents = False
.Calculation = xlCalculationManual
End With
'Prompt for Email Subject
Set outlApp = CreateObject("Outlook.Application")
weeknumber = "Week " & WorksheetFunction.WeekNum(Now, vbMonday)
'mySubject = InputBox("Subject for Email")
For i = 2 To 3
region = Sheets("Sheet1").Cells(i, 5).Value
mySubject = "Overdue Milestones | " & weeknumber & " | " & region
'Copy every sheet from the workbook with this macro
Set Sourcewb = ActiveWorkbook
'Create new folder to save the new files in
DateString = Format(Now, "yyyy-mm-dd hh-mm-ss")
FolderName = "C:\Users\mxr0520\Desktop\Ignite Reports\Milestones\" & weeknumber
If i < 3 Then
MkDir FolderName
Else
End If
'Copy every visible sheet to a new workbook
Set sh = Sheets(region)
'If the sheet is visible then copy it to a new workbook
If sh.Visible = -1 Then
sh.Copy
'Set Destwb to the new workbook
Set Destwb = ActiveWorkbook
'Determine the Excel version and file extension/format
With Destwb
If Val(Application.Version) < 12 Then
'You use Excel 97-2003
FileExtStr = ".xls": FileFormatNum = -4143
Else
'You use Excel 2007-2016
If Sourcewb.Name = .Name Then
MsgBox "Your answer is NO in the security dialog"
GoTo GoToNextSheet
Else
FileExtStr = ".xlsx": FileFormatNum = 51
End If
End If
End With
'Change all cells in the worksheet to values if you want
If Destwb.Sheets(1).ProtectContents = False Then
With Destwb.Sheets(1).UsedRange
.Cells.Copy
.Cells.PasteSpecial xlPasteValues
.Cells(1).Select
End With
Application.CutCopyMode = False
End If
'Save the new workbook, email it, and close it
'Set otlNewMail = outlApp.CreateItem(myMailItem)
Set OutLookApp = CreateObject("Outlook.application")
Set OutlookMailitem = OutLookApp.CreateItem(0)
With OutlookMailitem
.display
End With
Signature = OutlookMailitem.htmlbody
With Destwb
.SaveAs FolderName _
& "\" & Destwb.Sheets(1).Name & FileExtStr, _
FileFormat:=FileFormatNum
End With
myPath = ActiveWorkbook.path & "\" & ActiveWorkbook.Name
With Destwb
.Close False
End With
With OutlookMailitem
.Subject = mySubject
.To = Sheets("Sheet1").Cells(i, 6)
.CC = Sheets("Sheet1").Cells(i, 7)
.htmlbody = "Dear All," & "<br>" _
& "<br>" _
& "Attached please find the list of milestones that are <b>overdue</b> and <b>due in 14 days</b> for " & region & "." & "<br>" & "<br>" & "Regards," & "<br>" _
& "Marek" _
& Signature
.Attachments.Add myPath
Worksheets("Summary").Range("A1:E14").Copy
Set vInspector = OutlookMailitem.GetInspector
Set weditor = vInspector.WordEditor
wEditor.Application.Selection.Start = Len(.body)
wEditor.Application.Selection.End = wEditor.Application.Selection.Start
wEditor.Application.Selection.Paste
.display
End With
Set OutlookMailitem = Nothing
End If
thank you for help in advance!
Probably easiest to do this by creating an .oft (Outlook Email Template) with the message body and a placeholder for "region" and the table. Create the template without a signature, it will be added automatically per your Outlook user settings, later. I create a template like this, and save as .oft:
Then simply create the new mailitem with Set OutlookMailitem = OutlookApp.CreateItemFromTemplate({path to your template.oft}), replace the "region" placeholder, and copy/paste the table to the table placeholder's location.
Option Explicit
Sub foo()
Dim objOutlook As Outlook.Application
Dim objMsg As Outlook.MailItem
Dim wdDoc As Word.Document
Dim tblRange As Word.Range
Dim region As String
' define your Region, probably this is done in a loop...
region = "Region 1"
Set objOutlook = CreateObject("Outlook.Application")
' Create email from the template file // UPDATE WITH YOUR TEMPLATE PATH
Set objMsg = objOutlook.CreateItemFromTemplate("C:\path\to\your\template.oft")
objMsg.Display
Set wdDoc = objOutlook.ActiveInspector.WordEditor
' replace placeholder with region:
wdDoc.Range.Find.Execute "{{REGION PLACEHOLDER}}", ReplaceWith:=region
' in my template, paragraph 5 is the table placeholder, modify as needed:
Set tblRange = wdDoc.Range.Paragraphs(5).Range
tblRange.Text = "" ' remove the placeholder text
' copy the Excel table // modify to refer to your correct table/range
Sheet1.ListObjects(1).Range.Copy
' paste the table into the email
tblRange.PasteExcelTable False, False, False
End Sub
As you can see, the final email contains my default signature (which was not part of the template.oft file).
You can use the following properties to customize the message body:
Body - a string representing the clear-text body of the Outlook item.
HTMLBody - a string representing the HTML body of the specified item.
The Word Editor. The WordEditor property of the Inspector class returns an instance of the Word Document which represents the message body. You can find all these ways described in the Chapter 17: Working with Item Bodies in MSDN.
The Outlook object model doesn't provide any property or method for detecting signatures. You parse the message body and try to find such places.
However, when you create a signature in Outlook, three files (HTM, TXT and RTF) are created in the following folders:
Vista and Windows 7/8/10:
C:\Users\<UserName>\AppData\Roaming\Microsoft\Signatures
Windows XP:
C:\Documents and Settings\<UserName>\Application Data\Microsoft\Signatures
Application Data and AppData are hidden folders, change the view in the Windows explorer so it shows hidden files and folders if you want to see the files.
So, you read the content of these files and try to find the corresponding content in the message body. Note, users may type a custom signature in the end of emails.

On close Excel updated file send email or skype message using VBA

I need Excel VBA code in such way that whenever I close and updated Excel file (data must have been updated in the file), send a Skype Message or Email to other people stating that file was updated.
I'm looking for a VBA code where I can achieve this.
Important: The code is for Skype or Mozilla Thunderbird.
Here is a good article with VBA code on how to send an email when a Specific Excel Worksheet Is Updated.
Here is the code being used:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim nConfirmation As Integer
Dim objNewWorkbook As Excel.Workbook
Dim objNewWorksheet As Excel.Worksheet
Dim objOutlookApp As Object
Dim objMail As Object
nConfirmation = MsgBox("Do you want to send an email notification about the sheet updating now?", vbInformation + vbYesNo, "Mail Sheet Updates")
If nConfirmation = vbYes Then
ActiveWorkbook.Save
On Error Resume Next
Set objOutlookApp = CreateObject("Outlook.Application")
Set objMail = objOutlookApp.CreateItem(olMailItem)
'Change the email details as per your needs
With objMail
.To = "test#datanumen.com"
.Subject = "Email Notifying Sheet Updates"
.Body = "Hi," & vbCrLf & vbCrLf & "The worksheet " & Chr(34) & ActiveWorkbook.Sheets(1).Name & Chr(34) & " in this Excel workbook attachment is updated."
'Attach this workbook
.Attachments.Add ActiveWorkbook.FullName
.Send
End With
End If
End Sub
It can be useful as a starting point.

Resources