PDF per VBA erstellen im Detail

Im Beitrag “PDF erstellen mit Access im Detail” (www.access-im-unternehmen.de/1523) haben wir uns bereits angesehen, wie wir PDF-Dokumente über die Benutzeroberfläche erstellen können. Typischerweise möchte man einem Benutzer allerdings nicht die Aufgabe überlassen, einen Bericht zu öffnen und dann die entsprechenden Schaltflächen im Ribbon aufzurufen, um den Bericht als PDF-Dokument zu speichern. Dazu stellen wir einen eigenen Button zur Verfügung, mit dem wir den Bericht direkt als PDF speichern. Es fehlt also nur noch der passende VBA-Befehl. In diesem Beitrag schauen wir uns an, wie dieser lautet und welche Alternativen es gibt. Außerdem werfen wir einen Blick darauf, wie wir Spezialitäten wie Dokumente im PDF/A-Format erzeugen. Während wir dazu über die Benutzerfläche lediglich ein Option im Dateiauswahl-Dialog aktivieren mussten, ist der Aufwand unter VBA bereits deutlich höher. Aber immerhin ist dieser nur einmalig durchzuführen, weshalb wir gern darauf eingehen.

Bericht als PDF exportieren per DoCmd.OutputTo

Die erste und offensichtliche Möglichheit zum Exportieren eines Berichts ist die OutputTo-Methode des DoCmd-Objekts. Diese Methode erwartet die folgenden Parameter:

  • ObjectType: Typ des zu exportierenden Objekts, in diesem Fall acOutputReport
  • ObjectName: Name des Berichts
  • OutputFormat: Ausgabeformat, hier acFormatPDF
  • OutputFile: Pfad der zu erstellenden Datei
  • Autostart: Gibt an, ob die exportierte Datei nach dem Export automatisch angezeigt werden soll.
  • TemplateFile: Relevant für Exporte in andere Dateiformate wie Word oder Excel.
  • Encoding: Nur relevant für den Export in das Textformat.
  • OutputQuality: Gibt die Qualität der zu erstellenden Datei an. Wir können die beiden Werte acExportQualityPrint und acExportQualityScreen angeben.

Ein Aufruf sieht beispielsweise wie folgt aus:

DoCmd.OutputTo acOutputReport, "rptBeispiel", acFormatPDF, CurrentProject.Path & "\rptBeispiel_Screen.pdf", True, , , acExportQualityScreen

Bericht mit Kriterium als PDF exportieren

Natürlich kommt es immer mal vor, dass man einen Bericht genau so als PDF-Dokument speichern möchte, wie man diesen auch per Doppelklick auf seinen Namen im Navigationsbereich anzeigen würde – also ohne die Angabe von Kriterien et cetera.

Allerdings gibt es auch Berichte, die vor der Ausgabe im PDF-Format gefiltert werden sollen. Zu Beispielzwecken haben wir einen weiteren Bericht namens rptArtikel angelegt, der in der Entwurfsansicht wie in Bild 1 erscheint.

Entwurf eines Beispielberichts mit einer Artikelliste

Bild 1: Entwurf eines Beispielberichts mit einer Artikelliste

Wenn wir den Bericht nun gefiltert öffnen, sodass er beispielsweise nur die Artikel mit den Werten bis 10 im Feld ArtikelID ausgibt, öffnen wir diesen wie folgt:

DoCmd.OpenReport "rptArtikel", acViewPreview, , "ArtikelID <= 10"

Das Ergebnis sehen wir in Bild 2. Hier gibt der Bericht wie erwartet nur die ersten zehn Datensätze aus.

Bericht mit Where-Bedingung

Bild 2: Bericht mit Where-Bedingung

Nun schließen wir diesen Bericht und exportieren in im PDF-Format:

DoCmd.OutputTo acOutputReport, "rptArtikel", acFormatPDF, CurrentProject.Path & "\rptArtikel.pdf", True, , , acExportQualityScreen

Dies liefert logischerweise den Bericht mit allen Datensätzen (siehe Bild 3). Nun wollen wir diesen allerdings in gefilterter Form in einem PDF-Dokument speichern.

Artikel-Bericht als PDF

Bild 3: Artikel-Bericht als PDF

Dummerweise liefert uns die DoCmd.OutputTo-Methode keine Möglichkeit, einen Parameter namens WhereCondion für den Bericht anzugeben. Also müssen wir einen alternativen Weg finden, um den Bericht gefiltert auszugeben.

Dazu gehen wir zunächst den folgenden Weg:

  • Wir öffnen den Bericht unter Angabe der WhereCondition in der Seitenansicht.
  • Dann exportieren wir den Bericht.

Das läuft nun ohne Probleme und liefert das gewünschte Ergebnis. Wir öffnen den Bericht, dessen Namen wir zuvor in der Variablen strReport gespeichert haben, mit DoCmd.OpenReport, geben diesen dann mit DoCmd.OutputTo aus und schließen ihn mit DoCmd.Close wieder.

Die verwendete Prozedur sieht wie in Listing 1 aus.

Public Sub ArtikellisteGefiltert()
     Dim strReport As String
     Dim strPfad As String
     strReport = "rptArtikel"
     strPfad = CurrentProject.Path & "\" & strReport & ".pdf"
     DoCmd.OpenReport strReport, acViewPreview, , "ArtikelID <= 10"
     DoCmd.OutputTo acOutputReport, strReport, acFormatPDF, strPfad
     DoCmd.Close acReport, strReport
End Sub

Listing 1: Exportieren der zuvor gefilterten Artikelliste

Achtung, Fehler 2501!

Es kann beim Aufruf der Prozedur DoCmd.OutputTo passieren, dass wir den Fehler 2501 erhalten. Wir haben einige Minuten gebraucht, um herauszufinden, weshalb dieser aufgetreten ist. Der Grund war einfach: Wir hatten die zuvor bereits einmal erzeugte PDF-Datei namens rptArtikel.pdf bereits geöffnet. Eine geöffnete PDF-Datei kann jedoch nicht einfach überschrieben werden. Dabei erscheint die hier wenig aussagekräftige Meldung Die Aktion OutputTo wurde abgebrochen.

Bericht mit dem Standard PDF/A-3 speichern

Im Beitrag PDF erstellen im Detail (www.access-im-unternehmen.de/1523) haben wir gezeigt, wie wir zumindest mit neueren Access-Versionen Berichte so als PDF-Dokumente exportieren konnten, dass diese dem PDF/A-3-Standard entsprechen. Dazu mussten wir im Speichern-Dialog, den wir mit dem Ribbonbefehl Seitenansicht|Daten|PDF oder XPS geöffnet haben, die Optionen einblenden und dort die Option PDF/A-kompatibel aktivieren (siehe Bild 4). Dies führte je nach Access-Version dazu, dass die PDF-Datei im Format PDF/A-1 oder PDF/A-3 erzeugt wurde.

Exportieren im PDF/A-3-Format über die Benutzeroberfläche

Bild 4: Exportieren im PDF/A-3-Format über die Benutzeroberfläche

Wenn wir uns den Speichern-Dialog genauer ansehen, finden wir hier mit Datei nach dem Veröffentlichen öffnen und Optimieren für auch noch zwei Optionen, die wir bereits von der OutputTo-Methode des DoCmd-Objekts kennen. Da stellt sich die Frage, ob wir vielleicht auch noch die PDF/A-3-Kompatibilität per VBA sicherstellen können. Allerdings liefert selbst die Aktivierung der Anzeige versteckter Elemente im Objektkatalog irgendwelche Hinweise auf weitere Möglichkeiten.

Wenn wir den Export-Vorgang über diesen Dialog abschließen, taucht jedoch noch der Schritt Exportschritte speichern auf (siehe Bild 5). Vielleicht liefert dieser ja noch hilfreiche Informationen?

Speichern der Exportschritte

Bild 5: Speichern der Exportschritte

Und was geschieht eigentlich, wenn wir das Speichern der Exportschritte wie im Screenshot aktivieren? Also probieren wir das einmal aus und nennen den Export Exportschritte_rptArtikel.

Danach stellt sich allerdings die Frage, wo diese Exportschritte überhaupt gespeichert werden und wie wir diese nutzen können. Wenn wir erneut versuchen, den Bericht zu exportieren, finden wir jedenfalls keine Gelegenheit, diese auszuwählen.

Suchen wir ein wenig weiter, finden wir allerdings im Ribbon unter Externe Daten einen Befehl namens Gespeicherte Exporte (siehe Bild 6).

Im Ribbon befindet sich ein Button namens Gespeicherte Exporte.

Bild 6: Im Ribbon befindet sich ein Button namens Gespeicherte Exporte.

Klicken wir diesen an, öffnet sich ein Dialog, der unseren gespeicherten Export anzeigt (siehe Bild 7).

Unser gespeicherter Export

Bild 7: Unser gespeicherter Export

Hier haben wir jedoch auch nur die Möglichkeit, den Export nochmals zu starten.

Gespeicherten Export per VBA aufrufen

Logischerweise gibt es auch noch einen VBA-Befehl, mit dem wir einen gespeicherten Export starten können. Dieser ist ebenfalls eine Methode des DoCmd-Objekts und heißt RunSavedImportExport und wir rufen diese wie folgt auf:

DoCmd.RunSavedImportExport "Exportschritte_rptArtikel"

Mit dieser Methode können wir den Bericht exportieren. Die Frage ist noch, ob wir damit eine PDF/A-3-kompatible Datei erstellt haben. Dazu wollen wir nun einen Validierer hinzuziehen.

Validieren, ob ein PDF-Dokument dem Standard PDF/A-3 entspricht

Unter dem folgenden Link haben wir unsere mit Access erzeugten Dokumente auf PDF/A-3 validiert:

https://avepdf.com/de/pdfa-validation

Hier kann man sein Dokument angeben und dieses prüfen lassen. In unserem Beispiel kam das Ergebnis aus Bild 8 heraus.

Validieren von PDF/A-3-Dateien

Bild 8: Validieren von PDF/A-3-Dateien

Auch in der kostenpflichtigen Version von Adobe Acrobat können wir erkennen, ob es sich um eine PDF/A-3-Datei handelt. Wenn wir das PDF-Dokument damit öffnen, erscheint erstens oben die Meldung, dss die Datei schreibgeschützt geöffnet wurde, weil sie Konformität mit dem PDF/A-Standard verlangt (siehe Bild 9).

Validieren von PDF/A-3-Dateien im Adobe Acrobat

Bild 9: Validieren von PDF/A-3-Dateien im Adobe Acrobat

Außerdem sehen wir rechts ein Icon, mit dem wir den Bereich Standards öffnen können (der übrigens bei Dateien ohne PDF/A-Standard gar nicht erscheint). In diesem Bereich erhalten wir die Information, dass dieses Dokument dem Standard PDF/A-3B entspricht.

PDF-Dateien, die nicht mit neueren Access-Versionen erstellt wurden, weisen teilweise nur den Standard PDF/A-1B auf. Wir konnten nicht genau herausfinden, ab welchen Versionen PDF/A-3B erzeugt wird, daher sollte man dies immer selbst prüfen, wenn PDF-Dokumente mit diesem Standard benötigt werden – beispielsweise als Basis für ZUGFeRD-Rechnungen.

Damit haben wir grundsätzlich eine Lösung, mit der wir unseren Bericht im PDF/A-3-Format exportieren können. Wir benötigen allerdings nun noch eine Möglichkeit, die auszugebenden Daten wir im vorherigen Beispiel durch eine WhereCondition festzulegen. Lässt sich dies genau wie zuvor erledigen, indem wir den Bericht mit WhereCondition öffnen, diesen über den gespeicherten Export als PDF-Dokument sprichern, und den Bericht dann wieder schließen?

So etwas findet man nur heraus, indem man es ausprobiert. Unsere Testprozedur sieht so aus, und diesmal wollen wir die ersten 15 Datensätze ausgeben:

Public Sub GespeicherterExportGefiltert()
     Dim strReport As String
     Dim strPfad As String
     strReport = "rptArtikel"
     strPfad = CurrentProject.Path & "\" & strReport & ".pdf"
     DoCmd.OpenReport strReport, acViewPreview, , _
         "ArtikelID <= 15"
     DoCmd.RunSavedImportExport "Exportschritte_rptArtikel"
     DoCmd.Close acReport, strReport
End Sub

Aber können wir damit nun beispielsweise auch einen anderen Bericht öffnen und diesen im PDF/A-3-Format speichern? Wir öffnen also einfach mal unseren ganz einfachen Beispielbericht von Anfang des Beitrags und versuchen, den gespeicherten Export auf diesen anzuwenden:

DoCmd.OpenReport "rptBeispiel", acViewPreview
DoCmd.RunSavedImportExport "Exportschritte_rptArtikel"
DoCmd.Close acReport, strReport

Dies führt allerdings nicht zum gewünschten Ergebnis – es wird der Bericht rptArtikel exportiert, und zwar diesmal mit allen Datensätzen.

Das bedeutet also: Der gespeicherte Export legt das PDF immer für den beim Erstellen des Exports angegebenen Bericht an. Wenn wir den gleichen Bericht während des gespeicherten Exports geöffnet haben, holt sich die Methode RunSavedImportExport aber wohl die WhereCondition vom aktuell geöffneten Datensatz.

Gespeicherten Export anpassen

Damit bleibt noch eine Frage: Wie können wir mithilfe eines gespeicherten Exports einen beliebigen Bericht exportieren, ohne dass wir für jeden zu exportierenden Bericht zuvor einen gespeicherten Export angelegt haben? Hier stellt sich erst einmal die Frage, ob es so viele Berichte gibt, dass man sich genauer ansieht, wie man dies automatisieren könnte. Wenn wir davon ausgehen, dass das PDF/A-3-Format überwiegend zum Erstellen von PDFs für ZUGFeRD-Rechnungen verwendet werden soll, dürfte die Anzahl in den meisten Anwendungen überschaubar sein.

Aber uns reizt schon die Aufgabe, herauszufinden, wo die gespeicherten Exporte gespeichert werden – um diese dann auch noch anpassen zu können. Wie das gelingt, schauen wir uns allerdings in einem eigenen Beitrag namens Gespeicherte Importe und Exporte verwalten (www.access-im-unternehmen.de/1526) an.

Downloads zu diesem Beitrag

Enthaltene Beispieldateien:

PDFErstellenVBA.accdb

Download

Schreibe einen Kommentar