Hallo, ich möchte eine Serienmail versenden.
Das Modul als Email mit festvorgegebener Adresse läuft.
Jetzt habe ich versucht die Emai-Empfänger variabel einzubauen.
Mit DAO und Zugriff auf die Abfrage "SerienMailTeilnehmerAdressdatenCheckQ".
Die Abfrage filtert die Empfänger korrekt raus und bietet das Feld "Email"
Bei Durchführung des Befehls erhalte ich eine Fehlermeldung und einen Hinweis, die ich im nachfolgenden Code benannt habe.
Vielen Dank für die Hilfe!
Private Sub cmdSenden_Click()
Dim dB As DAO.Database
Dim rs As DAO.Recordset
Dim objOutlook As Outlook.Application
Dim objMailItem As Outlook.MailItem
Dim l As Long
Set objOutlook = New Outlook.Application
Set objMailItem = objOutlook.CreateItem(olMailItem)
Set dB = CurrentDb
Set rs = dB.OpenRecordset("SerienMailTeilnehmerAdressdatenCheckQ", dbOpenDynaset)
Do While Not rs.EOF
With objMailItem
.To = rs!Email
.Subject = Me!txtBetreff
.Body = Me!txtInhalt
For l = 0 To Me!lstAnlagen.ListCount - 1
.Attachments.Add Me!lstAnlagen.ItemData(l)
Next l
'.Display
.Send
End With
rs.MoveNext
Loop
MsgBox "Email(s) wurden versendet"
rs.Close
Set rs = Nothing
Set dB = Nothing
End Sub
Hallo,
zeige bitte den SQL-String der Abfrage "SerienMailTeilnehmerAdressdatenCheckQ"
Vermutlich ist dort als Kriterium ein Verweis auf ein Formular-Steuerelemente enthalten, den Openrecordset nicht auflösen kann und somit kein rs-Objekt erzeugt wird, was sich in der 2. Fehlermeldung niederschlägt.
Zudem sollte es in vorliegenden Fall so lauten:
Set rs = dB.OpenRecordset("SerienMailTeilnehmerAdressdatenCheckQ", dbOpenSnapShot)
Der string:
SELECT AdressdatenT.ID AS AdressdatenID, AdressdatenT.Nr, AdressdatenT.Firma, AdressdatenT.Branche, AdressdatenT.Email
FROM SerienMailTeilnehmerAdressdatenQ INNER JOIN AdressdatenT ON SerienMailTeilnehmerAdressdatenQ.AdressdatenID = AdressdatenT.ID
ORDER BY SerienMailTeilnehmerAdressdatenQ.ID;
Der Query hat als Datenquelle einen vorher laufenden Query mit Hinweis auf ein Formularfeld...
SELECT TeilnehmerAdressdatenT.ID, TeilnehmerAdressdatenT.TeilnehmerID, TeilnehmerAdressdatenT.AdressdatenID, TeilnehmerAdressdatenT.Neu, AdressdatenT.Nr, AdressdatenT.Firma, AdressdatenT.Branche, AdressdatenT.Email
FROM AdressdatenT INNER JOIN TeilnehmerAdressdatenT ON AdressdatenT.ID = TeilnehmerAdressdatenT.AdressdatenID
WHERE (((TeilnehmerAdressdatenT.TeilnehmerID)=[Formulare]![frmMailsMitAttachment]![cbxTeilnehmerSelect]) AND ((TeilnehmerAdressdatenT.Neu)=True));
Muss ich eine Tabelle erzeugen? Statt nur Query abzufragen?
Mittlerweile habe ich mich weiter auf Fehlersuche begeben und
- den Datentyp im Feld Email von link auf "Kurzer Text" umgestellt
Das führt dazu, dass jetzt von 2 selektierten Datensätzen
- der erste läuft > die Email wird versendet
- bei der zweiten Email der Code mit einer Fehlermeldung abgebrochen wird.
Ich komme an dieser Stelle nicht mehr weiter...hängt das mit dem dbOpenSnapshot zusammen?
die Stelle ist im Code kommentiert:
Private Sub cmdSenden_Click()
Dim dB As DAO.Database
Dim rs As DAO.Recordset
Dim objOutlook As Outlook.Application
Dim objMailItem As Outlook.MailItem
Dim l As Long
Set objOutlook = New Outlook.Application
Set objMailItem = objOutlook.CreateItem(olMailItem)
Set dB = CurrentDb
DoCmd.OpenQuery "SerienMailTeilnehmerAdressdatenCheckQ" 'Mit diesem Query erstelle ich die nachfolgende Tabelle
'Um dem Problem mit der ComboBox aus dem Weg zu gehen
Set rs = dB.OpenRecordset("SerienMailTeilnehmerAdressdatenCheckT", dbOpenSnapshot)
Do While Not rs.EOF
With objMailItem
.To = rs!Email.Value 'Die erste Email läuft, bei der zweiten Mail erhalte ich an dieser Stelle
'die Fehlermeldung "Laufzeitfehler" Das Element wurde verschoben oder gelöscht
'hängt das mit dem dbOpenSnapshot zusammen?
.Subject = Me!txtBetreff
.Body = Me!txtInhalt
For l = 0 To Me!lstAnlagen.ListCount - 1
.Attachments.Add Me!lstAnlagen.ItemData(l)
Next l
' .Display
.Send
End With
rs.MoveNext
Loop
MsgBox "Email(s) wurden versendet"
rs.Close
Set rs = Nothing
Set dB = Nothing
End Sub
Zitat von: Umbauwfb am Januar 16, 2022, 12:12:28Ich komme an dieser Stelle nicht mehr weiter...hängt das mit dem dbOpenSnapshot zusammen?
Nein, überhaupt nicht.
Mit
Set objMailItem = objOutlook.CreateItem(olMailItem)erstellst du ein neues MailItem-Objekt.
Mit
.Sendschickst du dieses konkrete Mailitem weg. Du kannst es danach nicht mehr verwenden, um die nächste Email zu erstellen, sondern du musst dafür ein neues Mailitem erstellen.
Die Serienmail läuft jetzt!
Vielen Dank an alle, die geholfen haben!
Der wesentliche Fehler war, dass das
Set objMailItem = objOutlook.CreateItem(olMailItem)
in den Loop musste...
Nachfolgend der komplette Code:
Private Sub cmdSenden_Click()
Dim dB As DAO.Database
Dim rs As DAO.Recordset
Dim objOutlook As Outlook.Application
Dim objMailItem As Outlook.MailItem
Dim l As Long
Set objOutlook = New Outlook.Application
' Set objMailItem = objOutlook.CreateItem(olMailItem) !!!!!MUSS AN DEN ANFANG DES LOOPs!!!!!
Set dB = CurrentDb
Dim AnzahlEmail As Integer
AnzahlEmail = 0
Dim strSQL As String
strSQL = "DELETE * FROM SerienMailTeilnehmerAdressdatenCheckT"
CurrentDb.Execute strSQL, dbFailOnError
DoCmd.SetWarnings False
DoCmd.OpenQuery "SerienMailTeilnehmerAdressdatenCheckQ" 'Mit diesem Query erstelle ich die nachfolgende Tabelle
DoCmd.SetWarnings True 'Um dem Problem mit einer ComboBox aus dem Weg zu gehen
Set rs = dB.OpenRecordset("SerienMailTeilnehmerAdressdatenCheckT", dbOpenSnapshot)
Do Until rs.EOF
Set objMailItem = objOutlook.CreateItem(olMailItem) '!!!!!MUSS AN DEN ANFANG DES LOOPs!!!!
With objMailItem
.To = rs!Email
.Subject = Me!txtBetreff
.Body = Me!txtInhalt
For l = 0 To Me!lstAnlagen.ListCount - 1
.Attachments.Add Me!lstAnlagen.ItemData(l)
Next l
' .Display
.Send
End With
rs.MoveNext
AnzahlEmail = AnzahlEmail + 1
Loop
MsgBox " " & AnzahlEmail & " " & "Email(s) wurden versendet"
rs.Close
Set rs = Nothing
Set dB = Nothing
End Sub