ms access - sirve - Usar bucles anidados para enviar por correo electrónico una lista de trabajos diarios a cada destinatario
for next visual basic ejemplos (2)
Estás en el camino correcto. Todo lo que necesita hacer es aprovechar el hecho de que una consulta de Access no solo se puede basar en tablas, sino que también puede usar otras consultas guardadas de la misma manera.
Entonces, si crea una "consulta guardada" (técnicamente llamada un objeto QueryDef
) llamada [dailyVisits] usando su cadena SQL en código VBA como este
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
Entonces puede usar bucles anidados para
- extraer el conjunto distinto de direcciones de correo electrónico,
- crear las cadenas de información del sitio para cada una y enviarlas por correo electrónico
usando el código VBA algo como esto:
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"
He estado jugando con VBA en Access durante años, pero para ser sincero, nunca antes había usado RecordSets.
Tengo una cadena de SQL que creará una lista de todas las visitas de ingenieros para un día específico:
"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""));"
Voy a reemplazar la fecha fija con una variable, que funciona bien en otro RecordSet que uso.
Lo que quiero hacer con estos datos es crear una cadena de texto de ID, nombre del sitio, fecha de visita para cada dirección de correo electrónico y luego enviarla como un correo electrónico. Puedo hacer el correo electrónico, y podría enviar todo el RecordSet como una cadena de texto de correo electrónico, simplemente estoy atascado con el envío de tantos correos electrónicos como direcciones de correo electrónico.
Tengo la sensación de que será un trabajo "para cada uno", pero realmente no lo sé.
Muchas gracias por su ayuda. Después de no mucho perder el tiempo, me he decidido por:
Dim rstEmail As DAO.Recordset, rstVisits As DAO.Recordset, VisitList As String, eml2txt As String, sql2 As String
Dim OutApp As Object
Dim OutMail As Object
Dim qdf As DAO.QueryDef
Set qdf = CurrentDb.CreateQueryDef("qryEngJobList1", _
"SELECT Cases.Id, Customers.SiteName, Customers.[Post Code] AS PCode, tbl_Visits.[Visit Date] AS vDate, Employees.[Last Name] AS lname, Employees.[Job Title], Employees.[E-mail Address] AS dEmail " & vbCrLf & _
"FROM Employees INNER JOIN (Customers INNER JOIN (Cases INNER JOIN tbl_Visits ON Cases.Id = tbl_Visits.CaseID) ON Customers.ID = Cases.Customer) ON Employees.ID = tbl_Visits.Engineer " & vbCrLf & _
"WHERE (((tbl_Visits.[Visit Date])=" & SQLDate([TempVars]![senddate].[Value]) & ") AND ((Employees.[Job Title])=""Engineer""));")
Set qdf = Nothing
Set rstEmail = CurrentDb.OpenRecordset( _
"SELECT DISTINCT [dEmail] FROM qryengjoblist1", _
dbOpenSnapshot)
Do Until rstEmail.EOF
Set rstVisits = CurrentDb.OpenRecordset( _
"SELECT Id, SiteName, vDate, PCode " & _
"FROM qryengjoblist1 " & _
"WHERE dEmail = ''" & rstEmail![dEmail] & "''", _
dbOpenSnapshot)
VisitList = ""
Do Until rstVisits.EOF
VisitList = VisitList & rstVisits!ID & vbTab & rstVisits!SiteName & vbTab & rstVisits!PCode & vbCrLf
rstVisits.MoveNext
Loop
rstVisits.Close
Set rstVisits = Nothing
''
'' insert code to send VisitList to rstEmail![E-mail Address]
eml2txt = "Please find below your visit summary for " & TempVars!senddate & ":" & Chr(13) & Chr(10) & Chr(13) & Chr(10) & "" _
& VisitList & Chr(13) & Chr(10) & Chr(13) & Chr(10) & "" _
& "If there are any issues, please contact " & TempVars!sereml & Chr(13) & Chr(10) & Chr(13) & Chr(10) & "" _
& "Thank you."
Set OutApp = CreateObject("Outlook.Application")
OutApp.Session.Logon
Set OutMail = OutApp.CreateItem(0)
On Error Resume Next
With OutMail
.SentOnBehalfOfName = TempVars!sereml
.To = rstEmail!dEmail
.CC = TempVars!sereml
.BCC = ""
.Subject = "Job Summary for " & TempVars!senddate
.Body = eml2txt
.Display ''or use .Send
.ReadReceiptRequested = False
End With
On Error GoTo 0
''MsgBox eml2txt
''
rstEmail.MoveNext
Loop
rstEmail.Close
Set rstEmail = Nothing
DoCmd.DeleteObject acQuery, "qryengjoblist1"
End Sub
Lo cual parece estar haciendo el truco muy bien. Todo lo que tengo que hacer ahora es descubrir cómo darle las gracias o algo por aquí :)