Solved

Looping email with personalized attachment - Two issues

Posted on 2015-01-22
3
156 Views
Last Modified: 2015-01-27
I'm using VBA code to loop through 'TblEmailAddresses' which is supposed to send a report to each user in the table.  The first step (I haven't yet gotten to the attachment really) is to send the email to each user.  The code below actually outputs a singular report with each user's name as a suffix.  It's ironic that the report name loops (as the attachment suffix) but the '.To' doesn't loop.  That is
      goal #1 - send multiple emails to multiple users.  (It is sending multiple emails but all to the same user.)
      goal #2 - attach a singular report with underlying query personalized for the looped user.  So that's really the same report with different data therein.

Please review the code and help me to loop .To correctly.  If you have time and think it appropriate (extra credits :)), please provide ideas of how to make one report work for each user.  Do I need multiple reports?  There are only nine users but I figure there must be something more streamlined with the use of code.  

If I should ask #2 in a separate question, that's okay too.  Thanks.

Dim MailOutLook As Outlook.MailItem
     Set appOutLook = CreateObject("Outlook.Application")
     Set MailOutLook = appOutLook.CreateItem(olMailItem)
Dim ContactEM As String
Dim SourceTable As String
    Set db = CurrentDb
    Set rstTables = db.OpenRecordset("TblEmailAddresses")

Do While Not rstTables.EOF
FileName = "H:\UnApprovedDetailedHours_Signoff_" & rstTables!Contact & ".pdf"
DoCmd.OutputTo acOutputReport, "RptEmployeeUnApprovedHrsEmail_HRSignoff", acFormatPDF, "H:\UnApprovedDetailedHours_Signoff.pdf", False, ""

Name "H:\UnApprovedDetailedHours_Signoff.pdf " As FileName  'Name "C:\WINDOWS\UnApprovedDetailedHours_Signoff.pdf " As FileName
            Set appOutLook = CreateObject("Outlook.Application")
            Set MailOutLook = appOutLook.CreateItem(olMailItem)
            With MailOutLook
            .BodyFormat = olFormatHTML
            .To = DLookup("EmailAddress", "TblEmailAddresses", rstTables!Contact)
            .Subject = "Unapproved Pay Hours Signoff"
            .HTMLBody = "Attached is a report that provides details of unapproved but paid hours for the current pay. " & _
            "Please sign, scan and return the report to Payroll@carefirst.com " & _
            "If you have any questions about this report, please call Bill Smith (111-222-7777)." & "<BR>" & "<BR>" & "<BR>" & "<BR>" & _
            "Thanks," & "<BR>" & "<BR>" & _
            "Bill Smith" & "<BR>" & _
            "(111) 222-7777"
            .Attachments.Add "H:\UnApprovedDetailedHours_Signoff_" & rstTables!Contact & ".pdf"
            .Close 0 '0 = olSave
            End With
            rstTables.MoveNext
        Set MailOutLook = Nothing
        Kill ("H:\UnApprovedDetailedHours*.pdf")
    Loop
0
Comment
Question by:CFMI
3 Comments
 
LVL 74

Expert Comment

by:Jeffrey Coachman
ID: 40565598
Can you simplify your question here? (perhaps using something simple like Customers and orders)
I have_________
I need to send____________, to___________

Is your goal here to send a few custom PDF's (filtered for that particular person), to each individual person?
for example: each user will get 1 email with 3 PDf's
...Then you can tr something like the attached file:
Access-EEQ27816383EmailMultipleIndividua
0
 
LVL 20

Accepted Solution

by:
GrahamMandeno earned 500 total points
ID: 40565791
Hi Bill (?)

Your main problem with #1 is in this line:
            .To = DLookup("EmailAddress", "TblEmailAddresses", rstTables!Contact)

The third argument of DLookup should be a valid expression for a SQL WHERE clause.  This would be something like:
          "Contact='" & rstTables!Contact & "'"

However, you don't need DLookup at all, because you already have TblEmailAddresses open, and positioned on the desired record!  All you need is this:
            .To = rstTables!EmailAddress

#2 is going to present you with a problem, because the OutputTo method does not allow for a filter or WHERE condition on the report.  Therefore, ALL the contacts will get the full report showing ALL the Unapproved Pay Hours Signoff information for ALL the other contacts as well as their own.

The trick is to open the report hidden, with only the information pertaining to the current contact, and then use OutputTo to export it as a PDF:

FileName = "H:\UnApprovedDetailedHours_Signoff_" & rstTables!Contact & ".pdf"
DoCmd.OpenReport "RptEmployeeUnApprovedHrsEmail_HRSignoff", acViewPreview, , _
      "ContactID=" rstTables!ContactID, acHidden
DoCmd.OutputTo acOutputReport, "RptEmployeeUnApprovedHrsEmail_HRSignoff", _
       acFormatPDF, FileName, False, ""

Open in new window


A few other comments on your code:
You are setting both appOutlook and MailOutlook both inside and outside the loop.  appOutlook needs to be set only once, outside the loop, and MailOutlook needs to be set for each message, inside the loop.
there is no need to export the PDF as a "Standard" name and then rename the file - just export it as the file with the contact name as above
I understand you are testing at the moment, but when you're happy with the code you will probably want to replace .Close 0 with .Send
Be sure to close rstTables and set appOutlook to Nothing before you exit the procedure

Good luck!
Graham Mandeno [Access MVP 1996-2015]
0
 
LVL 1

Author Closing Comment

by:CFMI
ID: 40567027
You guys are the best!   After changing  .To = rstTables!EmailAddress, #1 was resolved.  Then I added a table to be used for the report.  I looped through a 'strSql' which added only the corresponding data for each iteration.  So the code looked like this:

Do While Not rstTables.EOF
DoCmd.OpenQuery "qDel_tblCF_EmpUnapprHrs_Signoff", acViewNormal, acEdit

     strSql = "INSERT INTO tblCF_EmpUnapprHrs_Signoff ( [Fields])" & _
        "SELECT [Fields]" & _
        "From [Tables]" & _
        "WHERE ((([Field])= " & Chr(34) & rstTables!SeniorVP & Chr(34) & ") AND ((rstTables!.[Field])<>'Y'));"

FileName = "H:\UnApprovedDetailedHours_Signoff_" & rstTables!Contact & ".pdf"
DoCmd.RunSQL strSql
Debug.Print

DoCmd.OutputTo acOutputReport, "RptEmployeeUnApprovedHrsEmail_HRSignoff", acFormatPDF, "H:\UnApprovedDetailedHours_Signoff.pdf", False, ""

Name "H:\UnApprovedDetailedHours_Signoff.pdf " As FileName  'Name "C:\WINDOWS\UnApprovedDetailedHours_Signoff.pdf " As FileName
            Set appOutLook = CreateObject("Outlook.Application")
            Set MailOutLook = appOutLook.CreateItem(olMailItem)
            With MailOutLook
            .BodyFormat = olFormatHTML
            .To = rstTables!EmailAddress
            .Subject = "Unapproved Pay Hours Signoff"
            .HTMLBody = "Attached is a report that provides details of unapproved but paid hours for the current pay. " & _
            "Please sign, scan and return the report to Payroll@carefirst.com " & _
            "If you have any questions about this report, please call Bill (111-222-7777)." & "<BR>" & "<BR>" & "<BR>" & "<BR>" & _
            "Thanks," & "<BR>" & "<BR>" & _
            "Bill " & "<BR>" & _
            "(111) 222-7777"
            .Attachments.Add "H:\UnApprovedDetailedHours_Signoff_" & rstTables!Contact & ".pdf"
            .Close 0 '0 = olSave
            End With
            rstTables.MoveNext
        Set MailOutLook = Nothing
        Kill ("H:\UnApprovedDetailedHours*.pdf")
    Loop
0

Featured Post

Complete Microsoft Windows PC® & Mac Backup

Backup and recovery solutions to protect all your PCs & Mac– on-premises or in remote locations. Acronis backs up entire PC or Mac with patented reliable disk imaging technology and you will be able to restore workstations to a new, dissimilar hardware in minutes.

Join & Write a Comment

When you are entering numbers in a speadsheet, and don't remember what 6×7 is, you just type “=6*7" instead. It works in every cell! This is not so in Access. To enter the elusive 42 in a text box, you have to find a calculator, and then copy the re…
I see at least one EE question a week that pertains to using temporary tables in MS Access.  But surprisingly, I was unable to find a single article devoted solely to this topic. I don’t intend to describe all of the uses of temporary tables in t…
Familiarize people with the process of retrieving data from SQL Server using an Access pass-thru query. Microsoft Access is a very powerful client/server development tool. One of the ways that you can retrieve data from a SQL Server is by using a pa…
In Microsoft Access, learn how to use Dlookup and other domain aggregate functions and one method of specifying a string value within a string. Specify the first argument, which is the expression to be returned: Specify the second argument, which …

706 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

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now