Neuigkeiten:

Ist euer Problem gelöst, dann bitte den Knopf "Thema gelöst" drücken!

Mobiles Hauptmenü

Recordset aus gefilterter Abfrage öffnen

Begonnen von brueninghoff, August 05, 2021, 09:53:55

⏪ vorheriges - nächstes ⏩

brueninghoff

Hallo,

ich hoffe ich kann hier Hilfe für ein Problem mit einer unserer Access-Datenbanken finden.
Da wir den Mailversand von Tobit.David auf MS Exchange umgestellt haben, will ich grade die alten Funktionen zum Versand von Reports in den Datenbanken aktualisieren.
Problematik ist die folgende:
Ich habe ein Formular mit 2 Textfeldern in denen Monat und Jahr für den Report definiert wird (TXT_Monat, TXT_Jahr). diese werden in einer Abfrage zur Filterung der Daten verwendet, sodass auch wirklich nur Daten aus dem entsprechenden Monat gezeigt werden.
Da ich mit einen Klick auf "Senden" im Formular nacheinander Mails an alle Adressaten versenden will, öffne ich ein Recordset mit einem SQL-Select der die zuvor gefilterte Abfrage unter FROM miteinbezieht.
In der Ausführung erhalte ich immer einen Fehler beim Öffnen des Recordsets ("Fehler 3061: 2 Parameter wurden erwartet, aber es wurden zu wenig Parameter übergeben.").
Daraufhin habe ich zur Ausführung die gefilterte Abfrage kontrolliert und sie ist komischerweise leer. Außerhalb der Ausführung des Codes zeigt die Abfrage aber wie erwartet alle Daten.
Nehme ich dann die Filterung, die sich auf die beiden Formularfelder bezieht heraus, kann ich auch zur Ausführung die Daten der Abfrage sehen und das Recordset wird sauber geöffnet.
Die Daten sind dann aber eben nicht mehr gefiltert und der Report zeigt auch alte Informationen.

Da ich das Problem mit unterschiedlichen Reports habe, gibt es bei mir einige Anwendungsfälle für eine mögliche Lösung.
Kann jemand dieses Problem nachvollziehen und gibt es dafür eine Lösung? Ein Workaround wäre für mich ebenfalls praktisch.

hier noch mein Code für den Versand:
Private Sub CMD_Datenversand_Click()
On Error GoTo Err_EMailVersandAbgebrochen 'Routine zum Abfangen von Fehlern und Abbruch des Benutzers

    'Variablen definieren
    Dim QRY_Fracht As String
    Dim db As DAO.Database
    Dim rs_Fracht As DAO.Recordset
    Dim REPname As String
    Dim REPfilter As String
    Dim ATTname As String
    Dim SUBJ As String
    Dim BDY As String
   
    REPname = "REP_Frachtdaten" 'Report für die Auswertung
   
    Set db = CurrentDb()
    QRY_Fracht = "SELECT [QRY_Sped-Frachtdaten].AL20_SUCHNAME, [QRY_Sped-Frachtdaten].AL21_EMAIL, [QRY_Sped-Frachtdaten].VK30_NR " & _
                "FROM [QRY_Sped-Frachtdaten] " & _
                "WHERE (([QRY_Sped-Frachtdaten].VK30_NR) <> 90010) " & _
                "GROUP BY [QRY_Sped-Frachtdaten].AL20_SUCHNAME, [QRY_Sped-Frachtdaten].AL21_EMAIL, [QRY_Sped-Frachtdaten].VK30_NR;" 'Query für das Recordset
    Set rs_Fracht = db.OpenRecordset(QRY_Fracht) 'Recordset öffnen
    If rs_Fracht.EOF Then 'Wenn keine Einträge vorhanden sind
        MsgBox "Keine Addressaten gefunden!"
        Exit Sub
    End If
    BDY = "Sehr geehrte Damen und Herren" & vbCrLf & vbCrLf & "Anbei erhalten Sie die Auswertung der Milchlieferungen für den im Betreff genannten Zeitraum." 'Mailbody erzeugen
   
    REPfilter = "VK30_NR = " & rs_Fracht!VK30_NR 'Filterparameter für den Report
                   
    Do Until rs_Fracht.EOF 'Für jeden Datensatz im Recordset
        REPfilter = "VK30_NR = " & rs_Fracht!VK30_NR 'Filterparameter für den Report erneut setzen
        DoCmd.OpenReport REPname, acViewPreview, "", REPfilter 'Öffne den Report
       
        ZielEmail = "Administrator@brueninghoff.net" 'Reports!REP_Frachtdaten!TXT_MAIL.Value 'Adresse beziehen
       
       
        SUBJ = "Kälbermilch-Frachtdaten" & " " & Reports!REP_Frachtdaten!TXT_MON.Value 'Titel generieren
        ATTname = "Kälbermilch-Frachtdaten" & " " & rs_Fracht!AL20_SUCHNAME 'Name des Attachments
        Reports(REPname).Caption = ATTname 'Titel des Reports neu setzen
   
        DoCmd.SendObject acReport, REPname, "PDF", ZielEmail, , , SUBJ, BDY, False, "" 'Mail automatisch versenden (Outlook Warnung bestätigen)
       
        DoCmd.Close acReport, REPname 'aktiven Report wieder schließen
                   
        rs_Fracht.MoveNext 'Nächster Datensatz im Recordset
    Loop
   
    rs_Fracht.Close 'Recordset schließen
    Set rs_Fracht = Nothing
    Set db = Nothing
   
Exit Sub 'Bei sauberem Verlauf (Email wurde gesendet, kein Abbruch) oder wenn der notwendige Parameter fehlt, verlasse die Subroutine vorzeitig

    'Bei Abbruch durch den Benutzer Fehler 2501 Meldung ausgeben oder Fehler-Nummer
Err_EMailVersandAbgebrochen:
    If Err.Number = 2501 Then
        MsgBox "Die E-Mail wurde nicht gesendet.", vbCritical + vbOKOnly
    Else
        MsgBox "Fehler " & Err.Number & ":" & Err.Description
    End If
End Sub

DF6GL

Hallo,


zeige mal den SQL-String der Abfrage QRY_Sped-Frachtdaten.

Möglicherweise sind dort Verweise auf die Formularfelder als Kriterium angegeben.
Viele Grüße vom Bodensee
Franz, DF6GL

Hilfestellung:  http://www.access-o-mania.de/forum/index.php?topic=6969.msg118738#msg118738

Links und Tipps:
1.   http://v.hdm-stuttgart.de/~riekert/lehre/db-kelz/
1a. http://www.tinohempel.de/info/info/datenbank/normalisierung.htm
1b. https://support.office.com/de-de/article/Grundlagen-des-Datenbankentwurfs-eb2159cf-1e30-401a-8084-bd4f9c9ca1f5#bmterms
2.   http://www.donkarl.com
3.   https://web.archive.org/web/20201201233522/http://www.dbwiki.net/
4.   http://www.access-tutorial.de/
5.   http://www.tty1.net/smart-questions_de.htm
6.   http://access.joposol.com/accept

Last but not least:   < F1 > für Hilfe
;) Learning by doing not by spoon-feed ;)

Tipp: Find and Replace for Access

brueninghoff

Hallo,

ja es werden 2 Formularfelder abgefragt, die den Datumsfilter enthalten.
SELECT QRY_Adressen_Stallstandorte.AL20_SUCHNAME AS Stall_Name, QRY_SPED_Frachtdaten.KNR, QRY_SPED_Frachtdaten.Rezept, Sum(QRY_SPED_Frachtdaten.Gewicht) AS SummevonGewicht, QRY_SPED_Frachtdaten.Frachtpreis, Sum(QRY_SPED_Frachtdaten.Netto) AS SummevonNetto, Format([Lastaccess],"yyyy\/mm") AS Mon, Count(QRY_SPED_Frachtdaten.ID) AS AnzahlvonID, QRY_Adressen_Spediteure.VK30_NR, QRY_Adressen_Spediteure.AL20_SUCHNAME, QRY_Adressen_Spediteure.AL20_NAME1, QRY_Adressen_Spediteure.AL20_NAME2, QRY_Adressen_Spediteure.AL20_STRASSE, QRY_Adressen_Spediteure.AL20_LAND, QRY_Adressen_Spediteure.AL20_PLZ, QRY_Adressen_Spediteure.AL20_ORT, QRY_Adressen_Spediteure.AL21_TELEFON, QRY_Adressen_Spediteure.AL21_EMAIL
FROM QRY_Adressen_Stallstandorte INNER JOIN (QRY_SPED_Frachtdaten INNER JOIN QRY_Adressen_Spediteure ON QRY_SPED_Frachtdaten.Spedition_VK30_NR = QRY_Adressen_Spediteure.VK30_NR) ON QRY_Adressen_Stallstandorte.AL20_GEN = QRY_SPED_Frachtdaten.Stall_AL20_GEN
WHERE (((Year([LastAccess]))=[Formulare]![FRM_FuDa_Export]![Txt_Jahr]) AND ((Month([LastAccess]))=[Formulare]![FRM_FuDa_Export]![Txt_Monat]))
GROUP BY QRY_Adressen_Stallstandorte.AL20_SUCHNAME, QRY_SPED_Frachtdaten.KNR, QRY_SPED_Frachtdaten.Rezept, QRY_SPED_Frachtdaten.Frachtpreis, Format([Lastaccess],"yyyy\/mm"), QRY_Adressen_Spediteure.VK30_NR, QRY_Adressen_Spediteure.AL20_SUCHNAME, QRY_Adressen_Spediteure.AL20_NAME1, QRY_Adressen_Spediteure.AL20_NAME2, QRY_Adressen_Spediteure.AL20_STRASSE, QRY_Adressen_Spediteure.AL20_LAND, QRY_Adressen_Spediteure.AL20_PLZ, QRY_Adressen_Spediteure.AL20_ORT, QRY_Adressen_Spediteure.AL21_TELEFON, QRY_Adressen_Spediteure.AL21_EMAIL
ORDER BY QRY_Adressen_Stallstandorte.AL20_SUCHNAME, QRY_SPED_Frachtdaten.Rezept;

Maxel

Viele Grüße
Maxel

DF6GL

Hallo,

ich empfehle, Formreferenzen als Kriterium in Abfragen nicht zu verwenden.



Insofern, wirf die Formverweise heraus und baue sie in den SQL-String "QRY_Fracht" ein.



Zudem sind "Magic Numbers" wie diese: 90010  nicht sehr flexibel und transparent.

Alternativ wäre eine Public-Function oder  ein Tempvars-Element als Kriterium  anstelle der Form-Referenez besser geeignet


ähnlich:


.
.
"WHERE [QRY_Sped-Frachtdaten].VK30_NR <> 90010 and (Year([LastAccess]) = " & Me!Txt_Jahr & " and Month([LastAccess] = " &  Me!Txt_Monat & _
.
.


wenn der Code im Form "FRM_FuDa_Export"  abläuft
Viele Grüße vom Bodensee
Franz, DF6GL

Hilfestellung:  http://www.access-o-mania.de/forum/index.php?topic=6969.msg118738#msg118738

Links und Tipps:
1.   http://v.hdm-stuttgart.de/~riekert/lehre/db-kelz/
1a. http://www.tinohempel.de/info/info/datenbank/normalisierung.htm
1b. https://support.office.com/de-de/article/Grundlagen-des-Datenbankentwurfs-eb2159cf-1e30-401a-8084-bd4f9c9ca1f5#bmterms
2.   http://www.donkarl.com
3.   https://web.archive.org/web/20201201233522/http://www.dbwiki.net/
4.   http://www.access-tutorial.de/
5.   http://www.tty1.net/smart-questions_de.htm
6.   http://access.joposol.com/accept

Last but not least:   < F1 > für Hilfe
;) Learning by doing not by spoon-feed ;)

Tipp: Find and Replace for Access

brueninghoff

Hallo,

danke für die Tipps!

wollte die Zeile direkt ausprobieren, bekomme aber folgende Meldung:

Fehler 3075:Syntaxfehler (fehlender Operator) in Abfrageausdruck
([QRY_Sped-Frachtdaten].VK30_NR <> 90010 and (Year([LastAccess]) =
2021 and Month([LastAccess] = 7) GROUP BY
[QRY_Sped-Frachtdaten].AL20_SUCHNAME,
[QRY_Sped-Frachtdaten].AL21_EMAIL,
[QRY_Sped-Frachtdaten].VK30_NR;'.

Die 90100 ist auch erst mal nur zur Entwicklung drin, das wird später anders gelöst. Da kümmere ich mich aber erst drum wenn alles andere geht.

DF6GL

Hallo,

die Klammersetzung ist falsch



[QRY_Sped-Frachtdaten].VK30_NR <> 90010 and Year([LastAccess]) =
2021 and Month([LastAccess]) = 7 GROUP BY
[QRY_Sped-Frachtdaten].AL20_SUCHNAME,
[QRY_Sped-Frachtdaten].AL21_EMAIL,
[QRY_Sped-Frachtdaten].VK30_NR
Viele Grüße vom Bodensee
Franz, DF6GL

Hilfestellung:  http://www.access-o-mania.de/forum/index.php?topic=6969.msg118738#msg118738

Links und Tipps:
1.   http://v.hdm-stuttgart.de/~riekert/lehre/db-kelz/
1a. http://www.tinohempel.de/info/info/datenbank/normalisierung.htm
1b. https://support.office.com/de-de/article/Grundlagen-des-Datenbankentwurfs-eb2159cf-1e30-401a-8084-bd4f9c9ca1f5#bmterms
2.   http://www.donkarl.com
3.   https://web.archive.org/web/20201201233522/http://www.dbwiki.net/
4.   http://www.access-tutorial.de/
5.   http://www.tty1.net/smart-questions_de.htm
6.   http://access.joposol.com/accept

Last but not least:   < F1 > für Hilfe
;) Learning by doing not by spoon-feed ;)

Tipp: Find and Replace for Access

brueninghoff

Hallo,

habe die Klammersetzung korrigiert, das Ergebnis bleibt aber das gleiche.

hier der Code für QRY_Fracht:
QRY_Fracht = "SELECT [QRY_Sped-Frachtdaten].AL20_SUCHNAME, [QRY_Sped-Frachtdaten].AL21_EMAIL, [QRY_Sped-Frachtdaten].VK30_NR " & _
                "FROM [QRY_Sped-Frachtdaten] " & _
                "WHERE [QRY_Sped-Frachtdaten].VK30_NR <> 90010 and (Year([LastAccess]) = " & Me!Txt_Jahr & " and Month([LastAccess]) = " & Me!Txt_Monat & " " & _
                "GROUP BY [QRY_Sped-Frachtdaten].AL20_SUCHNAME, [QRY_Sped-Frachtdaten].AL21_EMAIL, [QRY_Sped-Frachtdaten].VK30_NR;" 'Query für das Recordset

PhilS

Zitat von: brueninghoff am August 05, 2021, 15:04:43habe die Klammersetzung korrigiert, das Ergebnis bleibt aber das gleiche.
Es ist weiterhin eine öffnende Klammer vor Year, die nie geschlossen wird.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

brueninghoff

Danke, das wars!
Beim Öffnen des Recordsets wird jetzt eine Fehlermeldung erzeugt:
"Fehler 3061: 1 Parameter wurden erwartet, aber es wurden zu wenig Parameter übergeben."

Ohne die WHERE Klausel wird das Recordset sauber geöffnet.

DF6GL

Hallo,


es wird sich auf Formular-Steuerelemente (Textfelder) bezogen. Steht da auch etwas darin oder sind die leer?
Evtl. leere Felder abfangen:


"WHERE [QRY_Sped-Frachtdaten].VK30_NR <> 90010 and Year([LastAccess]) = " & nz(Me!Txt_Jahr,Year(Date)) & " and Month([LastAccess]) = " & nz(Me!Txt_Monat,Month(Date)) & " " & _
Viele Grüße vom Bodensee
Franz, DF6GL

Hilfestellung:  http://www.access-o-mania.de/forum/index.php?topic=6969.msg118738#msg118738

Links und Tipps:
1.   http://v.hdm-stuttgart.de/~riekert/lehre/db-kelz/
1a. http://www.tinohempel.de/info/info/datenbank/normalisierung.htm
1b. https://support.office.com/de-de/article/Grundlagen-des-Datenbankentwurfs-eb2159cf-1e30-401a-8084-bd4f9c9ca1f5#bmterms
2.   http://www.donkarl.com
3.   https://web.archive.org/web/20201201233522/http://www.dbwiki.net/
4.   http://www.access-tutorial.de/
5.   http://www.tty1.net/smart-questions_de.htm
6.   http://access.joposol.com/accept

Last but not least:   < F1 > für Hilfe
;) Learning by doing not by spoon-feed ;)

Tipp: Find and Replace for Access

PhilS

Zitat von: brueninghoff am August 05, 2021, 15:23:09"Fehler 3061: 1 Parameter wurden erwartet, aber es wurden zu wenig Parameter übergeben."
Dann stimmt einer der Feldnamen in der Where-Klausel nicht. Vermutlich LastAccess.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

brueninghoff

DF6GL: Die Felder sind nicht leer, sie sind automatisch immer mit einem Standardwert befüllt wenn die Form geöffnet wird.

PhilS: LastAccess war zur Ausführung tatsächlich leer, aber auch wenn ich eine manuell befüllte Variable übergebe, bleibt das Ergebnis das gleiche.
 

DF6GL

Hallo,

"LastAccess" gibt es in der Abfrage nicht, nur diesen Alias, in der Selectliste:

 Format([Lastaccess],"yyyy\/mm") AS Mon

Dadurch könnte die Where-Condition im Recordser-SQL-String auch gleich so aussehen (vorausgesetzt, der Monat wird immer 2-stellig angegeben, ansonsten muss der Monat dahingehend formatiert werden):

"WHERE [QRY_Sped-Frachtdaten].VK30_NR <> 90010 and Mon = '" & Me!Txt_Jahr & "/" & Me!Txt_Monat & "'"  & _
Viele Grüße vom Bodensee
Franz, DF6GL

Hilfestellung:  http://www.access-o-mania.de/forum/index.php?topic=6969.msg118738#msg118738

Links und Tipps:
1.   http://v.hdm-stuttgart.de/~riekert/lehre/db-kelz/
1a. http://www.tinohempel.de/info/info/datenbank/normalisierung.htm
1b. https://support.office.com/de-de/article/Grundlagen-des-Datenbankentwurfs-eb2159cf-1e30-401a-8084-bd4f9c9ca1f5#bmterms
2.   http://www.donkarl.com
3.   https://web.archive.org/web/20201201233522/http://www.dbwiki.net/
4.   http://www.access-tutorial.de/
5.   http://www.tty1.net/smart-questions_de.htm
6.   http://access.joposol.com/accept

Last but not least:   < F1 > für Hilfe
;) Learning by doing not by spoon-feed ;)

Tipp: Find and Replace for Access

brueninghoff

Ahh jetzt hab ichs soweit, dass ich den Report öffnen kann.
Das ursprüngliche Problem habe ich aber weiterhin:
Die Daten sind nicht gefiltert und ich erhalte auch Daten von vor dem gefilterten Zeitraum.

kann ich dem Report im Filter jetzt eine entsprechende Eingrenzung mitgeben?

Private Sub CMD_Datenversand_Click()
On Error GoTo Err_EMailVersandAbgebrochen 'Routine zum Abfangen von Fehlern und Abbruch des Benutzers

    'Variablen definieren
    Dim QRY_Fracht As String
    Dim db As DAO.Database
    Dim rs_Fracht As DAO.Recordset
    Dim REPname As String
    Dim REPfilter As String
    Dim ATTname As String
    Dim SUBJ As String
    Dim BDY As String
    Dim Datetoday As Date
   
    REPname = "REP_Frachtdaten" 'Report für die Auswertung
   
    Set db = CurrentDb()
    QRY_Fracht = "SELECT [QRY_Sped-Frachtdaten].AL20_SUCHNAME, [QRY_Sped-Frachtdaten].AL21_EMAIL, [QRY_Sped-Frachtdaten].VK30_NR, [QRY_Sped-Frachtdaten].Mon " & _
                "FROM [QRY_Sped-Frachtdaten] " & _
                "WHERE [QRY_Sped-Frachtdaten].VK30_NR <> 90010 And Year([QRY_Sped-Frachtdaten].Mon) = " & Me!Txt_Jahr & " And Month([QRY_Sped-Frachtdaten].Mon) = " & Me!Txt_Monat & " " & _
                "GROUP BY [QRY_Sped-Frachtdaten].AL20_SUCHNAME, [QRY_Sped-Frachtdaten].AL21_EMAIL, [QRY_Sped-Frachtdaten].VK30_NR, [QRY_Sped-Frachtdaten].Mon;"
    Set rs_Fracht = db.OpenRecordset(QRY_Fracht) 'Recordset öffnen
    If rs_Fracht.EOF Then 'Wenn keine Einträge vorhanden sind
        MsgBox "Keine Addressaten gefunden!"
        Exit Sub
    End If
    BDY = "Sehr geehrte Damen und Herren" & vbCrLf & vbCrLf & "Anbei erhalten Sie die Auswertung der Milchlieferungen für den im Betreff genannten Zeitraum." 'Mailbody erzeugen
   
    REPfilter = "VK30_NR = " & rs_Fracht!VK30_NR 'Filterparameter für den Report
                   
    Do Until rs_Fracht.EOF 'Für jeden Datensatz im Recordset
        REPfilter = "VK30_NR = " & rs_Fracht!VK30_NR 'Filterparameter für den Report erneut setzen
        DoCmd.OpenReport REPname, acViewPreview, "", REPfilter 'Öffne den Report
       
        ZielEmail = "Administrator@brueninghoff.net" 'Reports!REP_Frachtdaten!TXT_MAIL.Value 'Adresse beziehen
       
       
        SUBJ = "Kälbermilch-Frachtdaten" & " " & Reports!REP_Frachtdaten!TXT_MON.Value 'Titel generieren
        ATTname = "Kälbermilch-Frachtdaten" & " " & rs_Fracht!AL20_SUCHNAME 'Name des Attachments
        Reports(REPname).Caption = ATTname 'Titel des Reports neu setzen

        DoCmd.SendObject acReport, REPname, "PDF", ZielEmail, , , SUBJ, BDY, False, "" 'Mail automatisch versenden (Outlook Warnung bestätigen)
       
        DoCmd.Close acReport, REPname 'aktiven Report wieder schließen
                   
        rs_Fracht.MoveNext 'Nächster Datensatz im Recordset
    Loop
   
    rs_Fracht.Close 'Recordset schließen
    Set rs_Fracht = Nothing
    Set db = Nothing
   
Exit Sub 'Bei sauberem Verlauf (Email wurde gesendet, kein Abbruch) oder wenn der notwendige Parameter fehlt, verlasse die Subroutine vorzeitig

    'Bei Abbruch durch den Benutzer Fehler 2501 Meldung ausgeben oder Fehler-Nummer
Err_EMailVersandAbgebrochen:
    If Err.Number = 2501 Then
        MsgBox "Die E-Mail wurde nicht gesendet.", vbCritical + vbOKOnly
    Else
        MsgBox "Fehler " & Err.Number & ":" & Err.Description
    End If

End Sub