Batch email from access query

Posted on 2002-05-30
Last Modified: 2012-05-04
I need to query a DB and return a list of email addresses.  Then I'd like to be able to put all those addresses into the "To" field of an email.  
I can see how to send individual mails, but I can't figure out how to build a single mail with many recipients.
Question by:bkosterm
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
LVL 143

Expert Comment

by:Guy Hengel [angelIII / a3]
ID: 7044677
You have of course the problem of your query, but you will also come to a quite small limit of emails in the TO/CC/BCC field.
I suggest that you don't try to put more than 10 recipients automatically...

The question is (as you know how to send individual mails), where is your problem putting more than 1 recipient to the TO field?
LVL 12

Accepted Solution

James Elliott earned 200 total points
ID: 7044708
Try something like this

Dim ol As New Outlook.Application
Dim olMail As Outlook.MailItem
Dim strSubject As String
Dim strMSG As String

strSubject = "Subject goes here"
strMSG = "Dear Person" & vbCrLf & vbCrLf
strMSG = strMSG & "Message Body goes here"

Set olMail = ol.CreateItem(olMailItem)

With olMail
    .To = ""
    '.Attachments.Add "c:\sometextfile.txt"
    '.Attachments.Add "c:\anothertextfile.txt"
    .Subject = strSubject
    .Body = strMSG
    '.Importance = olImportanceHigh
End With

Set olMail = Nothing
Set ol = Nothing

you could then replace the email address above with a variable or number or variables that you would have defined from your query. You would have to be careful of the syntax though. The whole line must be a string but contained within that string must be the ';' symbol between the addresses.

Alternatively you could a loop that ran this script for each mail address in your query. It would take up a lot more resources though. Again you would use a variable for the Email address and just loop the process through for every record in question.

Does this help?



LVL 11

Expert Comment

ID: 7044914
In the past I've had trouble simply adding a semi-colon delimited list of addresses to the Recipents object, so I resorted to using this routine to add the addresses one by one...

Sub AddToRecipients(sToEmail As String, objMailMessage As Outlook.MailItem, objOutlookRecip As Outlook.Recipient)
  '     Purpose: Add a semi-colon delimited list of email address to the To: header
  '  Parameters: sToEmail - the delimited list. Each email address is delimited by a semi-colon
  '              objMailMessage - an initialised MailItem object
  '              objOutlookRecip - the recipient object that recieves the emails addresses
Dim vTemp As Variant
Dim n As Integer
    n = 1
    vTemp = Field(sToEmail, ";", n)
    With objMailMessage
        While Not IsNull(vTemp)
            If bVerifyEmailAddress(CStr(vTemp)) Then
                Set objOutlookRecip = .Recipients.Add(CStr(vTemp))
                objOutlookRecip.Type = olTo
                MsgBox "The email address " & vTemp & "@appears to be invalid.@Please check it and add it manually to the message.", vbInformation, "Email Address Error"
            End If
            n = n + 1
            vTemp = Field(sToEmail, ";", n)
    End With
End Sub

So to use this you first create a MailItem and a Recipients object, build a semi-colon delimited list of email addresses, and then call AddToRecipients.

The above routine uses two other helper functions,

Field() which picks out elemets from a delimited list, and bVerifyEmailAddress() which does what it says.

Here is Field()

Function Field(ByVal strSource As String, strSep As String, intN As Integer) As Variant
'   Returns the Nth element in a delimited list.
'   Input: strSource - the list to search
'             strSep - the delimiter of the list - can be more than one character
'             intN - the ordinal value of the element to be returned
' Null is returned if either string parameter is null, or intN <=0 or
' If the separator string is not found
'Str = Field("Chuck*Roberts","*",1) would return "Chuck".
Dim strResult As String
Dim strSearch As String
Dim I As Long
Dim lSep As Long
Dim lRightChars As Long

    lSep = 0: I = 0
    If IsNull(strSource) Or strSource = "" Or IsNull(strSep) Or strSep = "" Or intN <= 0 Then
        strResult = ""
        strSearch = strSource
        While I < intN
            lSep = InStr(strSearch, strSep)
            If lSep > 0 Then ' we found the delimiter string
                I = I + 1 ' count occurance
                If I = intN Then ' this is the one we want
                    strResult = Left$(strSearch, lSep - 1)
                End If
                ' strip off i'th field
                strSearch = Right(strSearch, Len(strSearch) - (lSep + Len(strSep) - 1))
            Else ' did not find our separator string, so return the remainer of the string if the count is ok
                If I = intN - 1 Then '  we have seen N-1 separator strings, so this is the field we want
                                                ' at the end of the search string
                    I = I + 1 ' to terminate the While loop
                    strResult = strSearch
                Else    ' there were less than N-1 fields in the input to return Null
                    strResult = ""
                    I = intN
                End If
            End If
    End If
    If strResult = "" Then
        Field = Null
        Field = strResult
    End If
End Function

and here is bVerifyEmailAddress()

Function bVerifyEmailAddress(CM_Email As String)
' Verify if email address is valid
    Dim objOutlook As Outlook.Application
    Dim objOutlookMsg As Outlook.MailItem
    Dim objOutlookRecip As Outlook.Recipient
    If Not isblank(CM_Email) Then
        ' Create the Outlook session.
        Set objOutlook = CreateObject("Outlook.Application")
        ' Create the message.
        Set objOutlookMsg = objOutlook.CreateItem(olMailItem)
        With objOutlookMsg
             ' Add the To recipient(s) to the message.
             Set objOutlookRecip = .Recipients.Add(CM_Email)
            ' Resolve each Recipient's name.
            For Each objOutlookRecip In .Recipients
                If Not objOutlookRecip.Resolve = True Then
                    bVerifyEmailAddress = False
                    bVerifyEmailAddress = True
                End If
        End With
        Set objOutlookRecip = Nothing
        Set objOutlookMsg = Nothing
        Set objOutlook = Nothing
        bVerifyEmailAddress = False
    End If
End Function
Salesforce Has Never Been Easier

Improve and reinforce salesforce training & adoption using WalkMe's digital adoption platform. Start saving on costly employee training by creating fast intuitive Walk-Thrus for Salesforce. Claim your Free Account Now


Expert Comment

ID: 7045657
You stated that you dont have a problem creating the email to send it is just creating a list of multiple recipients.  This will work to create the distribution list based on your query.

Private Sub Command6_Click()
'[me.emailaddress] is the individuals email address on my form.
'[me.text4] is just a text box I used to test what would output.
'This works I am using it now for a distribution list and it is simple.

Dim emaillist 'This will be your email list.
DoCmd.GoToRecord , , acFirst 'Locate the first record in a record set.

'I used this next line to tell me when I was at the end of my records.  It works for me.
Do While Me.NewRecord = False

'This adds records email address and will loop through all records until it reaches the last record(new).
emaillist = emaillist & "; " & Me.EmailAddress
DoCmd.GoToRecord , , acNext
emaillist = emaillist & "; " & Me.EmailAddress

'I simply am outputting this to a text box on my form but you could easily put this in you "TO:" recipients.

Me.Text4 = emaillist

End Sub
LVL 12

Expert Comment

ID: 7049003
by now (june 2, 2002) , using the outlook library is pretty much 'asking for trouble', since versions of ms office change more often than Bill Gates changes underware.

Instead i would go for the real job, sent your mails directly via SMTP

In the next link u will find a component u have to register on your comp before u can use it;

if u have trouble using it, just ask away,

LVL 12

Expert Comment

ID: 7049006

hi, welcome to EE (u almost are a dinosaur here)
In many TA (not only the Access TA) it is common practice to only post comments.
That way the Q dont get 'lost' in the 'Locked questions', not very frequently visited by experts, thus decreasing the chance for the questioner to receive the help(s)he needs.

not meant to offend, only to help,


Expert Comment

ID: 7135938
Question dead ?
LVL 54

Expert Comment

ID: 7242268

No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in Community Support that this question is:
 - Answered by: jell
Please leave any comments here within the
next seven days.



Expert Comment

ID: 7269226
Per recommendation, force-accepted.

CS Moderator

Featured Post

Back Up Your Microsoft Windows Server®

Back up all your Microsoft Windows Server – on-premises, in remote locations, in private and hybrid clouds. Your entire Windows Server will be backed up in one easy step with patented, block-level disk imaging. We achieve RTOs (recovery time objectives) as low as 15 seconds.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Phishing attempts can come in all forms, shapes and sizes. No matter how familiar you think you are with them, always remember to take extra precaution when opening an email with attachments or links.
Code that checks the QuickBooks schema table for non-updateable fields and then disables those controls on a form so users don't try to update them.
In Microsoft Access, learn the trick to repeating sub-report headings at the top of each page. The problem with sub-reports and headings: Add a dummy group to the sub report using the expression =1: Set the “Repeat Section” property of the dummy…
With Microsoft Access, learn how to specify relationships between tables and set various options on the relationship. Add the tables: Create the relationship: Decide if you’re going to set referential integrity: Decide if you want cascade upda…

628 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question