Hallo zusammen,
ich versuche gerade verzweifelt, Access 365 dazu zu nötigen, mir einen Bericht gruppiert nach Kunden auszugeben (pro Kunde ein separater Bericht als PDF mit Benennung nach Kunde). Der Bericht heißt "Bericht1" und entsteht aus der Abfrage "nachKundenNr". Die relevanten Werte stehen in der Spalte "KUNDE" (Text).
Im Folgenden findet ihr mein VBA-Skript, welches ich durch Onlinerecherche schreiben konnte. Nun kommt es zu einem Synatxfehler in der DoCmd.OutputTo-Zeile, wegen eines fehlenden Operators (3075: KUNDE = Max Mustermann).
-------------------------------------
Public Sub ExportPDF()
Dim sql As String
Dim db As DAO.Database
Dim rs As DAO.Recordset
sql = "SELECT KUNDE FROM nachKundenNr"
Set db = CurrentDb
Set rs = db.OpenRecordset("nachKundenNr")
'Set rs = db.OpenRecordset(sql, dbOpenSnapshot)
Do Until rs.EOF
DoCmd.OpenReport "Bericht1", acViewPreview, , "[KUNDE] = '" & rs!KUNDE & "'"
DoCmd.OutputTo acOutputReport, "Bericht1", acFormatPDF, "C:\Users\H107705\Desktop\Test\report" & "_" & rs.Fields(sql).Value & ".pdf"
DoCmd.Close acReport, "Bericht1"
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub
---------------------------------
Weiß eventuell einer, wo es da klemmt? Ich tippe auf fehlende Hochkommata, aber alle von mir getesteten Varianten bringen nichts. Ich habe von VBA leider gar keinen wirklichen Plan.
Vielen Dank schon mal für eure Mühe!
Viele Grüße
MTGL
Hallo!
Ist Option Explicit im Codemodul gesetzt?
Beim gezeigten Code, würde ich als Compiler möglicherweise meckern, weil ich die Variable sql nicht kenne.
Gruß
Josef
Danke für den Hinweis! Da hatte ich glattweg zu viel auskommentiert :-D Explicit war auch aus. Es hat aber leider beides nichts gebracht, da der Fehler vorher aufgetreten ist.
Jetzt kennt die Recordset.Fields-Collection das Datenfeld "SELECT KUNDE FROM nachKundenNr" nicht. ;)
Die Möglichkeit, den Code im Einzelschritt auszuführen und die Inhalte der Variablen zu prüfen, kennst du?
Du sprichst in Rätseln :-) Nein, das sagt mir leider beides nichts.
Ich schreib deinen Code etwas um, damit du den Fehler besser finden kannst. (Di nvorhandenen Fehler lasse ich aber im Code.)
Public Sub ExportPDF()
Const ReportName As String = "Bericht1"
Dim sql As String
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim DateiName As String
Dim DateiPfad As String
Dim FilterString As String
Stop ' Der Code hält hier an. Du kannst mit {F8} den jeweils nächsten Schritt ausführen.
' Im Direktbereich des VBA-Editors siehst du die Ausgaben von Debug.Print.
sql = "SELECT KUNDE FROM nachKundenNr"
Set db = CurrentDb
Set rs = db.OpenRecordset("nachKundenNr")
'Set rs = db.OpenRecordset(sql, dbOpenSnapshot)
Do Until rs.EOF
FilterString = "[KUNDE] = '" & rs!KUNDE & "'"
Debug.Print FilterString ' Ist der String SQL-tauglich?
DoCmd.OpenReport ReportName, acViewPreview, , FilterString
DateiName = "report" & "_" & rs.Fields(sql).Value & ".pdf"
Debug.Print DateiName ' ist das ein gültiger Dateiname?
DateiPfad = "C:\Users\H107705\Desktop\Test\" & DateiName
Debug.Print DateiPfad
DoCmd.OutputTo acOutputReport, ReportName, acFormatPDF, DateiPfad
DoCmd.Close acReport, ReportName
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub
Vielen Dank für deine Hilfe! Irgendwie zieht er den Wert in dem FilterString nicht korrekt. Ich habe jetzt wieder allerhand mit Me und .Value probiert, aber er liest den Wert des Feldes einfach nicht aus. Brauche ich dafür ein zweites Recordset? Aber dann würde er ja nicht den aktuellen Wert nehmen, oder?
Ich lese deine Worte, erfasse aber deren Aussage nicht. ;)
Ab wann ist etwas falsch im Code?
In welcher Zeile kommt die Fehlermeldung?
DateiName = "report" & "_" & rs.Fields(sql).Value & ".pdf"Dass hier etwas nicht stimmt, hast du hoffentlich schon entdeckt.
Oder kommst du im Ablauf gar nicht so weit?
Gruß
Josef
Das Problem liegt in der Zeile:
DoCmd.OpenReport ReportName, acViewPreview, , FilterString
Er wirft dort den Fehler 3075 aus, da er als Resultat
KUNDE='Max Mustermann'
bekommt. Eigentlich sollte er ja den aktuellen Feldwert mit dem aus dem Recordset vergleichen und danach die Berichte ausgeben (also 'Max Mustermann' = 'Max Mustermann').
D.h. ich komme im Ablauf wirklich nicht bis dahin.
Ok, dann passt die Datenquelle des Berichts nicht. Der Filterausdruck sieht richtig aus.
Wie sieht die SQL-Anweisung der Abfrage aus?
Gruß
Josef
Die zieht nur ein paar Felder aus einer Tabelle, deren Name leider sehr lang ist (kommt aus einer Oracle-DB auf die ich keinen Einfluss habe) und die nur nach dem Jahr gefiltert wird. Den Filter könnte man sicher auch in VBA einbauen:
SELECT AMDB_TT_VIEW_VC_NB13.VERTRAGSNR, AMDB_TT_VIEW_VC_NB13.LEITUNGSNUMMER, AMDB_TT_VIEW_VC_NB13.PRODUKTTYP, AMDB_TT_VIEW_VC_NB13.LEITUNG_STATUS, AMDB_TT_VIEW_VC_NB13.ZEITRAUM_VON, AMDB_TT_VIEW_VC_NB13.ZEITRAUM_BIS, AMDB_TT_VIEW_VC_NB13.ANZAHL_STOERUNGEN, AMDB_TT_VIEW_VC_NB13.VERFUEGBARKEIT, AMDB_TT_VIEW_VC_NB13.VERFUEGBARKEIT_GJ, AMDB_TT_VIEW_VC_NB13.ZEITRAUM_MONAT, AMDB_TT_VIEW_VC_NB13.KUNDENNR, AMDB_TT_VIEW_VC_NB13.KUNDE
FROM AMDB_TT_VIEW_VC_NB13
GROUP BY AMDB_TT_VIEW_VC_NB13.VERTRAGSNR, AMDB_TT_VIEW_VC_NB13.LEITUNGSNUMMER, AMDB_TT_VIEW_VC_NB13.PRODUKTTYP, AMDB_TT_VIEW_VC_NB13.LEITUNG_STATUS, AMDB_TT_VIEW_VC_NB13.ZEITRAUM_VON, AMDB_TT_VIEW_VC_NB13.ZEITRAUM_BIS, AMDB_TT_VIEW_VC_NB13.ANZAHL_STOERUNGEN, AMDB_TT_VIEW_VC_NB13.VERFUEGBARKEIT, AMDB_TT_VIEW_VC_NB13.VERFUEGBARKEIT_GJ, AMDB_TT_VIEW_VC_NB13.ZEITRAUM_MONAT, AMDB_TT_VIEW_VC_NB13.KUNDENNR, AMDB_TT_VIEW_VC_NB13.KUNDE
HAVING (((AMDB_TT_VIEW_VC_NB13.ZEITRAUM_MONAT)="2022"))
ORDER BY AMDB_TT_VIEW_VC_NB13.LEITUNG_STATUS;
Ich gehe einmal davon aus, dass die Abfrage im direkten Aufruf funktioniert.
Wenn du den Bericht ohne Filter öffnest, enthält der alle Kunden und es kommt kein Fehler, oder?
Gruß
Josef
Jo, der Bericht funktioniert einwandfrei und liefert dann eine saubere Gruppierung nach Kunden. Ich kann ihn auch händisch nach Kunden filtern. Allerdings hätte er über 21.000 Seiten, was das Ganze etwas mühselig machen würde. Darum der Auto-PDF-Export, zumal wir das jährlich brauchen. So viele Werksstudenten finden wir nirgendwo :-D
@MTGL Zitatderen Name leider sehr lang ist (kommt aus einer Oracle-DB auf die ich keinen Einfluss habe
Auf die Vergabe eines Alias aber schon?!
Die HAVING Klausel gehört zu einer WHERE-Klausel (vor dem GROUP BY) umgewandelt.
Eine Gruppierung über alle Felder ist sinnlos. Wahrscheinlich am Besten komplett
raus und im Bericht gruppieren, was tatsächlich gruppiert werden soll/muss.
gruss ekkehard
ZitatIch kann ihn auch händisch nach Kunden filtern.
Wie machst du das?
Zum Testen:
Der Aufruf
DoCmd.OpenReport "Bericht1", acViewPreview
sollte somit funktionieren.
Zitat von: Beaker s.a. am Januar 31, 2023, 16:55:29Die HAVING Klausel gehört zu einer WHERE-Klausel (vor dem GROUP BY) umgewandelt.
Eine Gruppierung über alle Felder ist sinnlos. Wahrscheinlich am Besten komplett
raus und im Bericht gruppieren, was tatsächlich gruppiert werden soll/muss.
gruss ekkehard
Danke dir! Ich hatte das einfach im Entwurfsmodus zusammengeklickt und eigentlich lief der Bericht einwandfrei. Jetzt wollte ich den Bericht öffnen und es hakte mit eben der Fehlermeldung aus dem VBA-Modul. Ich habe das jetzt nochmal sauber gebaut und schon läuft der Bericht wieder. Verrückt. Es war zwar nicht schön, aber ich hatte daran zwischenzeitlich nichts verändert.
Zitat von: Josef P. am Januar 31, 2023, 17:34:32ZitatIch kann ihn auch händisch nach Kunden filtern.
Wie machst du das?
Zum Testen:
Der Aufruf
DoCmd.OpenReport "Bericht1", acViewPreview
sollte somit funktionieren.
Die Filterung nach Kunden habe ich am Anfang einfach über den SQL-Code gemacht, damit es schneller läuft.
Jo, jetzt läuft es. Allerdings wirft er mit den Zeilen
DoCmd.OpenReport ReportName, acViewPreview, , FilterString
DateiName = "report" & "_" & rs.Fields(sql).Value & ".pdf"
scheinbar nur eine riesige Datei mit dem Namen "report_rs.Fields(sql).Value.pdf" aus, anstatt dass er die Kundennamen einzeln verwendet. Du hattest also mit deiner vorangehenden Vermutung recht. Warum verwendet er jetzt nicht die Werte des Recordsets, sondern den Text?
Aktueller SQL-Code:
SELECT AMDB_TT_VIEW_VC_NB13.VERTRAGSNR, AMDB_TT_VIEW_VC_NB13.LEITUNGSNUMMER, AMDB_TT_VIEW_VC_NB13.PRODUKTTYP, AMDB_TT_VIEW_VC_NB13.LEITUNG_STATUS, AMDB_TT_VIEW_VC_NB13.ZEITRAUM_VON, AMDB_TT_VIEW_VC_NB13.ZEITRAUM_BIS, AMDB_TT_VIEW_VC_NB13.ANZAHL_STOERUNGEN, AMDB_TT_VIEW_VC_NB13.VERFUEGBARKEIT, AMDB_TT_VIEW_VC_NB13.VERFUEGBARKEIT_GJ, AMDB_TT_VIEW_VC_NB13.ZEITRAUM_MONAT, AMDB_TT_VIEW_VC_NB13.KUNDENNR, AMDB_TT_VIEW_VC_NB13.KUNDE
FROM AMDB_TT_VIEW_VC_NB13
WHERE (((AMDB_TT_VIEW_VC_NB13.ZEITRAUM_MONAT)="2022"));
Mit folgendem Code erzeugt er jetzt einzelne Berichte, allerdings gibt er sie immer noch mit falschem Namen aus und überschreibt sie somit (report_rs.Fields(sql).Value.pdf):
Option Explicit
Public Sub ExportPDF()
Const ReportName As String = "Bericht1"
Dim sql As String
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim DateiName As String
Dim DateiPfad As String
Dim FilterString As String
'Stop ' Der Code hält hier an. Du kannst mit {F8} den jeweils nächsten Schritt ausführen.
' Im Direktbereich des VBA-Editors siehst du die Ausgaben von Debug.Print.
sql = "SELECT KUNDE FROM nachKundenNr"
Set db = CurrentDb
Set rs = db.OpenRecordset("nachKundenNr")
Do Until rs.EOF
FilterString = "KUNDE = '" & rs!KUNDE & "'"
Debug.Print FilterString ' Ist der String SQL-tauglich?
DoCmd.OpenReport ReportName, acViewPreview, , FilterString
DateiName = "report" & "_" & "rs.Fields(sql).Value" & ".pdf"
Debug.Print DateiName ' ist das ein gültiger Dateiname?
DateiPfad = "C:\Users\H107705\Desktop\Test\" & DateiName
Debug.Print DateiPfad
DoCmd.OutputTo acOutputReport, ReportName, acFormatPDF, DateiPfad
DoCmd.Close acReport, ReportName
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub
Heureka! Jetzt bin ich verdammt nah dran. Mit folgendem Code, gibt er die Berichte korrekt aus. Allerdings bezieht er sich dabei stumpf auf die 12. Spalte. Wie nötige ich ihn jetzt dazu, dass er konkret auf die Spalte KUNDE bzw. das Recordset zugreift?
Option Explicit
Public Sub ExportPDF()
Const ReportName As String = "Bericht1"
Dim sql As String
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim DateiTitel As String
Dim DateiName As String
Dim DateiPfad As String
Dim FilterString As String
Set db = CurrentDb
Set rs = db.OpenRecordset("nachKundenNr")
Do Until rs.EOF
FilterString = "KUNDE = '" & rs!KUNDE & "'"
Debug.Print FilterString ' Ist der String SQL-tauglich?
DoCmd.OpenReport ReportName, acViewPreview, , FilterString
DateiTitel = rs.Fields(11)
DateiName = "report" & "_" & DateiTitel & ".pdf"
Debug.Print DateiName ' ist das ein gültiger Dateiname?
DateiPfad = "C:\Users\H107705\Desktop\Test\" & DateiName
Debug.Print DateiPfad
DoCmd.OutputTo acOutputReport, ReportName, acFormatPDF, DateiPfad
DoCmd.Close acReport, ReportName
rs.MoveNext
Loop
rs.Close
Set rs = Nothing
Set db = Nothing
End Sub
Hallo!
DateiTitel = rs.Fields("Kunde").Value
Gruß
Josef
Läuft :-) Ich hatte es vorher mit [] anstatt von "" versucht.
Hab vielen Dank für deine Hilfe!
ZitatAllerdings bezieht er sich dabei stumpf auf die 12. Spalte.
Das kommt davon, wenn man in der Abfrage
SELECT * ...verwendet, da muss man vorher abzählen an welcher Stelle das gewünschte
Feld aufgeführt ist, oder eben den Namen hernehmen (s. #18). Ist m.E. auch
die sicherste Methode, mit der Einschränkung, dass sich Tippfehler erst
zur Laufzeit bemerkbar machen.
gruss ekkehard