You're on the right track. All you need to do is leverage the fact that an Access query can not only be based on tables, it can also use other saved queries in the same way.
So if you create a "saved query" (technically called a QueryDef
object) named [dailyVisits] using your SQL string in VBA code like this
Dim qdf As DAO.QueryDef
Set qdf = CurrentDb.CreateQueryDef("dailyVisits", _
"SELECT Cases.Id, Customers.SiteName, tbl_Visits.[Visit Date], Employees.[Last Name], Employees.[Job Title], Employees.[E-mail Address] " & vbCrLf & _
"FROM (Customers INNER JOIN Cases ON Customers.ID = Cases.Customer) INNER JOIN (Employees INNER JOIN tbl_Visits ON Employees.ID = tbl_Visits.Engineer) ON Cases.Id = tbl_Visits.CaseID " & vbCrLf & _
"WHERE (((tbl_Visits.[Visit Date])=#1/27/2014#) AND ((Employees.[Job Title])=""Engineer""));"
Set qdf = Nothing
Then you can use nested loops to
- extract the distinct set of e-mail addresses,
- create the site information strings for each one, and send via e-mail
using VBA code something like this:
Dim rstEmail As DAO.RecordSet, rstVisits As DAO.RecordSet, VisitList As String
Set rstEmail = CurrentDb.OpenRecordset( _
"SELECT DISTINCT [E-mail Address] FROM dailyVisits", _
dbOpenSnapshot)
Do Until rstEmail.EOF
Set rstVisits = CurrentDb.OpenRecordset( _
"SELECT Id & ", " & SiteName & ", " & [Visit Date] AS Visit " & _
"FROM dailyVisits " & _
"WHERE [E-mail Address] = '" & rstEmail![E-mail Address] & "'",
dbOpenSnapshot)
VisitList = ""
Do Until rstVisits.EOF
VisitList = VisitList & rstVisits!Visit & VbCrLf
rstVisits.MoveNext
Loop
rstVisits.Close
Set rstVisits = Nothing
'
' insert code to send VisitList to rstEmail![E-mail Address]
'
rstEmail.MoveNext
Loop
rstEmail.Close
Set rstEmail = Nothing
DoCmd.DeleteObject acQuery, "dailyVisits"