Hi am trying to automate email from word through mail merge
right now my code is working but I can't able to add an email body while sending an email
please help me to sort it out
here is my code below
Private Sub Send_EmailUsingMaiIMerge_Click()
Dim Wd_App As Word.Application
Dim Wd_Doc As Word.Document
Dim Wd_MailMerge As Word.MailMerge
Dim Data_Path As String
Dim Wd_MMFNs As Word.MailMergeFieldNames
Dim Wd_MMFN As Word.MailMergeFieldName
Dim Wd_MMDFs As Word.MailMergeDataFields
Dim Wd_MMDF As Word.MailMergeDataField
Set Wd_App = Application
Set Wd_Doc = Wd_App.Documents.Open("template.docx")
Set Wd_MailMerge = Wd_Doc.MailMerge
'Get Data Path'
Data_Path = "Sheet.xlsx"
'Give mail merge type'
Wd_MailMerge.MainDocumentType = wdFormLetters
'Lets connect to data source'
Wd_MailMerge.OpenDataSource Name:=Data_Path, SQLStatement:="SELECT * FROM [Sheet1$]"
'Lets Email using Mail Merge'
'Outlook must be open and you are connected to the internet'
Dim TotalCnt As Integer
For TotalCnt = 1 To Wd_MailMerge.DataSource.RecordCount
Wd_MailMerge.DataSource.ActiveRecord = TotalCnt
Wd_MailMerge.DataSource.FirstRecord = TotalCnt
Wd_MailMerge.DataSource.LastRecord = TotalCnt
'Target Mail Address Column'
Wd_MailMerge.MailAddressFieldName = "Email"
'Add Attachment'
Wd_MailMerge.MailAsAttachment = True
'Add Subject'
Wd_MailMerge.MailSubject = "Email Subject Test"
'Add Destination'
Wd_MailMerge.Destination = wdSendToEmail
'Execute'
Wd_MailMerge.Execute False
Next TotalCnt
Wd_Doc.Close False
Set Wd_Doc = Nothing
End Sub
Using this code i can able to send bulk emails but it's getting sent without any email body i want to add more clarification before sending
please help me with a solution to add an email body or is there any other approach to archive my requirements
Thank you very much in advance
On the add attachment module just set it to False then it will send as the body of the email
'Target Mail Address Column'
Wd_MailMerge.MailAddressFieldName = "Email"
'Add Attachment'
Wd_MailMerge.MailAsAttachment = False
'Add Subject'
Wd_MailMerge.MailSubject = "Email Subject Test"
'Add Destination'
Wd_MailMerge.Destination = wdSendToEmail
Related
when CDO.message (SMTP server) VBA code is run it checks if that gmail ID (from which we are sending email) is linked with the current system or not. If it is run on a new system where we never logged in with that gmail id then it gives sever failing error and email is not sent. So I want ask some other way with code (may be gmail api) which does not check for system's link with gmail ID.
BELOW IS THE CODE THAT I AM USING
Dim iMsg As Object
Dim iConf As Object
Dim strbody As String
Dim Flds As Variant
Dim email As String
Dim pass As String
Dim CN As String
Dim OS As String
Set iMsg = CreateObject("CDO.Message")
Set iConf = CreateObject("CDO.Configuration")
iConf.Load -1
Set Flds = iConf.Fields
With Flds
.Item("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = 1
.Item("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1
.Item("http://schemas.microsoft.com/cdo/configuration/sendusername") = FF
.Item("http://schemas.microsoft.com/cdo/configuration/smtpaccountname") = "abcd"
.Item("http://schemas.microsoft.com/cdo/configuration/sendpassword") = DD
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = "smtp.gmail.com"
.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 465
.Update
End With
With iMsg
Set .Configuration = iConf
.To = FF
.CC = ""
.BCC = ""
.From = """from"" <Reply#something.nl>"
.Subject = UN & " C1 LOGGED IN"
.TextBody = "COMPUTER NAME IS -" & CPN & ", USERNAME NAME IS -" & UN & ", COMPUTER ID IS -" & sAns
.Send
End With
Set iMsg = Nothing
Set iConf = Nothing
Set Flds = Nothing
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Solution
Apps Script allows you to get information from Spreadsheets and other Google Documents and be able to use it to then send emails using its Gmail services under certain conditions met on these Spreadsheets for instance.
The following example is a simplification of your scenario where if two numbers / values do not match then you send an email to notify that the system has been run with another device. Below is the code with self-explanatory comments and an image representing the Spreadsheet I am using for this example.
function myFunction() {
// Get the sheet we will be using
var ss = SpreadsheetApp.getActive().getSheetByName('Sheet1');
// get the values of the range that contains the content
// flat is used to get the 2D array returned by getValues() into a simple
// 1D array with these values
var content = ss.getRange('A1:A3').getValues().flat();
// get the values of the range that contains the condition
var condition1 = ss.getRange('B1:B3').getValues().flat();
var condition2 = ss.getRange('C1:C3').getValues().flat();
// get the values of the range that contains the email address
var email = ss.getRange('D1:D3').getValues().flat();
// iterate over all the values of the content column
for(i=0;i<content.length;i++){
// if the column B and C have different values in the row
if(condition1[i]!=condition2[i]){
// send emails with the appropiate properties
GmailApp.sendEmail(email[i], 'Generated email', content[i]);
}
}
}
Resources used: Gmail App and SpreadsheetApp
I hope this has helped you. Let me know if you need anything else or if you did not understood something. :)
So I have multiple mailboxes under my Outlook account and I am trying to get them to generate reply template based on the mailbox I am replying from (one is private, one is shared). I have tried to base the condition on SenderName and SenderEmailAddress, but to no avail (reply email gets generated with the contents of the previous email retrieved but the text I intend to put in front of it is not there; the cause is that the value of oReply.SenderEmailAddress is empty as Else clause will write the stuff as intended).
(and yes, there are snippets from code enabling reply with attachments)
Sub ReplyWithAttachments()
Dim oReply As Outlook.MailItem
Dim oItem As Object
Dim sSignature As String
Set oItem = GetCurrentItem()
If Not oItem Is Nothing Then
Set oReply = oItem.Reply
If oReply.SenderEmailAddress = "mailbox.private#something.com" Then
sSignature = "Hello and welcome!"
ElseIf oReply.SenderEmailAddress = "mailbox.shared#something.com" Then
sSignature = "Go to hell!"
End If
CopyAttachments oItem, oReply
oReply.HTMLBody = sSignature & oReply.HTMLBody
oReply.Display
oItem.UnRead = False
End If
Set oReply = Nothing
Set oItem = Nothing
End Sub
Edit:
so I managed to get somewhere with
Set oReply = oItem.Reply
sMailBox = oReply.Sender.GetExchangeUser.Address
If sMailBox = "mailbox.private#something.com" Then
sSignature = "whatever"
ElseIf sMailBox = "mailbox.shared#something.com" Then
sSignature = "bla bla bla"
Else
sSignature = "Something"
The code works as intended for the shared mailbox but for the private one, it errors out with Object variable or With block variable not set pointing to .Sender
sMailBox = oReply.Sender.GetExchangeUser.Address
I have something that I use to get sender email (as its dependent on your email exchange)
Dim strSendersEmailAddress As String
If oItem.SenderEmailType = "EX" Then
strSendersEmailAddress = oItem.Sender.GetExchangeUser.PrimarySmtpAddress
Else
strSendersEmailAddress = oItem.SenderEmailAddress
End If
You will have to get the email address before you Set oReply = oItem.Reply
My VBA experience is incredibly limited.I have created basic macros for excel primarily by frankensteining multiple macros I find online together.
Here's what I am looking to do. Every morning I send out an email to a list of 200 customers, I open the new message from a list and the message auto populates (as it is a signature). Currently I then go through all these emails and add my subject and BCC. Could I possibly create a macro to open all of these emails, add my BCC, add my subject, and then send the emails.
Any and all help is much appreciated.
The following code defines an instance of Outlook.Application, and sets up a MailItem ready for sending. It uses a Dictionary object called EmailData to hold the various bits of info to populate To, BCC etc but those can be replaced with your own strings etc. I've pulled this from a function I wrote and made it a little more generic:
Public Function OL_SendMail()
Dim bOpenedOutlook, sComputer, iLoop, iAccount, sAttachArray, sAttachment
bOpenedOutlook = False
sComputer = "."
Dim oWMIService : Set oWMIService = GetObject("winmgmts:\\" & sComputer & "\root\cimv2")
Dim colItems : Set colItems = oWMIService.ExecQuery ("Select * from Win32_Process Where Name = 'outlook.exe'")
Dim oOutlook : Set oOutlook = CreateObject("Outlook.Application")
Dim oNamespace : Set oNamespace = oOutlook.GetNamespace("MAPI")
If colItems.Count = 0 Then
' Outlook isn't open, logging onto it...
oNamespace.Logon "Outlook",,False,True
bOpenedOutlook = True
End If
Dim oFolder : Set oFolder = oNamespace.GetDefaultFolder(olFolderInbox)
If EmailData("SendFrom") = "" Then
' default to first email account the user has access to
iAccount = 1
Else
' Checking to see if the account to send from is accessible by this user...
iAccount = 0
For iLoop = 1 To oOutlook.Session.Accounts.Count
If UCase(Trim(oOutlook.Session.Accounts.Item(iLoop))) = UCase(Trim(EmailData("SendFrom"))) Then
iAccount = iLoop
Exit For
End If
Next
If iAccount = 0 Then
sErrorMsg = "Cannot send email from specified account: " & EmailData("SendFrom") & " as this user doesn't appear to have access to it in Outlook!"
OL_SendMail = False
Exit Function
End If
End If
Dim oMailItem : Set oMailItem = oOutlook.CreateItem(olMailItem)
With oMailItem
Set .SendUsingAccount = oOutlook.Session.Accounts.Item(iAccount)
.To = EmailData("To")
.CC = EmailData("CC")
.BCC = EmailData("BCC")
.Subject = EmailData("Subject")
.Body = EmailData("Body")
sAttachArray = Split(EmailData("AttachmentPaths"), ";")
For Each sAttachment In sAttachArray
.Attachments.Add(sAttachment)
Next
.Recipients.ResolveAll
.Display ' debug mode - uncomment this to see email before it's sent out
End With
'Mail Item created and ready to send
'oMailItem.Send ' this is commented out so the mail doesn't auto send, allows checking of it!!
Set oMailItem = Nothing
Set oNamespace = Nothing
If bOpenedOutlook Then
'oOutlook.Quit
End If
Set oOutlook = Nothing
Set colItems = Nothing
Set oWMIService = Nothing
OL_SendMail = True
End Function
Here is my current setup...
I have an Access project tracking database with project description values (example: Project_ID) and I have a button "Create Email" which I've successfully gotten to open Outlook, pick an Outlook draft, and automatically generate the appropriate subject line.
However, I have no clue where to start on this next step. Any help is appreciated!
I would like the Outlook email to have dynamic fields that are linked to the fields in my Access database. I'm not even sure if I should be trying to code in Access or in Outlook for this step!
Example of what I want:
NAME,
Attached are your documents for:
Project_ID Project_Name Project_Type <--Values from my Access
database
Sincerely,
my signature
you should code in MS Access.
a pseudo code would be:
Read all values from your access table
create outlook object, mail object
Open outlook mail and add subject, content, attachments
send or leave it to the employee to send
call this like
send_email_message "to#to.to","","","Email subject","Add your email content/body like project id= &field1, project name = field2 and so on"
you can attach more than one file just join the document name with a ";" delimiter. like
"C;\file1.txt;c:\File2.txt"
here a sending email function:
this function uses outlook objects (import them in reference)
or change it to late binding by vba.createobject("outlook.application")
Function SEND_EMAIL_MESSAGE(mTo As String, mCC As String, mBC As String, mSubject As String, mBody As String, Optional useOwnSignature As Boolean = False, Optional DisplayMsg As Boolean = False, Optional isHTML As Boolean = False, Optional AttachmentPath = "") As Boolean
'---------------------------------------------------------------------------------------
' Procedure : SEND_EMAIL_MESSAGE
' Author : KRISH KM
' Date : 01/09/2013
' Purpose : Send emails using outlook
'---------------------------------------------------------------------------------------
'
' Please check the reference for Microsoft Outlook 14.0 object library for outlook 2010.
Dim oAPP As Outlook.Application
Dim oMail As Outlook.MailItem
Dim oAPPAttach As Outlook.Attachment
Dim mSignature As String
On Error GoTo ERROR_EMAIL
' Create the Outlook session.
Set oAPP = New Outlook.Application
' Create the message.
Set oMail = oAPP.CreateItem(olMailItem)
With oMail
' Add the To recipient(s) to the message.
.to = mTo
.cc = mCC
.BCC = mBC
.Subject = mSubject
If useOwnSignature Then .BodyFormat = olFormatHTML
.Display
If useOwnSignature Then
If isHTML Then
mSignature = .HTMLBody
.HTMLBody = mBody & mSignature
Else
mSignature = .body
.body = mBody & mSignature
End If
Else
.body = mBody
End If
' Add attachments to the message.
If Not IsMissing(AttachmentPath) Then
Dim mFiles() As String
If (VBA.Right(AttachmentPath, 1)) <> ";" Then AttachmentPath = AttachmentPath & ";"
mFiles = VBA.Split(AttachmentPath, ";")
Dim i As Integer
For i = 0 To UBound(mFiles) - 1
If Not mFiles(i) = "" Then .Attachments.Add (mFiles(i)) 'Set oAPPAttach = .Attachments.Add(mFiles(i))
Next i
End If
' Should we display the message before sending?
If DisplayMsg Then
.Display
Else
.Send
End If
End With
SEND_EMAIL_MESSAGE = True
EXIT_ROUTINE:
On Error GoTo 0
Set oAPP = Nothing
Set oMail = Nothing
Exit Function
ERROR_EMAIL:
SEND_EMAIL_MESSAGE = False
GoTo EXIT_ROUTINE
End Function
I have created a rule that executed when outlook receives an mail and it will create the appointment on outlook calendar. In that I need to get the date and time mentioned in the mail as the appointment date.
Sub NewMeetingRequestFromEmail(email As MailItem)
Dim app As New Outlook.Application
Dim meetingRequest As AppointmentItem
Set meetingRequest = app.CreateItem(olAppointmentItem)
meetingRequest.Categories = email.Categories
meetingRequest.Body = email.Body
meetingRequest.Subject = email.Subject
meetingRequest.Location = email.Subject
meetingRequest.Start = DateSerial(Year(Now), Month(Now), Day(Now) + 1) + #10:00:00 AM#
meetingRequest.Duration = 60
meetingRequest.ReminderMinutesBeforeStart = 45
meetingRequest.ReminderSet = True
Dim attachment As attachment
For Each attachment In email.Attachments
CopyAttachment attachment, meetingRequest.Attachments
Next attachment
Dim recipient As recipient
Set recipient = meetingRequest.Recipients.Add(email.SenderEmailAddress)
recipient.Resolve
For Each recipient In email.Recipients
RecipientToParticipant recipient, meetingRequest.Recipients
Next recipient
Dim inspector As inspector
Set inspector = meetingRequest.GetInspector
'inspector.CommandBars.FindControl
inspector.Display
meetingRequest.Save
End Sub
Private Sub RecipientToParticipant(recipient As recipient, participants As Recipients)
Dim participant As recipient
If LCase(recipient.Address) <> LCase(Session.CurrentUser.Address) Then
Set participant = participants.Add(recipient.Address)
Select Case recipient.Type
Case olBCC:
participant.Type = olOptional
Case olCC:
participant.Type = olOptional
Case olOriginator:
participant.Type = olRequired
Case olTo:
participant.Type = olRequired
End Select
participant.Resolve
End If
End Sub
Private Sub CopyAttachment(source As attachment, destination As Attachments)
On Error GoTo HandleError
Dim filename As String
filename = Environ("temp") & "\" & source.filename
source.SaveAsFile (filename)
destination.Add (filename)
Exit Sub
HandleError:
Debug.Print Err.Description
End Sub
The Outlook object model provides three main ways for working with item bodies:
Body.
HTMLBody.
The Word editor. The WordEditor property of the Inspector class returns an instance of the Word Document which represents the message body.
See Chapter 17: Working with Item Bodies for more information.