Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!

Mobiles Hauptmenü

PDF Export - Für jeden Kunden ein extra PDF

Begonnen von Alex_80, April 20, 2015, 14:26:57

⏪ vorheriges - nächstes ⏩

Alex_80

Hallo,

ich möchte gerne per VBA die Rechnungen als PDF speichern. Dabei soll für jeden Kunden bzw. jede Rechnungsnummer ein extra PDF angelegt werden. Ich habe schon etwas rumgespielt, aber leider funktioniert es nicht. Access macht den Bericht auf, geht die einzelnen Rechnungen durch, legt aber nur ein PDF und zwar das mit dem letzten Kunden ab. Kann mir hier jemand weiterhelfen:

Meine Abfrage, auf die zugegriffen werden soll:
SELECT tbl_RechNr.*, tbl_Patientendaten.*, tbl_Leistungen.*, tbl_RechNr.RechnDruck
FROM (tbl_Patientendaten INNER JOIN tbl_RechNr ON tbl_Patientendaten.PatID = tbl_RechNr.PatID_f) INNER JOIN tbl_Leistungen ON tbl_RechNr.Rechnungsnummer = tbl_Leistungen.Rechnungsnummer_ff
WHERE (((tbl_RechNr.RechnDruck)=No));


Mein VBA Code:Private Sub Umschaltfläche138_Click()
Dim db As Database
Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("Select Distinct Rechnungsnummer from qry_Rechnungsstellung")
Do While Not rst.EOF
DoCmd.OpenReport "rpt_Rechnung_30112015", acViewPreview, , "Rechnungsnummer='" & rst!Rechnungsnummer & "'"
DoCmd.OutputTo acOutputReport, "rpt_Rechnung_30112015", "PDF", "X:\Kundenrechnungen\Rechnungen\Rechnungen vom " & Date & " " & Rechnungsnummer & ".pdf", False
DoCmd.Close acReport, "rpt_Rechnung_30112015"
rst.MoveNext
Loop
Set rst = Nothing
End Sub


Vielen Dank!

MaggieMay

Hi,

die Variable "Rechnungsnummer" ist nicht definiert, verwende statt dessen "rst!Rechnungsnummer".

Das hätte dir eigentlich auffallen müssen, dass der Dateiname anders aussieht als du es vorgesehen hast...
Freundliche Grüße
MaggieMay

Alex_80

Hey,

also ich habe die betreffende Zeile abgeändert, allerdings kommt jetzt ein Syntaxfehler (Laufzeitfehler '3075':Syntaxfehler in Zeichenfolge in Abfrageausdruck 'rst!Rechnungsnummer71500000".). Dabei ist die 71500000 der Nummernkreis meiner Rechnungsnummern. Habe ich da jetzt noch was falsch gemacht?

Dim db As Database
Dim rst As DAO.Recordset
Dim sNow As String
sNow = Format(CStr(Now), "dd_mm_yyyy - hh_mm_ss")
Set rst = CurrentDb.OpenRecordset("Select Distinct Rechnungsnummer from qry_Rechnungsstellung")
Do While Not rst.EOF
[b]DoCmd.OpenReport "rpt_Rechnung_30112015", acViewPreview, , "rst!Rechnungsnummer" & rst!Rechnungsnummer & "'"[/b]
DoCmd.OutputTo acOutputReport, "rpt_Rechnung_30112015", "PDF", "\\diskstation\Rechnungen\Rechnung vom " & sNow & " " & Rechnungsnummer & ".pdf", False
DoCmd.Close acReport, "rpt_Rechnung_30112015"
rst.MoveNext
Loop
Set rst = Nothing
End Sub

MaggieMay

Du hast die falsche Zeile erwischt, mein Hinweis bezog sich auf den OutputTo-Befehl.
Mach also bitte deine Änderung rückgängig und schau dir die nächste Code-Zeile einmal genauer an.

BTW:
Vor dem Testen sollte der Code kompiliert werden, ist dir das bekannt?

Dazu sollte im Kopf eines jeden Moduls der Eintrag "Option Explicit" stehen und der Haken bei der VBA-Option "Variablendeklaration erforderlich" sollte standardmäßig gesetzt sein.
Freundliche Grüße
MaggieMay

Alex_80

Alles klar, danke. Es funktioniert jetzt  :).

Alex_80

Hallo, ich würde das Thema gerne nochmal aufgreifen, weil ich hier wieder ein Problem beim Filtern habe. Wie das Thema schon sagt, möchte ich gerne für jeden Kunden bzw. jetzt Kundennummer ein extra PDF exportieren lassen. Dabei ist das Feld "Kundennummer" als Zahl in der Tabelle angelegt.
Was ich bisher geschafft habe, ist, dass er mir die PDFs ausdruckt, aber es sind immer alle Rechnungen von allen Kundennummern in diesen PDFs enthalten. Sprich in dem PDF mit der KdNr 1 sind auch die Dokumente für die KdNr 2 enthalten und umgekehrt (siehe Anhang).

Meine weiteren Versuche verursachen immer einen "Datentypenkonflikt in Kriterienausdruck" - Laufzeitfehler 3464.

Private Sub Umschaltfläche33_Click()
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim I As Long
Dim M As Double, Ende As Double, MilliSekunden As Double
Set rst = CurrentDb.OpenRecordset("Select Distinct Kundennummer from Patientendaten Order By Kundennummer")
Do While Not rst.EOF
I = DCount("[Kundennummer]", "Patientendaten", "Kundennummer='" & rst!Kundennummer & "'")
DoCmd.OpenReport "rpt_Rechnung_org", acViewPreview, , "KdNr='" & rst!Kundennummer & "'"
'DoCmd.OpenReport "rpt_Rechnung_org", acViewPreview, , "Kundennummer='" & rst!Kundennummer & "'"
'DoCmd.PrintOut acPrintAll
DoCmd.OutputTo acOutputReport, "rpt_Rechnung_org", "PDF", "X:\Verwaltung\Patientenmanagement\Kostenvoranschläge\KVA Archiv\KVA vom " & Date & " KdNr " & rst!Kundennummer & ".pdf", False
DoCmd.Close acReport, "rpt_Rechnung_org"

Ende = Timer + (MilliSekunden / 100)
Do While M < Ende
  DoEvents
  M = Timer
Loop

rst.MoveNext
Loop
Set rst = Nothing
End Sub


Dabei wir die Zeile mit dem "DCount" gelb markiert. Kann mir hier jemand helfen, weil ich das nicht verstehe, was da falsch läuft. Danke!

DF6GL

#6
Hallo,

für was brauchst Du denn die Dcount-Funktion?

Wenn die "Kundennummer"  den Datentyp Zahl aufweist, dann sind die Hochkommata in den Where-Conditions zu entfernen.

Weiterhin könnte der Report auch "hidden" geöffnet werden, so dass nicht jedes Mal der Bericht am Monitor zu sehen ist, falls das gewünscht wäre.

Und lass bei Outputto den Berichtsnamen weg, bin mir jetzt nicht sicher, ob ansonsten versucht wird, den Bericht nochmal zu öffnen.
Zudem sollten die Objektvariablen (Recordset) noch sauber "entsorgt" werden:

.
.
rst.Close
Set rst =Nothing
.

PhilS

Zitat von: DF6GL am August 28, 2017, 10:07:34Weiterhin könnte der Report auch "hidden" geöffnet werden, so dass nicht jedes Mal der Bericht am Monitor zu sehen ist, falls das gewünscht wäre.

Und lass bei Outputto den Berichtsnamen weg, bin mir jetzt nicht sicher, ob ansonsten versucht wird, den Bericht nochmal zu öffnen.
Nein, der Bericht wird nicht erneut geöffnet, wenn er bereits geöffnet ist, egal ob sichtbar oder nicht.

Der Berichtsname sollte unbedingt bleiben. Besonders in Kombination mit einem unsichtbaren Bericht, wird sonst, für den Fall dass ein weiterer Bericht sichtbar geöffnet ist, der falsche (sichtbare) Bericht als PDF exportiert.
Neue Videoserie: Windows API in VBA

Klassische CommandBars visuell bearbeiten: Access DevTools CommandBar Editor

Alex_80

Danke für die Rückmeldungen. Ich habe die Sachen von Euch umgesetzt, mit dem Ergebnis, dass er mir ein PDF als Report exportiert, allerdings nur jeweils den der letzten Kundennummer. Er macht beide kurz auf, aber legt nur ein PDF ab. Allerdings ist darin nun nur der Inhalt für die entsprechende Kundennummer drin, was ja richtig ist. Wie schaffe ich das denn jetzt, dass er - in diesem Fall - beide PDFs für beide Kundennummern anlegt und nicht nur die letzte?
Mein jetziger Code:
Private Sub Umschaltfläche33_Click()
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim I As Long
Dim M As Double, Ende As Double, MilliSekunden As Double
Set rst = CurrentDb.OpenRecordset("Select Distinct Kundennummer from Patientendaten Order By Kundennummer")
Do While Not rst.EOF
'I = DCount("[Kundennummer]", "Patientendaten", "Kundennummer='" & rst!Kundennummer & "'")
'DoCmd.OpenReport "rpt_Rechnung_org", acViewPreview, , "Kundennummer=" & rst!Kundennummer & ""
DoCmd.OpenReport "rpt_Rechnung_org", acViewPreview, , "Kundennummer=" & rst!Kundennummer & ""
'DoCmd.PrintOut acPrintAll
DoCmd.OutputTo acOutputReport, "rpt_Rechnung_org", "PDF", "X:\Verwaltung\Patientenmanagement\Kostenvoranschläge\KVA Archiv\KVA vom " & Date & " KdNr " & Kundennummer & ".pdf", False
DoCmd.Close acReport, "rpt_Rechnung_org"

Ende = Timer + (MilliSekunden / 100)
Do While M < Ende
  DoEvents
  M = Timer
Loop

rst.MoveNext
Loop
rst.Close
Set rst = Nothing
End Sub


Die Zeile "DCount" habe ich deaktiviert.

DF6GL

Hallo,

und wo stellst Du die "Millisekunden" für die Wartezeit  ein??


Ich empfehle "debuggen"...

Setz einen Haltepunkt an den Schleifenanfang und fahre mit F8 (Einzelschritt) die Schleife durch.  Prüfe bei jedem Schritt den Inhalt der Variablen..


Alex_80

Das habe ich jetzt leider nicht verstanden, was ich machen soll.

Die Millisekunden waren als Trick gedacht, damit eine Pause zwischen der Generierung der Dokumente ist und somit die Trennung besser erkannt wird. Irgendwo hatte ich das mal gelesen. Das funktioniert aber leider auch nicht.

DF6GL

Hallo,

Du sollst die Variable "Millisekunden"  mit einem Wert versehen, damit der Timer auch funktionieren kann...

Wobei eine mSek eine 1/1000 Sekunde ist und keine 1/100....

Alex_80

Guten Morgen,

meinst Du so:

Private Sub Umschaltfläche33_Click()
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim I As Long
Dim M As Double, Ende As Double, MilliSekunden As Double
Set rst = CurrentDb.OpenRecordset("Select Distinct Kundennummer from Patientendaten Order By Kundennummer")
Do While Not rst.EOF
'I = DCount("[Kundennummer]", "Patientendaten", "Kundennummer='" & rst!Kundennummer & "'")
'DoCmd.OpenReport "rpt_Rechnung_org", acViewPreview, , "Kundennummer=" & rst!Kundennummer & ""
DoCmd.OpenReport "rpt_Rechnung_org", acViewPreview, , "Kundennummer=" & rst!Kundennummer & ""
'DoCmd.PrintOut acPrintAll
DoCmd.OutputTo acOutputReport, "rpt_Rechnung_org", "PDF", "X:\Verwaltung\Patientenmanagement\Kostenvoranschläge\KVA Archiv\KVA vom " & Date & " KdNr " & Kundennummer & ".pdf", False
DoCmd.Close acReport, "rpt_Rechnung_org"

Ende = Timer + (1 / 1000)
Do While M < Ende
  DoEvents
  M = Timer
Loop

rst.MoveNext
Loop
rst.Close
Set rst = Nothing

End Sub


Allerdings hat es leider nicht gebracht: Er legt immer noch nur das letzte Dokument an. Also das mit der Kundennummer 2. Er läuft durch beide durch, aber anlegen tut er nur das zweite. Kann Access das überhaupt, so eine Trennung vollziehen? Oder warum klappt das nicht? Bin da echt überfragt.

DF6GL

Hallo,

nein...

eher so:


Dim Millisekunden as Long

Millisekunden = 3500
.
.
Ende = Timer + (Millisekunden / 1000)

.

und einfacher:

Dim dblSek as Double

dblSek = 3.5
.
.
Ende = Timer + dblSek
.




ZitatIch empfehle "debuggen"...

Setz einen Haltepunkt an den Schleifenanfang und fahre mit F8 (Einzelschritt) die Schleife durch.  Prüfe bei jedem Schritt den Inhalt der Variablen..

Alex_80

Ich habe jetzt alles so umgesetzt, aber es tritt keine Änderung ein - er legt weiterhin nur den letzten Datensatz an:

Private Sub Umschaltfläche33_Click()
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim I As Long
Dim M As Double, Ende As Double ', Millisekunden As Double
Dim Millisekunden As Long
Millisekunden = 3500
Set rst = CurrentDb.OpenRecordset("Select Distinct Kundennummer from Patientendaten Order By Kundennummer")
Do While Not rst.EOF
'I = DCount("[Kundennummer]", "Patientendaten", "Kundennummer='" & rst!Kundennummer & "'")
'DoCmd.OpenReport "rpt_Rechnung_org", acViewPreview, , "Kundennummer=" & rst!Kundennummer & ""
DoCmd.OpenReport "rpt_Rechnung_org", acViewPreview, , "Kundennummer=" & rst!Kundennummer & ""
'DoCmd.PrintOut acPrintAll
DoCmd.OutputTo acOutputReport, "rpt_Rechnung_org", "PDF", "X:\Verwaltung\Patientenmanagement\Kostenvoranschläge\KVA Archiv\KVA vom " & Date & " KdNr " & Kundennummer & ".pdf", False
DoCmd.Close acReport, "rpt_Rechnung_org"

Ende = Timer + (Millisekunden / 1000)
Do While M < Ende
  DoEvents
  M = Timer
Loop

rst.MoveNext
Loop
rst.Close
Set rst = Nothing

End Sub


F8 habe ich auch probiert, aber da erscheint nichts. Also gibt es wohl nichts zum debuggen. Gibt es noch irgendwas, wo hier ein Fehler sein könnte?