blog.bartlweb - a technologist's external brain

Word-Serienbrief in einzelne Word- oder PDF-Dateien speichern

vereinfachte und verbesserte Version:

formletter2pdf - die Weiterentwicklung des Makros als Open Source-Projekt, mit Einstellungsdialog und Schritt-für-Schritt Anleitung:

www.formletter2pdf.com

Das folgende Makro für Microsoft Word 2007 und Word 2010, dient dazu die einzelnen Schreiben der Serienbrieffunktion als getrennte Dateien zu speichern. Das Makro erfragt nach dem Start nach dem Speicherort. Dabei wird am Speicherort automatisch ein Ordner der die Serienbriefe enthält erstellt. Der Dateiname der einzelnen Dateien wird dabei aus einem der Datenfelder des Serienbriefs generiert. Um die Generierung der Serienbriefe zu beschleunigen, wird während des Vorgangs das Word-Fenster ausgeblendet.

Sub Serienbrief()
' set variables
Dim iBrief As Integer, sBrief As String
Dim AppShell As Object
Dim BrowseDir As Variant
Dim Path As String
' catch any errors
On Error GoTo ErrorHandling

' determine path
Set AppShell = CreateObject("Shell.Application")
Set BrowseDir = AppShell.BrowseForFolder(0, "Speicherort für Serienbriefe auswählen", 0, 16)

If BrowseDir = "Desktop" Then
Path = CreateObject("WScript.Shell").SpecialFolders("Desktop")
Else
Path = BrowseDir.items().Item().Path
End If

If Path = "" Then GoTo ErrorHandling

Path = Path & "\Serienbrief-" & Format(Now, "dd.mm.yyyy-hh.mm.ss") & "\"
MkDir Path

On Error GoTo ErrorHandling

' hide application for better performance
MsgBox "Serienbriefe werden exportiert. Dieser Vorganag kann einige Minuten dauern - Microsoft Word wird während dieser Zeit ausgeblendet", vbOKOnly + vbInformation
Application.Visible = False

' create bulkletter and export as pdf
With ActiveDocument.MailMerge
.DataSource.ActiveRecord = 1
Do
.Destination = wdSendToNewDocument
.SuppressBlankLines = True
With .DataSource
.FirstRecord = .ActiveRecord
.LastRecord = .ActiveRecord
sBrief = Path & .DataFields("ID").Value & ".pdf"
End With
.Execute Pause:=False

If .DataSource.DataFields("ID").Value > "" Then
ActiveDocument.SaveAs FileName:=sBrief, FileFormat:=wdFormatPDF
End If
ActiveDocument.Close False

If .DataSource.ActiveRecord < .DataSource.RecordCount Then
.DataSource.ActiveRecord = wdNextRecord
Else
Exit Do
End If
Loop
End With

' error handling
ErrorHandling:
Application.Visible = True

If Err.Number = 76 Then
MsgBox "Der ausgewählte Speicherort ist ungültig", vbOKOnly + vbCritical
ElseIf Err.Number = 5852 Then
MsgBox "Das Dokument ist kein Serienbrief"
ElseIf Err.Number = 4198 Then
MsgBox "Der ausgewählte Speicherort ist ungültig", vbOKOnly + vbCritical
ElseIf Err.Number = 91 Then
MsgBox "Exportieren von Serienbriefen abgebrochen", vbOKOnly + vbExclamation
ElseIf Err.Number > 0 Then
MsgBox "Unbekannter Fehler: " & Err.Number & " - Bitte Makro erneut ausführen.", vbOKOnly + vbCritical
Else
MsgBox "Serienbriefe erfolgreich exportiert", vbOKOnly + vbInformation
End If

End Sub

Im obigen Skript wird der Dateiname aus dem Feld ID des Serienbrief-Datensatzes generiert. Passen Sie in den Zeilen sBrief = Path & .DataFields("ID").Value & ".pdf" und If .DataSource.DataFields("ID").Value > "" Then den Namen des Datenbankfelds (hier ID) an, um ein beliebiges Datenbankfeld für die Generierung des Dateinamens zu nutzen.

Mittlerweile habe ich das Makro auf vielen unterschiedlichen Systemen benutzt und die Erfahrung gemacht, dass zumindest bei Office 2007 alle aktuellen Updates (Service Pack 3) eingespielt sein müssen, damit das Makro überhaupt läuft.

Aufgrund der zahlreichen Rückmeldungen hier im Blog habe ich das Makro optimiert und als Open Source-Projekt weiterentwickelt. Mehr dazu auf der Projekt-Website www.formletter2pdf.com.

Word-Dokumente anstelle von PDF-Dateien speichern

Das obige Skript nutzt die PDF-Funktion von Office um die Dateien als PDF zu sichern. Um die Dateien im Word Format zu sichern, passen Sie die folgende Zeile an um dem Dateinamen die Endung .doc zu verpassen:

sBrief = Path & .DataFields("ID").Value & ".pdf"

wird zu

sBrief = Path & .DataFields("ID").Value & ".doc"

Und ändern Sie die folgende Zeile, um das Ausgabeformat von PDF auf Word umzustellen:

ActiveDocument.SaveAs FileName:=sBrief, FileFormat:=wdFormatPDF

wird zu

ActiveDocument.SaveAs FileName:=sBrief

Variante für Office for Mac

Microsoft Office unter Windows und Office for Mac unterscheiden sich in diversen Funktionen und den Möglichkeiten in der Makroprogrammierung. Daher hier der adaptierte Code für Office for Mac (bisher nur unter Office for Mac 2011 getestet):

Sub Serienbrief()
' set variables
Dim iBrief As Integer, sBrief As String
Dim AppShell As Object
Dim BrowseDir As Variant
Dim Path As String
' catch any errors
On Error GoTo ErrorHandling

' determine path
Path = MacScript("(choose folder with prompt ""Speicherort für Serienbriefe auswählen"") as string")
If Path = "" Then GoTo ErrorHandling

Path = Path & "Serienbrief-" & Format(Now, "dd.mm.yyyy-hh.mm.ss") & ":"
MkDir Path

On Error GoTo ErrorHandling

' hide application for better performance
MsgBox "Serienbriefe werden exportiert. Dieser Vorganag kann einige Minuten dauern - Microsoft Word wird während dieser Zeit ausgeblendet", vbOKOnly + vbInformation
Application.Visible = False
Application.ScreenUpdating = False
Application.DisplayAlerts = False

' create bulkletter and export as pdf
With ActiveDocument.MailMerge
.DataSource.ActiveRecord = 1

.Destination = wdSendToNewDocument
.SuppressBlankLines = True
.DataSource.ActiveRecord = wdLastRecord

RecordCount = .DataSource.ActiveRecord
.DataSource.ActiveRecord = 1

Do
With .DataSource
.FirstRecord = .ActiveRecord
.lastRecord = .ActiveRecord
sBrief = Path & .DataFields("ID").Value & ".pdf"
End With
.Execute Pause:=False

If .DataSource.DataFields("ID").Value > "" Then
ActiveDocument.SaveAs fileName:=sBrief, FileFormat:=wdFormatPDF
End If
ActiveDocument.Close False

If .DataSource.ActiveRecord < RecordCount Then
.DataSource.ActiveRecord = .DataSource.ActiveRecord + 1
Else
Exit Do
End If
Loop
End With

' error handling
ErrorHandling:
Application.Visible = True

If Err.Number = 76 Then
MsgBox "Der ausgewählte Speicherort ist ungültig", vbOKOnly + vbCritical
ElseIf Err.Number = 5852 Then
MsgBox "Das Dokument ist kein Serienbrief"
ElseIf Err.Number = 4198 Then
MsgBox "Der ausgewählte Speicherort ist ungültig", vbOKOnly + vbCritical
ElseIf Err.Number = 91 Then
MsgBox "Exportieren von Serienbriefen abgebrochen", vbOKOnly + vbExclamation
ElseIf Err.Number > 0 Then
MsgBox "Unbekannter Fehler: " & Err.Number & " - Bitte Makro erneut ausführen.", vbOKOnly + vbCritical
Else
MsgBox "Serienbriefe erfolgreich exportiert", vbOKOnly + vbInformation
End If

End Sub

Dieser Artikel hat Dir deinen Tag gerettet?

... und mühevolles Probieren, Recherchieren und damit Stunden an Zeit gespart? Oder einfach nur Dein Problem gelöst?

Dann würde ich mich freuen, wenn Du meine Zeit für die Erstellung dieses Blogartikels mit einer kleinen Anerkennung honorierst:

Zahlung mit PayPal oder Kreditkarte.

Hinweis zur Verwendung

Die Übermittlung einer Zahlung ist eine persönliche Anerkennung Ihrerseits an den Entwickler (Christian Bartl, Privatperson). Eine Zahlung ist nicht zweckgebunden und es ist keine Gegenleistung zu erwarten. Bitte beachten Sie, dass für eine übermittelte Zahlung keine Quittung ausgestellt werden kann.

Über den Autor

Christian Bartl

Christian Bartl Requirements Engineer
& Solution Architect für Online und Mobile

Als Technologie-Enthusiast und begeisterter Programmierer entwickle ich in meiner Freizeit Websites, Software und IT-Lösungen, die mir selbst und anderen den Alltag vereinfachen.

mehr auf christian.bartl.me

Kommentare

Zu diesem Artikel können keine neuen Kommentare mehr abgegeben werden.

  1. Vielen Dank, das Macro laeuft fast einwandfrei! Es gibt nur ein kleines Problem, es endet nicht!
    Ich habe
    sBrief = Path & .DataFields("ID").Value & ".pdf"
    angepasst:
    sBrief = Path & .DataFields("Customer").Value & .DataFields("Quote_Number").Value & ".pdf"
    Das als letzter Brief von Word angezeigte Dokument hat noch einen Customer Namen. Trotzdem scheint das Macro ein Dokument speichern zu wollen, dass weder Customer noch Quote_Number besitzt, und somit keinen gueltigen Speichernamen besitzt.
    Die Daten fuer den Serienbrief beziehe ich aus einer Exceltabelle, von der 115 Zeilen befuellt sind, danach sind nur noch Leerzeilen, von denen allerdings einige Felder Formeln enthalten. Diese kann ich aber auch nicht loeschen, da monatlich neue Eintraege hinzukommen koennen. Und eigentlich duerfte das kein Problem sein, da Word in der Serienbrieffunktion ja sowieso nur die Values uebernimmt, und nicht die Formeln, oder?
    Kann ich den Code erweitern, sodass das Macro automatisch stoppt, wenn das Feld "Customer" nicht befuellt ist?

    Danke fuer die Hilfe schonmal!

    1. Ich habe das Makro so adaptiert, dass es bei Fehlen einer ID kein Dokument speichert, damit läuft das Makro nun auch bei einer nicht vollständigen Quelldatei durch.

      1. bin anfaenger...wo fuege ich das kopierte makro in word ein?

  2. Macro funktioniert eigentlich toll, aber es ist leider instabil. Ich würde gerne 5000 Dokumente speichern, aber bei ca 90 hängt er sich auf und sagt "Angegebener Speicherort ist ungültig". Woran könnte das liegen, es sind jeweils mehrere Seiten.

    1. Das Makro ist mit 500 Dokumenten (Einzelseiten) getestet und hat dort immer ohne Abbrüche funktioniert. Hast du vielleicht in der Datenspalte, die für die Erstellung des Dateinamens benötigt wird, leere Einträge?

  3. Vielen Dank für das Makro - Damit es bei mir fehlerfrei läuft, muss ich allerdings auch in der Zeile

    If .DataSource.DataFields("ID").Value > "" Then

    ID durch den jeweiligen Eintrag in meiner Datenquelle ersetzen.

  4. Hallo zusammen,

    das ist genau das, was ich gerade suche.
    Ich habe allerdings (noch) keinen blassen Schimmer von Makroprogrammierung.

    Ich hab es versucht einfach einzufügen und den Dateinamen von "ID" zu "Firmenname" (dem Namen des entsprchenden Seriendruckfeldes) an den folgenden zwei Stellen abzuändern zu:

    sBrief = Path & .DataFields("Firmenname").Value & ".pdf"

    und

    If .DataSource.DataFields("Firmenname").Value > "" Then

    Das Makro startet, ich wähle den Speicherort aus und bestätige den Dialog, dass Word ausgeblendet wird.

    Und dann bekomme ich immer eine Fehlermeldung "Unbekannter Fehler: 4605 - Bitte Makro erneut ausführen."

    Hat jemand eine Ahnung, was ich falsch mache?
    Liegt es eventuell daran, dass in den Firmennamen Leerzeichen enthalten sind?

    Vielen Dank für Eure Hilfe vorab
    und
    viele Grüße
    Ingo

    1. Hallo zusammen,

      hab den Fehler gefunden.
      Es lag nur am Speicherort. :-(

      Jetzt läuft es super!
      Vielen Dank dafür.

      Viele Grüße
      Ingo

  5. Hallo,

    hab den Code so eingefügte wie es oben beschrieben wurde.
    Nachdem ich das Makro gestartet hab bekomme ich die Frage wohin ich die Datei speichern soll. Soweit so gut.
    Nach dem Info-Banner "Serienbriefe werden exportiert. Dieser Vorgang kann einige Minuten dauern - Microsoft Word wird während dieser Zeit ausgeblendet" erhalte ich folgende Fehlermeldung: "Unbekannter Fehler: 5941 - Bitte Makro erneut ausführen" . Kenn mich mit Makro-programmierung nicht wirklich aus und wäre dankbar für jeden Tipp, Hinweis oder Lösungsvorschlag.

    Viele Grüße
    K

    1. Hey Kalle,

      ich hab auch nicht wirklich Ahnung von Macros, aber es mal mit dem Speicherort c:/
      Ich hatte es immer versucht auf dem Desktop abzuspeichern und hab deshalb eine Fehlermeldung bekommen.

      Hast Du ansonsten vielleicht in den Feldern, die Du für den Dateinamen heranziehst Zeichen, welche nicht für Dateinamen verwendet werden dürfen? (@,:,/ usw.)

      Wie gesagt, ich hab eigentlich keine Ahnung von Macros, das oben sind nur Sachen über die ich gestolpert bin.

      Viele Grüsse
      Ingo

      1. Hallo Ingo,

        danke für den Hinweis. Bin es nach besten Wissen noch einmal durchgegangen, hab auch direkt auf c: versucht zu speichern, leider bekomme ich noch immer die Fehlermeldung "Unbekannter Fehler: 5941 - Bitte Makro erneut ausführen" . Ich Arbeite mit Office 2010 - eventuell hier der Fehler?! Ansonsten hier der Code für das Makro welches ich nutze:

        Sub Serienbrief()
        ' set variables
        Dim iBrief As Integer, sBrief As String
        Dim AppShell As Object
        Dim BrowseDir As Variant
        Dim Path As String

        ' catch any errors
        On Error GoTo ErrorHandling

        ' determine path
        Set AppShell = CreateObject("Shell.Application")
        Set BrowseDir = AppShell.BrowseForFolder(0, "Speicherort für Serienbriefe auswählen", 0, 16)

        If BrowseDir = "Desktop" Then
        Path = CreateObject("WScript.Shell").SpecialFolders("Desktop")
        Else
        Path = BrowseDir.items().Item().Path
        End If

        If Path = "" Then GoTo ErrorHandling

        Path = Path & "\Serienbrief-" & Format(Now, "dd.mm.yyyy-hh.mm.ss") & "\"
        MkDir Path

        On Error GoTo ErrorHandling

        ' hide application for better performance
        MsgBox "SeSerienbriefe werden exportiert. Dieser Vorgang kann einige Minuten dauern - Microsoft Word wird während dieser Zeit ausgeblendet", vbOKOnly + vbInformation
        Application.Visible = False

        ' create bulkletter and export as doc
        With ActiveDocument.MailMerge
        .DataSource.ActiveRecord = 1
        Do
        .Destination = wdSendToNewDocument
        .SuppressBlankLines = True
        With .DataSource
        .FirstRecord = .ActiveRecord
        .LastRecord = .ActiveRecord
        sBrief = Path & .DataFields("bsz").Value & ".doc"
        End With
        .Execute Pause:=False

        If .DataSource.DataFields("BSZ").Value > "" Then
        ActiveDocument.SaveAs FileName:=sBrief
        End If
        ActiveDocument.Close False

        If .DataSource.ActiveRecord 0 Then
        MsgBox "Unbekannter Fehler: " & Err.Number & " - Bitte Makro erneut ausführen.", vbOKOnly + vbCritical
        Else
        MsgBox "Serienbriefe erfolgreich exportiert", vbOKOnly + vbInformation
        End If

        End Sub

        Wie schon erwähnt, wäre ich sehr sehr dankbar für jeden Tipp oder Hinweis.

        Viele Grüße

        K

        1. stellt mal den errorhandler aus (also auskommentieren mit dem hochkomma') und postet den dann auftretenden fehler und die zeile in der es passiert

          1. der Fehler liegt möglicherweise hier:
            sBrief = Path & .DataFields("bsz").Value & ".doc"

            Tausche "BSZ" gegen die in in der Empfängerliste verwendete Spaltenüberschrift. Z.B. "F21".
            Hat bei mir funktioniert!

  6. Hallo,

    das Makro funktioniert bei mir auch, es kommt auch diese Fehlermeldung, was mich aber weiter nicht stört. Klick ich einfach weg ... ;-).
    Leider hab ich auch null Ahnung von VBA und Makroprogrammierung.

    Kann mir vielleicht jemand sagen, wie die getrennten Dateien aus dem Serienbrief als rtf-Dateien gespeichert werden können. Wir dürfen einer Behörde die Texte nur als rtf zusenden nicht als doc. Ich hatte auch schon versucht hier sBrief = Path & .DataFields("ID").Value & ".rtf"
    einzugeben, funktioniert aber leider nicht. Da macht "er" gar nix.
    Wäre über jede Hilfestellung sehr dankbar.

    Viele Grüße
    Inge

    1. Hallo nochmal,

      noch eine Ergänzung zu oben genannten rtf-Problem. Er macht schon Dateien, allerdings keine rtf sondern docx. Es steht auch die Dateinamenerweiterung .rtf dahinter, aber geht man auf speichern unter, ist der Dateityp "Worddokument docx" eingestellt. Gibt es hierfür eine Lösung?
      Schon mal vielen, vielen Dank vorab.
      Inge

    2. Das Ändern der Dateiendung auf .rtf. Also der Zeile

      sBrief = Path & .DataFields("ID").Value & ".pdf"

      auf

      sBrief = Path & .DataFields("ID").Value & ".rtf"

      ist ein guter Anfang. Du musst allerdings auch noch das Ausgabeformat auf RTF stellen und damit die folgende Zeile

      ActiveDocument.SaveAs FileName:=sBrief, FileFormat:=wdFormatPDF

      wie nachstehend abändern:

      ActiveDocument.SaveAs FileName:=sBrief, FileFormat:=wdFormatRTF

      1. Hallo Christian,

        super, super, super!!! Klappt perfekt!!!

        Vielen, vielen Dank.

        Das ist mal ein guter Wochenstart.
        LG
        Inge

  7. Hallo Christian,

    eine Frage noch. Kann man das Makro (rtf) noch dahingehend erweitern, dass es mir vor der Aufteilung in die einzelnen Dateien, alle Änderungen im Dokument annimmt (Menüpunkt - "Überprüfen" - "Annehmen" - "Alle Änderungen im Dokument annehmen"?

    Vielen Dank schon mal vorab.

    Viele Grüße
    Inge

    1. Hallo Inge,

      der Experte für Makro-Programmierung bin ich leider auch nicht. Eine schnelle Internetrecherche hat ergeben das dir der Befehl "AcceptAllRevisions" helfen könnte. Ohne es getestet zu haben:

      Probier einmal vor deiner Zeile
      ActiveDocument.SaveAs FileName:=sBrief, FileFormat:=wdFormatRTF
      folgende Zeile einzufügen
      ActiveDocument.AcceptAllRevisions

      Liebe Grüße,
      Christian

      1. Du bist super! Hat geklappt!
        Danke Dir!
        Schöne Woche und liebe Grüße
        Inge

  8. Hallo,

    bei mir läuft das Makro auch.

    Allerdings exportiert es nur den ersten Datensatz und nicht alle. Hat dafür jemand eine Erklärung?

    Grüße
    Yves

    1. Hallo Yves,
      eine Erklärung habe ich dafür leider nicht, aber prüfe doch einmal die folgenden zwei Punkte:
      - Kannst du dir in Word die einzelnen Serienbriefe in der Vorschau ansehen?
      - Hast du vielleicht für die Erzeugung des Dateinamen das falsche Datenfeld genutzt bzw. ist hier vielleicht nur in der ersten Zeile ein Wert enthalten?

      lg Christian

  9. Vielen Dank ersteinmal für diesen sehr Umfangreichen Postvorgang hilft mir ebenfalls sehr viel weiter.

    nur habe ich das problem das ich aus meiner .dotm
    die saveas anweisung in eine .doc mache, und danach die .doc trotzdem noch die macros...

    Kann ich nicht als .doc ohne macros speichern?

    Gruß,
    Jan

    1. Hallo Jan,
      wenn du deine Dokumente über den unteren Befehl speicherst werden auch keine Makros mitgespeichert. Hast du dein Makro vielleicht in Normal.dot anstelle des eigentlichen Dokuments gespeichert, dann wird es dir nämlich in jedem geöffneten Word-Dokument angezeigt.

      ActiveDocument.SaveAs FileName:=sBrief, FileFormat:=wdFormatXMLDocument

      lg Christian

  10. Hallo

    Vielen Dank für das Makro aber es funktioniert nicht richtig. Bei mir ist auch das Problem obwohl ich nun sogar in meiner Excel Steuerdatei ein Feld ID eingefügt habe und ich jeden Datensatz in der Vorschau einwandfrei sehe, ich trotzdem immer nur einen Datensatz erstellt bekomme. Was mache ich falsch? Bitte um einen Tipp. Danke

  11. Ich habe das Problem gelöst habe anstatt eine dotm ein docm erstellt nun funktioniert der Marco Transfer in die docx nicht mehr :))) an sascha ich habe nicht ganz verstanden was du möchtest also aus einer Excel ein doc Machen oder wie?

    1. Hi Jan

      also die Excel Datei ist die Stuerdatei mit den Datensätzen und da ich mir nicht sicher war ob ich richtig referenziert hatte, dachte ich ich füge einfach in meine Excel Tabelle eine Spalte mit "ID" ein und nummeriere diese durch. Auf jeden Fall habe ich 35 Datensätze und keine Leerfelder und in der Vorschau alle 35 Seiten in der Ansicht, aber das Makro hört einfach nach dem ersten Datensatz auf. Das lustige ist wenn ich If .DataSource.ActiveRecord .DataSource.RecordCount Then
      .DataSource.ActiveRecord = wdNextRecord

      ändere läuft er durch aber leider in einer Endloschleife die sich nicht abbrechen lässt aber immerhin erstellt mir das Makro dann alle 35 Datensätze. Irgendwo passt es nicht. Office ist 2010.

      Grüße

      1. Misst ich sehe Gerade es hat gar nicht den ganzen Code kopiert egal, also wenn ich an der Stelle einfach von ändere dann erstellt mir eben das Makro alle Datensätze aber läuft in ner Endlosschleife.

        Grüße

  12. Okay also ich bin auch noch nicht lange dabei aber du brauchst 2 Dateien 1 Word mit dem Macro und eine Excel mit Name mailmerge also auch den blatt nane und einer Spalte id wenn ich das richtig lese Auf

  13. Aber mit dem if leer dann exit do müsste es stoppen evtl deine Formatierung prüfen

  14. Eine Frage
    Ich bekomme leider auch nur einen Brief gespeichert obwohl Ich alle in der Vorschau sehe. Liegt es vielleicht an der Datenquelle. Wenn Ich eine Word-Tabelle habe erstellt er mir nur einen Brief. Wenn Ich aber eine Excel Tabelle habe erstellt er mir alle. Es soll aber eine Word-Tabelle sein. was muß Ich ändern?

  15. Ich habe ein Problem mit dem Ausführen.
    Es kommt die Meldung "Fehler beim Kompilieren: Syntaxfehler".

    Im Makro selbst erhalte ich den Hinweis, dass folgende Angabe nicht stimmt:

    If .DataSource.ActiveRecord 0 Then

    Kann jemand helfen? Ich arbeite mit einem Serienbrief, der sich seine Daten aus Access gezogen hat.

    Leider bin auch auch blutiger Anfänger, was VBA betrifft...

    Herzlichen Dank und Viele Grüße,
    André!

    1. Hallo André,
      hatte trotz funktionierenden Codes auch des Öfteren das beschriebene Problem. Habe darauf hin das Makro neu angelegt bzw. so weit ich mich erinnere auch ein neues Dokument erstellt.
      lg Christian

  16. You made my day!!!!!
    Das ist exakt genau das, was ich benötige. Vielen Dank.

    Läuft super!!

  17. Hallo zusammen,

    erstmal ist ein super Makro!

    jetzt wollte ich das ganze jedoch auch einem anderen Makro heraus starten. Quasi Das Serienbriefformular öffnen Die Exceldatenquelle einbinden und dann automatisch die einzelnen PDFs speichern!

    Er öffnet auch das Dco und verbindet das excel -> macht einen Serienbrief.
    Er öffnet auch den ersten serienbrief(Serienbrief1.doc) als Word bricht dann aber ab:

    Sub Serienb_erst()

    Dim iBrief As Integer
    Dim sBrief As String
    Dim AppShell As Object
    Dim BrowseDir As Variant
    Dim Path As String
    Dim WordApp As Object
    Dim wrdDoc As Object
    Dim tmpDoc As Object
    Dim WDoc As String
    Dim myDoc As String
    Dim Word As Object
    Dim strDatenQuelle As String
    Dim WinDoc As Object

    Const WD_STORY = 6

    Set Word = CreateObject("Word.Application")
    strDatenQuelle = "Pfad zur .xlsx"

    Word.Visible = True

    With Word
    Set WinDoc = Word.Documents.Open("Pfad zum Formular.docx")

    End With
    Path = "Pfad zum \Output\"
    With WinDoc.MailMerge
    .OpenDataSource Name:=strDatenQuelle, LinkToSource:=True, Format:=0, SQLStatement:="SELECT * FROM `Tabelle1$`"
    .Destination = 0
    .SuppressBlankLines = True

    .DataSource.ActiveRecord = 1
    Do
    .Destination = wdSendToNewDocument
    .SuppressBlankLines = True
    With .DataSource
    .FirstRecord = .ActiveRecord
    .LastRecord = .ActiveRecord
    sBrief = Path & .DataFields("ID").Value & ".pdf"
    End With
    .Execute Pause:=False

    If .DataSource.DataFields("ID").Value > "" Then
    ActiveDocument.SaveAs Filename:=sBrief, FileFormat:=wdFormatPDF
    End If
    ActiveDocument.Close False

    If .DataSource.ActiveRecord < .DataSource.RecordCount Then
    .DataSource.ActiveRecord = wdNextRecord
    Else
    Exit Do
    End If
    Loop
    End With

    End Sub

  18. Hallo,

    erstmal vielen Dank für das klasse Makro, funktioniert echt super! Leider läuft das Makro nicht so stabil und bei ca. 200 Datensätzen stürzt es immer wieder ab. Ich bekomme dann die Fehlermeldung: Der ausgewählte Speicherort ist ungültig. Ich habe in der relevanten Excel-Spalte keine Sonderzeichen... Habt ihr Erfahrungen oder Lösungen für dieses Problem?

    Vielen Dank!

    Max

  19. Das Makro funktioniert toll - vielen Dank dafür!
    Meinen Kollegen passiert es allerdings immer wieder, dass in den beiden Felder, die ich verwendet habe um einen eindeutigen Dateinamen zu erzeugen, für Dateinamen ungültige Zeichen enthalten sind. Könnte man dies nicht im Makro abfangen? Am besten, in dem die Zeichen rausgelassen werden. In SQL gäbe es dafür "replace"...

  20. Hallo,

    vielen Dank für das super Makro.
    Hab mich durch die Beiträge gelesen, aber noch keine Antwort erhalten, woran es liegen könnte, dass nur die 1. Datei erzeugt wird.
    Hat jm. noch eine Idee?

    Alle Dokumente werden in der Vorschau angezeigt.
    Und komischerweise werden im Debugging-Modus auch alle Dokumente erzeugt, nur beim "normalen" Ausführen nicht.

    Danke schon mal!

  21. Hallo!

    Ich bin sehr froh, dass es dieses Makro gibt. Es ist genau das, was ich benötige.

    Allerdings habe ich bis dato noch nie Makros eingesetzt bzw. bin damit vollkommen unerfahren. Habe es jetzt geschafft, ein Makro "Serienbrief" zu erstellen. Habe dann einfach im Editierfenster alles gelöscht und den oben angeführten Code eingefügt. Wenn ich dann auf Makro ausführen gehe, bekomme ich diese Fehlermeldung:
    https://www.box.net/shared/t1woeiy9hpl93q32hlj7

    Kann mir bitte jemand helfen? Was mache ich falsch? Danke und lg
    Andreas

    1. Bitte helft mir!

      Wenn ich den Code einfüge und Makro ausführen klicke, kommt die Fehlermeldung:

      Fehler beim Kompilieren. Sub oder Function nicht definiert.
      Die Meldung bezieht sich auf: Sub Serienbrief()

      Was mache ich falsch?
      Danke
      Andreas

      1. Hallo Andreas,
        verwendest du vielleicht schon Word 2013? - hier hab ich das Makro nie getestet. Ansonsten teste einmal das Makro in einem neu erstellten Dokument, anstelle deines bestehenden. Hast du auch den ganzen Code beim Kopieren erwischt, dass dieser auch mit "End Sub" endet?
        lg Christian

  22. Hallo Christian!

    Danke für deine Antwort.
    Ich verwende MS Word 2010 professional.

    Habe den Makro Edition gestartet, alles gelöscht und deinen Code eingefügt. Auch End Sub .... aber leider kommt noch immer die gleiche Fehlermeldung ....

  23. Hallo Zusammen,

    Danke - Tolles Makro!
    Bin ebenso VBA Anfänger, aber es klappt super. Ein Frage hätte ich:
    Ich würde gerne mehrere Daten mit in die Benennung der neuen Datei mit einbeziehen:
    sBrief = Path & .DataFields("Familien_ID") & .DataFields("Vorname").Value & ".pdf"
    Das klappt auch soweit, ich bräuchte aber ein Trennung (Leerzeichen, Minus, Unterstrich, Punkt oder sonstwas) zwischen der Familien ID und dem Vornamen. Gibt es da eine Möglichkeit.

    Wäre sehr dankbar!
    Ela

    1. Hallo Ela,

      du kannst Textbausteine genauso mit & Verknüpfen solange du sie unter Anführungszeichen setzt.

      sBrief = Path & .DataFields("Familien_ID").Value & "-" & .DataFields("Vorname").Value & ".pdf"

      Christian

  24. Guten Abend Christian,

    VIELEN DANK - so einfach kann es manchmal sein...

    VG
    Ela

  25. Leider geht das Makro noch immer nicht ....

    1. Hallo Andreas,
      ist leider etwas schwer von der Ferne eine Diagnose zu stellen. Hast du alle Office-Updates eingespielt? - Ich hatte einmal einen Fall wo das Makro auf Grund eines fehlenden Updates einfach nicht laufen wollte.
      Christian

  26. Wenn ich die Serienbriefe als Word-Dateien speichere, funktioniert alles bestens. SUPER
    Wenn ich haber die Briefe als *.pdf-Dateien haben möchte, sieht primär auch alles bestens aus. Nur wenn ich die Dateien anschauen möchte, kommt sowohl beim "Adobe Reader" wie auch beim "Adobe Acrobat Professional" eine Fehlermeldung:
    "...konnte *.pdf nicht öffnen, da der Dateityp nicht unterstützt wird oder die Datei beschädigt ist ..."

    Wo ist der Wurm?

    1. Zusatz: Ich arbeite "noch" mit WORD 2003!!!

    2. Hallo Hartmut,
      Word 2003 kann noch keine PDF-Dateien erstellen, daher erhältst du auch fehlerhafte Dateien. Eine Lösung kann ich dir in diesem Fall also leider nicht anbieten.
      Christian

  27. Hallo,

    ich arbeite zum ersten Mal mit Makros überhaupt. Ich habe einen Serienbrief erstellt in Word 2010, der auch einwandfrei funktioniert. Nun möchte ich die daraus entstehenden Dateien einzeln abspeichern. Ich habe das Makro oben kopiert und eingefügt. Führe ich es aus, erhalte ich immer wieder die Fehlermeldung "Unbekannter Fehler: 5941 - bitte Makro erneut ausführen".

    Nun habe ich gesehen, dass unter dem Makro steht:

    "Im obigen Skript wird der Dateiname aus dem Feld ID des Serienbrief-Datensatzes generiert. Passen Sie die Zeile sBrief = Path & .DataFields("ID").Value & ".pdf" an um ein beliebiges Datenbankfeld für die generierung des Dateinamens zu nutzen." Hängt die Fehlermeldung hiermit zusammen? Da ich blutige Anfängerin bin, weiß ich ehrlich gesagt nicht so genau, was mit "Datenbankfeld" gemeint ist. Was muss ich an dem Makro abändern bzw. anpassen, dass es läuft?

    Ich habe auch versucht, das Makro in Einzelschritten bzw. in Prozedurschritten ablaufen zu lassen. Die Fehlermeldung kommt erst hier:

    ElseIf Err.Number > 0 Then

            MsgBox "Unbekannter Fehler: " & Err.Number & " - Bitte Makro erneut ausführen.", vbOKOnly + vbCritical

    Ich verzweifel langsam... ;o) Kann mir bitte jemand helfen? Ich wäre sehr dankbar!!!

    Viele Grüße,

    Sonja

    1. Hi,

      Mit "Datenbankfeld" ist die Spaltenüberschrift deiner Tabelle gemeint. Daraus wird dann der Dateiname generiert.
      Du musst also die beiden ("ID") durch eine Spaltenüberschrift deiner Tabelle ersetzen.

      Bei mir lag das mit "Unbekannter Fehler: 5941", daran, dass mein Feld E-Mail hieß, Word das aber zu EMail gemacht hat. Danach hat alles wunderbar funktioniert.

  28. super makro - nach einigen Startschwierigkeitan am Laufen - wichtig : "ID" durch Spaltenüberschrift ersetzen!

  29. Hallo!

    Ich versuche zur Zeit auch dieses Makro zu benutzen. Ich stoße aber meine Grenzen sobald ist versuche es als .dotx zu speichern.

    Der Mittelteil des Codes sieht bei mir so aus:

    With .DataSource
    .FirstRecord = .ActiveRecord
    .LastRecord = .ActiveRecord
    sBrief = Path & .DataFields("Speicher").Value & ".dotx"
    End With
    .Execute Pause:=False

    If .DataSource.DataFields("Speicher").Value > "" Then
    ActiveDocument.SaveAs FileName:=sBrief, FileFormat:=wdFormatdotx

    Ein weiteres Problem ist, dass alle Einzelbriefe Textfelder haben sollen. Ich benutze Word 2010, will aber gerne die Textfelder aus den Vorversionen benutzen, da die komfortabler sind als die Neuen.

    Kann mir da jemand weiterhelfen?

    Gruß
    Bluemotion

  30. Hi Christian,

    ich benutzte Word 2007. Habe dein Makro unter Enwicklertools Markos eingefügt und lediglich den Speicherort definiert. ( Set BrowseDir = AppShell.BrowseForFolder(0, "d:\testen", 0, 16).
    Habe auch schon das Makro in ein neues Dokument eingefügt und neue Serienbriefe angelegt. Hilft Alles nicht. Jedes mal erscheint die Meldung "Fehler beim kompilieren: Sprungmarke nicth definiert. (Die Zeile "On Error GoTo ErrorHandling"wird dabei immer markiert) Was ist eine Sprungmarke? Wo liegt der Fehler bei mir. Vielen Dank vorab. Gruß Jochen

    1. Hallo Jochen,
      vermutlich liegt es daran, dass du den Code durch die Pfadangabe ergänzt hast. Die von dir veränderte Codezeile ruft nämlich einen Dialog zur Auswahl des Pfades auf und du kannst daher keinen direkt Pfad angeben. Die von dir durch den Pfad ersetzte Zeichenfolge definiert lediglich den Titel des Dialogs.
      Sollte das nicht helfen, kontrolliere noch einmal ob du wirklich den gesamten Code kopiert hast (du kannst nach dem Erstellen des Makros, einfach alle bereits vorhandenen Zeilen durch obigen Code ersetzten).
      lg Christian

  31. Super Skript!!! Fkt gut !!
    Eine Frage noch:

    Ich möchte gerne die Excel-Zeilennummer des aktuellen Datensatzes verarbeiten. Mit welchem Befehl geht das??

    vermutlch irgendwas mit .DataSource ???

    Dank und Gruß
    Bernd

    1. Hallo Bernd,
      am einfachsten fügst du in der Schleife eine Variable hinzu, die du bei jedem Durchlauf um 1 erhöhst, damit solltest du die entsprechende Zeilennummer aus Excel haben und diese für den Dateinamen nutzen können. Wenn du die Zeilennummer allerdings im Serienbrief selbst nutzen willst, wirst du dafür im Ausgangsdokument wahrscheinliche eine eigene Spalte mit fortlaufender Nummerierung ergänzen müssen.
      lg Christian

  32. Hallo Christian,

    wir verwenden Dein Makro seit einigen Monaten und es funktioniert hervorragend.
    Leider bekamen wir jetzt von der Behörde eine Auflage, dass in der PDF-Datei KEINE Kopf- und Fußzeile vorhanden sein darf. Es soll also für die Erstellung der geeinzelten PDF´s keine Kopf- und Fußzeile enthalten sein, nach der Erstellung soll aber die Kopf- und Fußzeile mit gleichen Inhalt wieder im Word-Dokument erscheinen. Gibt es da eine Möglichkeit? Danke schon mal für Deine Mühe.
    Viele Grüße Inge

    1. Hallo Inge,
      es gibt sicher eine Möglichkeit, die Anforderung über die Textformatierung "verstecken" per Makro zu lösen. Allerdings bin ich selbst nicht der Makro-Experte um den Code ohne größeren Rechercheaufwand daran anzupassen.
      Daher würde ich einmal den eher pragmatischen Weg vorschlagen: Wenn du den Serienbrief erstellst und auch schon deine Datenquelle gewählt hast, kannst du diesen Speichern und Schließen. Dann die Datei im selben Verzeichnis kopieren und die neue Datei öffnen. Beim erneuten Öffnen wird der Serienbrief mit deiner gewählten Quelldatei sofort geladen, du kannst die Kopf- und Fußzeile entfernen, den Serienbrief als PDF exportieren und danach die temporäre Datei wieder löschen.
      lg Christian

  33. Vielen Dank für dieses super Skript!

    Hat mir mein Leben gerettet ... oder zumindest doch deutlich einfacher gemacht.

    Weiter so!

    Marcus

  34. Danke,
    Tolles Script, einfach und für einen Halbprofi auch zum Debugen.
    Fehler 5941: Es muss in den Daten eine Spalte ID vorhanden sein. Spalte eingefügt, dann hats geklappt.
    Danke, Lois

  35. Hallo,
    Makro funktioniert super wenn man die beiden Zeilen in denen "ID" vorkommt durch ein Seriendruckfeld ersetzt.

    Bei mir werden allerdings die Seriendruckfelder aus dem Dokument gelöscht sobald das Makro ausgeführt wurde.
    Kann mir jemand dazu etwas sagen?

    1. Hallo Christoph,

      aus welchem Dokument werden die Felder gelöscht?

      Du hast ja drei Dateien (Beispiel):
      - eine "Adressen.xls". Dort steht in der ersten Zeile: Name, Vorname, Ort
      - eine "Serienbrief.doc". Dort steht dann "Sehr geehrter Herr aus
      - Mit dem Macro erzeugst du eine Datei "Müller_Max.doc". In dieser steht dann "Sehr geehrter Herr Max Müller aus Lüdenscheid".

      Was passiert jetzt bei dir? Was wird gelöscht?

      Grüße

      Johanna

  36. Hallo,

    herzlichen Dank für das Makro. Hatte mir selbst eines gebastelt, was eigentlich nie richtig funktionierte. Das hier klappt prima.

    Einzig eine Ergänzung bekam ich nicht hin: kann ich auch den Namen aus dem Namen des Dokuments und den Serienfeldern zusammensetzen?
    Ein Dokument mit dem Namen Test.docx für den Max Müller sollte also unter Test_Müller_Max.docx gespeichert werden. Das _Müller_Max bekomme ich hin, aber nicht den Dokumententitel ohne Endung. Wäre klasse, vielen Dank schon mal.

    Grüße
    Johanna

    1. Hallo Johanna,
      der Dateiname für die einzelnen Dateien wird in der folgenden Zeile festgelegt:
      sBrief = Path & .DataFields("ID").Value & ".pdf"
      In deinem Fall würde die dann vermutlich in etwa so aussehen (die Feldbezeichnungen musst du natürlich noch an deine Quelle anpassen):
      sBrief = Path & "Test_" & .DataFields("Vorname").Value & "_" & .DataFields("Nachname").Value & ".pdf"

      Was genau meinst du mit "nicht den Dokumententitel ohne Endung"?

      lg Christian

      1. Hallo Christian, da habe ich mich wohl unklar ausgedrückt. Ich habe es hinbekommen, dass ein "Test_" voran gestellt wird. Danke. Wenn das nächste Dokument aber nicht "Test", sondern "Muster" heißt, stimmt der Eintrag nicht mehr.

        Deshalb fände ich es klasse, wenn
        sBrief = Path & ActiveDocument.Name & "_" & .DataFields("Vorname").Value & "_" & .DataFields("Nachname").Value & ".pdf"
        funktionieren würde. Dann allerdings heißt die von deinem Tool erstellte Datei: "Test.docx_Max_Müller" oder eben "Muster.docx_Max_Müller". Das meinte ich mit: ich bekomme den Titel des Dokuments eingebaut, aber eben nur mit der Endung (.docx). Besser wäre es natürlich, die Endung abzuschneiden und die Datei dann unter "[Name ohne .docx]_Max_Müller" zu speichern.

        Grüße
        Johanna

        1. Hallo Johanna,
          der einfachste Weg ist den zurückgelieferten Wert so zu manipulieren, dass die Dateiendung abgeschnitten wird. Folgende Lösung sollte funktionieren (nicht getestet):
          sBrief = Path & Left(ActiveDocument.Name, InStr(ActiveDocument.Name, ".") - 1) & "_" & .DataFields("Vorname").Value & "_" & .DataFields("Nachname").Value & ".pdf"
          lg Christian

          1. Hallo Christian,
            habe es jetzt getestet und es funktioniert prima. Dein Makro hat mir bis jetzt schon bestimmt 4 - 5 Stunden Arbeitszeit gerettet. Herzlichen Dank.

            Grüße
            Johanna

  37. Hallo,
    ich habe noch eine Frage, die du vielleicht auch lösen kannst (oder ein anderer Besucher des Blogs): Der Pfad zum Excel-Sheet (oder der anderen Quelle mit den Daten) ist ja fest vorgegeben. Wenn also Serienbrief und Datenquelle auf C:/Daten liegen und ich die beiden verbinde, dann klappt es.

    Verschiebe ich nun beide Dateien auf z.B. D:/Daten klappt es nicht mehr, ich muss den Bezug erst neu herstellen. Könnte man per VBA den Serienbrief auch dazu bringen, einen relativen Bezug herzustellen? Das wäre klasse. Danke schon einmal fürs Nachdenken ;-)

    Grüße
    Johanna

    1. Hallo Johanna,
      mir ist dafür zumindest nichts bekannt. Die Verknüpfung zwsichen Word-Dokument und Excel-Sheet passiert auch nicht über das obige Skript sondern schon vorher mit Word-Boardmitteln. Ich kann mir allerdings gut vorstellen das es mittels VBA möglich ist diese Verbindung zu schaffen und das Skript entsprechend so zu erweitern, dass es zunächst einen Dialog zur Auswahl der Quelldatei anzeigt oder eben auch einen fest hinterlegen relativen Pfad nutzt.
      lg Christian

      1. Hallo Christian,

        ja, deinen letzten Satz meinte ich. Dein Makro zu erweitern (falls das überhaupt geht). Dass dein Script nicht den Pfad sucht, ist klar. Ich habe auch schon Lösungen gesehen. Die waren aber (für mich) zu komplex oder funktionierten bei mir einfach nicht. (Wie z.B. http://devblog.alexsapps.com/2011/08/how-to-use-relative-path-to-data-source.html). Nun, das ist ein Randproblem, deine Lösung spart mir auf jeden Fall viel Zeit. Herzlichen Dank dafür.

        Grüße
        Johanna

  38. hallo, danke für das makro, funktioniert super! frage, gibts dies auch für office 2003? danke und gruss reto

    1. Hallo Reto,
      Office 2003 unterstützt das Speichern von Dateien im PDF-Format noch nicht, daher funktioniert das Makro dort leider nicht.
      lg Christian

      1. Besten Dank für die Antwort und Gruss
        Reto

  39. Hallo,

    klappt wirklich super. (nachdem ich das mit der ID verstanden hatte :-) )
    Ich starte das Makro per Commandbutton (im Dokument).
    Bei pdf ist der auch dann weg, aber als word-Datei gespeichert ist er in den einzelnen Dateien noch da -
    wie kriege ich ihn weg?
    Herzlichen Dank, Tom

    1. Hallo Tom,
      ich kann mich aktuell leider nicht mehr genau daran erinnern, ob das Makro in den erzeugten Word-Dokumenten wieder miteingebettet wird. Wenn du das Makro allerdings so angelegt hast, das es nicht nur im Dokument sondern generell in Word gespeichert wird, ist dieses natürlich auch in allen anderen Dokumenten vorhanden. Generell kannst du auch versuchen per Makro gewisse Elemente aus dem Dokument zu löschen bzw. auszublenden um zu verhindern, dass diese in den erzeugten Dokumenten miteingebettet werden.
      lg Christian

  40. Top!
    Das Makro läuft einwandfrei.
    Danke für die Super-Lösung und den ausführlichen Thread, den Fehler 5941 hatte ich anfangs auch.
    Mein Irrtum die Excel Spalte aus der ich den Dateinamen ableite hieß "ZVS Nr." habe sie in "ZVS" umbenannt. und das Makro funktioniert.
    Tipp: in Excel Steuerdateien keine Leerzeiche, Bindestriche o.ä in den Spaltennamen verwenden.

    Gruß
    Roland

  41. Super, vielen Dank für das Makro - funktioniert einwandfrei!
    :-)

  42. Wenn ich das Makro nun erweitern wollen würde, sodass nicht nur das Dokument mit einem Feldnamen versehen wird, sondern er gleichzeitig auch einen Ordner für jedes Dokument anlegt, das Feldnamen als Ordnernamen hat, wie wäre dies anzustellen? Wie sähe der Code dafür aus?

    1. Hallo Nils,
      du müsstest die Zeile die den Dateinamen generiert:

      sBrief = Path & .DataFields("ID").Value & ".pdf"

      durch den folgenden Code ersetzen um damit einen Ordnernamen zu generieren und den Ordner vor der Erstellung des PDFs anzulegen:

      FilePath = Path & "Folder-" & .DataFields("ID").Value & "\"
      MkDir FilePath
      sBrief = FilePath & .DataFields("ID").Value & ".pdf"

      lg Christian

      1. Super!! Vielen vielen Dank! Klappt wunderbar. So spar ich mir Stunden bei der Reorganisation der Ablage des Personals :)

        Viele Grüße,
        Nils

        1. Hi Christian,

          meine Frage bezieht sich auch auf den Ordner. Ich hätte gern, dass der erstellte Ordner nicht immer "Serienbrief" heißt, sondern sich an einem Feld in der Exceldatei orientiert - Also in einer Spalte steht "Bayern" und in einer anderen "Lieferanten" und der Ordner soll dann "Bayern Lieferanten" heißen und darunter sind dann die Serienbriefe abgespeichert.

          Beste Grüße

          1. Hallo Philipp,

            das ist in der aktuellen Umsetzung so nicht vorgessen. Der Pfad wird aktuelle außerhalb der Schleife in der Zeile

            Path = Path & "\Serienbrief-" & Format(Now, "dd.mm.yyyy-hh.mm.ss") & "\"

            erstellt und innerhalb der Schleife in der Zeile

            sBrief = Path & .DataFields("ID").Value & ".pdf"

            verwendet.

            In deinem Fall müsstest du die erste Zeile auf

            Path = Path & "\"

            abändern und die Zweite auf

            sBrief = Path & .DataFields("Ordnerbezeichnung").Value & "\" & .DataFields("Dateibezeichnung").Value & ".pdf"

            lg Christian

          2. Hi Christian,

            die beiden entsprechenden Stellen sehen jetzt so aus:

            Path = Path & "\"
            MkDir Path

            On Error GoTo ErrorHandling

            ' hide application for better performance
            MsgBox "Serienbriefe werden exportiert. Dieser Vorganag kann einige Minuten dauern - Microsoft Word wird während dieser Zeit ausgeblendet", vbOKOnly + vbInformation
            Application.Visible = False

            ' create bulkletter and export as pdf
            With ActiveDocument.MailMerge
            .DataSource.ActiveRecord = 1
            Do
            .Destination = wdSendToNewDocument
            .SuppressBlankLines = True
            With .DataSource
            .FirstRecord = .ActiveRecord
            .LastRecord = .ActiveRecord
            sBrief = Path & .DataFields("Bundesland").Value & "\" & .DataFields("Lieferant").Value & ".doc"
            End With
            .Execute Pause:=False

            If .DataSource.DataFields("Lieferant").Value > "" Then
            ActiveDocument.SaveAs FileName:=sBrief
            End If
            ActiveDocument.Close False

            Er wirft mir aberimmer einen Fehler, nachdem ich den Pfad zum abspeichern gewählt habe.

          3. Hallo Philipp,

            ich hatte übersehen, dass der Zielordner bereits außerhalb der Schleife erzeugt wird, d.h. du musst die Logik zur Erstellung des Ordners (Mkdir) bzw. falls notwendig die Sicherheitsabfrage ob ein Ordner schon existiert auch noch innerhalb der Schleife platzieren.

            lg Christian

          4. meine Prog-Kenntnisse sind schlimmer als miserabel und daher weiß ich auch nicht genau, an welche Stelle ich "MkDir Path" setzen muss. Kannst du das ein wenig genauer Ausführen?

            Beste Grüße

          5. Hallo Philipp,
            nachdem der Umbau des Codes, mit dem entsprechenden Fehlerhandling, keine schnelle Sache auf 5 Minuten ist, kann ich dir hier leider nicht weiterhelfen.
            lg Christian

  43. Makros funktionier soweit. Habe aber trotzdem noch ein Problem:
    Makros speichert mir nur eine einzige Datei aus dem S-Brief. Ich brauche aber alle einzeln als .doc.
    Hilfe?!?!
    Was muss ich beachten?

    1. Hallo Ari,
      wahrscheinlich wird bei dir immer der selbe Dateinamen erzeugt und deshalb die Datei immer wieder überschrieben, oder das Feld mit der eindeutigen ID bzw. dem eindeutigen Namen ist nicht immer belegt. Prüfe dazu die folgenden beiden Zeilen im Code:
      sBrief = Path & .DataFields("ID").Value & ".pdf"
      If .DataSource.DataFields("ID").Value > "" Then
      lg Christian

      1. Hallo Christian
        Habe ich geprüft, sollte nicht an dem liegen.
        Habe eine anderen "Problemfaktor" gefunden:

        With ActiveDocument.MailMerge
        .DataSource.ActiveRecord = 1
        Do

        Ich glaube, hier liegt das Problem. Habe den Test gemacht und die 1 durch 31 (Mein Dokument hat 31 Seiten) ersetzt. Hier wird das Dokument auch erzeugt (die letzte Seite).

        Gibt es hierfür kein Code, wie z.B. 1 - 31 (1 bis 31) oder alle Seiten.. etc?

        Danke für die Antwort.
        LG Ari

        1. Hallo Ari,
          diese Option hat nichts mit den Seiten sondern mit den Datensätzen in deiner Datenquelle des Serienbriefs zu tun.
          Kann es sein, dass du versuchst die einzelnen Seiten eines Dokuments als einzelne Dateien zu speichern? - Das Makro speichert nämlich das gesamte Dokument pro Serienbrief-Empfänger.
          lg Christian

      2. Hallo Christian
        Wenn ich den S-Brief fertigstelle, werden mir alle Datensätze (31 Seiten) in einem Dokument angezeigt. Das möchte ich aber nicht.
        Bevor ich den S-Brief fertigstelle, muss ich ja den Makro ausführen?!
        Dieser muss mir die 31 Seiten (= 31 Kunden) einzeln speichern.

        Ich blick nicht mehr durch..
        Vielen Dank für deine Hilfe

        LG Ari

        1. Hallo Ari,
          jetzt glaube ich hab ich dein Problem erkannt. Du musst das Makro ausführen nachdem du die Empfängerliste ausgewählt hast, aber bevor du die Option "Fertig stellen und zusammenführen" ausführst. (In diesem Stadium kannst du dir das Ergebnis der einzelnen Dokumente mit Hilfe der Menü-Option "Vorschau Ergebnisse" ansehen.)
          lg Christian

  44. Hi,
    habe das Makro in Word2010 probiert und es hat sofort funktioniert! Klasse vielen vielen Dank!
    Hans

  45. Hi, ein super Makro, hat auf anhieb funktioniert (trozt Fehlermeldung, dass ich das Makro erneut ausführen soll)

    Nun aber noch eine Frage
    Bis anhin habe ich alle Datensätze in ein Worddokument Serienebriefe.docx zusammengeführt (normale Serienbreif Funktion.
    Jetzt hab ich ein Makro, welches die Leerzeilen einer Tabelle im zusammengeführten Serienbriefe.docx löscht (Bereinigung damits schöner aussieht).

    Kann ich das jetzt in dieses Makro irgendwie integrieren, bzw. geht das überhaupt, dass ich auch im PDF keine Leerzeilen hab? (wahrscheinlich geht ja auch viel einfacher :-)) Irgendjemand eine Idee?

    Hier mal den Code, den ich benutze:
    Sub LeerZeilenoeschen()

    ' prüfen ob Serienreife.docx geöffnet ist
    Application.ScreenUpdating = False
    Dim Offen As Boolean
    Const sPathFile As String = "ThisDocument.Path & \Serienbriefe.docx" '<- anpassen
    On Error Resume Next
    Set appWord = GetObject(, "Word.Application")
    If Err 0 Then Set appWord = CreateObject("Word.Application")
    On Error GoTo 0
    appWord.Visible = True
    With appWord
    For Each doc In .Documents
    If doc.Name = Mid(sPathFile, InStrRev(sPathFile, "\") + 1) Then

    Offen = True
    Exit For
    End If
    Next doc

    ' wenn serienbriefe.docx geöffnet, lösche leerzeilen
    If Offen = True Then

    Documents("Serienbriefe.docx").Activate

    Dim oTable As Table, tblrow As Row, bEmpty As Boolean
    Dim cl As Cell
    For Each oTable In ActiveDocument.Tables
    For Each tblrow In oTable.Rows
    bEmpty = True
    For Each cl In tblrow.Cells
    If Replace(cl.Range, Chr(13) & Chr(7), "") "" Then
    bEmpty = False
    End If
    Next cl
    If bEmpty = True Then
    tblrow.Delete
    End If
    Next tblrow
    Next oTable
    Application.ScreenUpdating = True

    MsgBox "Die leeren Zeilen im Dokument Serienbriefe.docx wurden erfolgreich gelöscht."

    End If

    ' Wenn serienbriefe.docx nicht geöffnet, dann Fehlermeldung zeigen
    If Not Offen Then

    MsgBox "Die leeren Zeilen werden im Dokument Serienbriefe.docx gelöscht." _
    & vbNewLine & " " _
    & vbNewLine & "Bitte sicherstellen, dass der Dokumentenname stimmt und" _
    & vbNewLine & "die Datei offen ist!" _
    & vbNewLine & " " _
    & vbNewLine & "Erstellt wird das Dokument über Word/Sendungen/Fertigstellen" _
    & vbNewLine & "und zusammenführen/einzelne Dokumente bearbeiten." _

    End If
    End With

    End Sub

  46. Das Makro funktioniert leider gar nicht unter Microsoft Office mac 2011. Das liegt am mac oder hat es etwas anderes damit auf sich?

    Fehlermeldung:
    Fehler beim Kompilieren.:

    "Sub" oder "Funktion" ist nicht definiert

    1. Hallo Mathias,
      ich hatte gerade Gelegenheit das Makro unter Office for Mac 2011 zu testen. Das erste Problem besteht darin, dass unter Office for Mac der Parameter RecordCount nicht verfügbar ist (http://www.ms-office-forum.net/forum/showthread.php?t=301241). Das lässt sich schnell durch etwas umprogrammieren beheben, dennoch lässt sich dieses dann auf Grund eines unbekannten Fehlers nicht ausführen. Daher meine Vermutung, dass hier die unterschiede zwischen Office für Windows und Office für Mac doch zu groß sind.
      lg Christian

  47. Super, genau das was ich gesucht habe.
    Ich habe vorher noch nie mit Makros gearbeitet und musste mich etwas durchwurschteln.
    Habe es zuerst mit Word 2010 probiert. Lief auch einigermaßen, aber dann hat sich Word immer aufgehangen und es kam "keine Rückmeldung".
    Da ich dachte das liegt an meinem Rechner und habe es auf einem anderen mit Word 2012 probiert. Lief auch erst alles reibungslos, 196 Dateien wurden erstellt (365 müssten es sein). Nur dann kam der Fehler, dass der Speicherort ungültig sei. Habe es dann an verschiedenen Speicherorten probiert, ohne Erfolg. Habe mir dann sogar nochmal eine zweite Tabelle erstellt, die erst nach dem letzten gespeicherten Datensatz beginnt und neu verknüpft, damti es nicht zu viele auf einmal werden, nichts. Weiterhin ungültiger Speicherort. Nun habe ich es nochmal auf meinem Rechner probiert, da tritt das selbe Problem auf. Mein Code sieht derzeit so aus:
    ____________________________________________
    Sub Serienbrief()
    ' set variables
    Dim iBrief As Integer, sBrief As String
    Dim AppShell As Object
    Dim BrowseDir As Variant
    Dim Path As String

    ' catch any errors
    On Error GoTo ErrorHandling

    ' determine path
    Set AppShell = CreateObject("Shell.Application")
    Set BrowseDir = AppShell.BrowseForFolder(0, "Speicherort für Serienbriefe auswählen", 0, 16)

    If BrowseDir = "Desktop" Then
    Path = CreateObject("WScript.Shell").SpecialFolders("Desktop")
    Else
    Path = BrowseDir.items().Item().Path
    End If

    If Path = "" Then GoTo ErrorHandling

    Path = Path & "\Serienbrief-" & Format(Now, "dd.mm.yyyy-hh.mm.ss") & "\"
    MkDir Path

    On Error GoTo ErrorHandling

    ' hide application for better performance
    MsgBox "Serienbriefe werden exportiert. Dieser Vorganag kann einige Minuten dauern - Microsoft Word wird während dieser Zeit ausgeblendet", vbOKOnly + vbInformation
    Application.Visible = False

    ' create bulkletter and export as pdf
    With ActiveDocument.MailMerge
    .DataSource.ActiveRecord = 1
    Do
    .Destination = wdSendToNewDocument
    .SuppressBlankLines = True
    With .DataSource
    .FirstRecord = .ActiveRecord
    .LastRecord = .ActiveRecord
    sBrief = Path & .DataFields("Lfd").Value & " - " & .DataFields("KdNr") & " - " & .DataFields("Rechnungsadresse").Value & ".pdf"
    End With
    .Execute Pause:=False

    If .DataSource.DataFields("KdNr").Value > "" Then
    ActiveDocument.SaveAs FileName:=sBrief, FileFormat:=wdFormatPDF
    End If
    ActiveDocument.Close False

    If .DataSource.ActiveRecord 0 Then
    MsgBox "Unbekannter Fehler: " & Err.Number & " - Bitte Makro erneut ausführen.", vbOKOnly + vbCritical
    Else
    MsgBox "Serienbriefe erfolgreich exportiert", vbOKOnly + vbInformation
    End If

    End Sub
    _________________________________________

    Angepasst habe ich lediglich die Parameter für den Dateinamen und die Angabe wann die Datensätze in der Tabelle zu Ende sind.
    Ich komme einfach nicht weiter, vielleicht weiß hier jemand was.

    1. Hallo Ines,
      das Problem mit dem ungültigen Speicherort, dass noch dazu erst nach einigen Datensätzen auftritt, hört sich für mich nach einem Problem mit den Daten in den für die Dateinamensgenerierung genutzten Feldern (also in deinem Fall Lfd und KdNr) an. Der Dateiname setzt sich ja direkt aus den in den Feldern enthaltenen Werten zusammen, daher ist darauf zu achten, dass in diesen Feldern auch keine für Dateinamen nicht erlaubte Zeichen enthalten sind - dies prüft das Makro nämlich nicht. Unter Windows sind das die folgenden Zeichen: \ / ? : * " > < |
      lg Christian

      1. Super, vielen lieben Dank, genau da lag das Problem :)
        Es hat sich zwar auch zwischendrin immer aufgehangen, aber lief scheinbar im Hintergrund weiter.
        Das Makro werd ich auf jeden Fall speichern :)
        Gruß Ines

  48. Hi Christian!

    Ich nutze auch dein Makro (aber nur 1 Mal im Jahr,was mir aber Unmengen an Zeit erspart) mit Office 2010. Bis letztes Jahr funktionierte es prima. Nun aber ist das Problem, das mir das Makro beim Ausführen folgendes sagt "Das Dokument ist kein Serienbrief"

    Ich kenne mich mit VBA auch Null aus und wäre dir super dankbar, wenn du das u.s. Makro mal gegenliest. Vielleicht siehst du ja das Problem?! Herzlichen Dank und beste Grüße, André!

    Sub Serienbrief()
    ' set variables
    Dim iBrief As Integer, sBrief As String
    Dim AppShell As Object
    Dim BrowseDir As Variant
    Dim Path As String

    ' catch any errors
    On Error GoTo ErrorHandling

    ' determine path
    Set AppShell = CreateObject("Shell.Application")
    Set BrowseDir = AppShell.BrowseForFolder(0, "Speicherort für Serienbriefe auswählen", 0, 16)

    If BrowseDir = "Desktop" Then
    Path = CreateObject("WScript.Shell").SpecialFolders("Desktop")
    Else
    Path = BrowseDir.items().Item().Path
    End If

    If Path = "" Then GoTo ErrorHandling

    Path = Path & "\Serienbriefe 2014"
    MkDir Path

    On Error GoTo ErrorHandling

    ' hide application for better performance
    MsgBox "Serienbriefe werden exportiert. Dieser Vorganag kann einige Minuten dauern - Microsoft Word wird während dieser Zeit ausgeblendet", vbOKOnly + vbInformation
    Application.Visible = False

    ' create bulkletter and export as docx
    With ActiveDocument.MailMerge
    .DataSource.ActiveRecord = 1
    Do
    .Destination = wdSendToNewDocument
    .SuppressBlankLines = True
    With .DataSource
    .FirstRecord = .ActiveRecord
    .LastRecord = .ActiveRecord
    sBrief = Path & .DataFields("Country").Value & "_2014" & ".docx"
    End With
    .Execute Pause:=False

    If .DataSource.DataFields("Country").Value & "_2014" > "" Then
    ActiveDocument.SaveAs FileName:=sBrief
    End If
    ActiveDocument.Close False

    If .DataSource.ActiveRecord 0 Then
    MsgBox "Unbekannter Fehler: " & Err.Number & " - Bitte Makro erneut ausführen.", vbOKOnly + vbCritical
    Else
    MsgBox "Serienbriefe erfolgreich exportiert", vbOKOnly + vbInformation
    End If

    End Sub

    1. Hallo André,
      das schöne an Computern ist, dass ein einmal funktionierender Code (zumindest unter gleichen Bedingungen) immer und immer wieder funktioniert.
      Meine Vermutung ist daher, dass du zwar dein Dokument wieder geöffnet hast, dieses aber entweder die Datenquelle nicht mehr finden kann oder der Serienbrief-Modus beendet wurde. Am einfachsten prüfst du, ob du wirklich einen funktionierenden Serienbrief hast, in dem du dir in der Vorschau einmal ein oder zwei Dokumente ansiehst. Vermutlich musst du also nur den Serienbrief-Assistenten neu starten.
      Und noch ein kleiner Tipp zum Code. Die Zeile
      If .DataSource.DataFields("Country").Value & "_2014" > "" Then
      sollte eigentlich
      If .DataSource.DataFields("Country").Value > "" Then
      heißen - also ohne & "_2014". Diese Zeile überprüft nämlich ob im Feld Country auch wirklich ein Wert steht und damit ein gültiger und eindeutiger Dateiname generiert werden kann.
      lg Christian

      1. Hi Christian!

        Besten Dank für deinen Tipp! Es lag tatsächlich am Serienbrief-Assistenten. Ich war einen Schritt zu weit und deshalb hatte es nicht funktioniert.

        Zu & "_2014" im Code habe ich übrigens keine Probleme, da es diesen Wert gibt.

        Da einzige was stört ist, dass die generierten Dateibezeichnungen nun immer am Anfang ein "Serienbriefe2014..." enthalten, was ich später händisch löschen muss.

        Kannst du mir sagen, wie der Code anzupassen ist, damit dieser Zusatz nicht mehr in die Dateibezeichnungen einbezogen wird?

        VG André!

      2. Hallo André,
        du hattest mit dem Zusatz & "_2014" deshalb keine Probleme weil dieser die Abfrage so abändert, dass diese immer akzeptiert wird und daher solltest du diese auch besser entfernen.
        Der Zusatz "Serienbriefe2014" vor deinen Dateinamen kommt daher, weil du diesen in der Zeile die den Speicherort generiert ergänzt hast:
        Path = Path & "\Serienbriefe 2014"
        Du wolltest vermutlich am Speicherort immer einen Ordner mit dem Namen "Serienbriefe 2014" anlegen. Dazu musst du am Ende noch einen Slash ergänzen:
        Path = Path & "\Serienbriefe 2014\"
        lg Christian

  49. Hallo, tolles Ding, das ist genau was ich brauche. Leider läuft es bei mir überhaupt nicht. Ich benütze Word for Mac 2011. Liegt es daran? Bin für jeden Hinweis dankbar.

    1. Hallo Elio,
      ja, das Makro funktioniert leider nur unter Office für Windows.
      lg Christian

      1. Vielen Dank...kennst du ne alternative für Windows für Mac? Für jeden Hinweis bin ich sehr dankbar.

        LG, Elio

      2. Hallo Elio,
        ich hatte heute Gelegenheit das Makro unter Office for Mac zu testen und habe es entsprechend angepasst.
        lg Christian

        Sub Serienbrief()
        ' set variables
        Dim iBrief As Integer, sBrief As String
        Dim AppShell As Object
        Dim BrowseDir As Variant
        Dim Path As String

        ' catch any errors
        On Error GoTo ErrorHandling

        ' determine path
        Path = MacScript("(choose folder with prompt ""Speicherort für Serienbriefe auswählen"") as string")
        If Path = "" Then GoTo ErrorHandling

        Path = Path & "Serienbrief-" & Format(Now, "dd.mm.yyyy-hh.mm.ss") & ":"
        MkDir Path

        On Error GoTo ErrorHandling

        ' hide application for better performance
        MsgBox "Serienbriefe werden exportiert. Dieser Vorganag kann einige Minuten dauern - Microsoft Word wird während dieser Zeit ausgeblendet", vbOKOnly + vbInformation
        Application.Visible = False
        Application.ScreenUpdating = False
        Application.DisplayAlerts = False

        ' create bulkletter and export as pdf
        With ActiveDocument.MailMerge
        .DataSource.ActiveRecord = 1

        .Destination = wdSendToNewDocument
        .SuppressBlankLines = True
        .DataSource.ActiveRecord = wdLastRecord

        RecordCount = .DataSource.ActiveRecord
        .DataSource.ActiveRecord = 1

        Do
        With .DataSource
        .FirstRecord = .ActiveRecord
        .lastRecord = .ActiveRecord
        sBrief = Path & .DataFields("ID").Value & ".pdf"
        End With
        .Execute Pause:=False

        If .DataSource.DataFields("ID").Value > "" Then
        ActiveDocument.SaveAs fileName:=sBrief, FileFormat:=wdFormatPDF
        End If
        ActiveDocument.Close False

        If .DataSource.ActiveRecord < RecordCount Then .DataSource.ActiveRecord = .DataSource.ActiveRecord + 1 Else Exit Do End If Loop End With ' error handling ErrorHandling: Application.Visible = True If Err.Number = 76 Then MsgBox "Der ausgewählte Speicherort ist ungültig", vbOKOnly + vbCritical ElseIf Err.Number = 5852 Then MsgBox "Das Dokument ist kein Serienbrief" ElseIf Err.Number = 4198 Then MsgBox "Der ausgewählte Speicherort ist ungültig", vbOKOnly + vbCritical ElseIf Err.Number = 91 Then MsgBox "Exportieren von Serienbriefen abgebrochen", vbOKOnly + vbExclamation ElseIf Err.Number > 0 Then
        MsgBox "Unbekannter Fehler: " & Err.Number & " - Bitte Makro erneut ausführen.", vbOKOnly + vbCritical
        Else
        MsgBox "Serienbriefe erfolgreich exportiert", vbOKOnly + vbInformation
        End If

        End Sub

      3. Hey Christian, vielen herzlichen Dank!!!

        Ich bekomme noch eine Fehlermeldung für diese Linie

        If .DataSource.ActiveRecord 0 Then

      4. Hallo Elio,
        hier hat die Kommentarfunktion wohl einige Zeichen verschluckt, habe den Code in meinen vorherigen Kommentar aktualisiert bzw. oben im Blog-Eintrag ergänzt.
        lg Christian

      5. Funktioniert einwandfrei. Herzlichen Dank Christian, Du hast mir so viele mühsamen Stunden erspart!

  50. Hi Christian!
    Vielen Dank für dieses SUPER-GEILE-Makro!!!
    Genau so etwas habe ich gesucht, da wir immer mal wieder personalisierte PDF's generieren müssen.
    Jetzt nur noch eine Frage: Ist es möglich, bei dem generierten PDF ein Hintergrundbild (genauer: ein anderes PDF als Hintergrund) einzufügen?
    Ich weiß, dass man ein normales Bild auch im Word als Hintergrund legen könnte, aber eben kein PDF...
    Ich wäre für einen Tipp sehr dankbar!

    Viele Grüße aus dem (heute) sonnigen Berlin! :-)

    1. Hallo Heiko,
      dazu bin ich leider zu wenig Word-Experte, aber rein aus dem Bauch heraus würde ich einmal sagen nein.
      lg Christian

  51. Hallo Christian,

    vielen Dank für das Makro. Ich habe dies gerade mit WORD 2012 probiert, jedoch werden bei mir die Dokumente nicht getrennt erstellt, sondern jede Datei enthält 10 Seiten. Die Formel zur Erstellung des Dateinamens funktioniert bei mir leider auch nicht, die Nummern werden erzeigt jedoch der Rest leider nicht. Gibt es da eine Idee wo ich schauen kann?
    Danke, Mathias

    1. Hallo Mathias,
      Word 2012 gibt es so weit ich weiß nicht - meintest du Word 2013 oder Word for Mac 2011? - In Office 2013 hatte ich noch keine Gelegenheit das Makro zu testen - hier kann es also durchaus zu Fehlern kommen, auch Office for Mac 2011 ist nur rudimentär getestet.

      Aber zu deinen Symptomen: Kann es sein, dass du gar keinen Serienbrief hast sondern versuchst aus einem Dokument die einzelnen Seiten als einzelne Dateien zu speichern? – das kann das Makro nämlich nicht. Die Dateinamensgenerierung erfordert eine Anpassung des Codes, damit dort die entsprechenden Felder aus der Datenquelle eingetragen werden.

      Hast du schon meine verbesserte Version http://www.formletter2pdf.com getestet, ob es vielleicht mit dieser klappt?
      lg Christian

  52. Hallo!

    Leider bin ich offensichtlich zu doof die Namensgebung der Dateien mit dem AddIn formletter2pdf durchzuführen. Versuche ich ein Datenfeld mit {Feld} in den Namensstring einzubauen, wird nicht der Feldwert verwendet, sondern eben der Ausdruck "{Feld}" im Dateinamen verwendet.

    {%Counter%} funktioniert einwandfrei.

    1. Noch soeben aufgefallen: Es werden in meinem Fall 37 Dokumente gespeichert, allerdings in jedem Dokument auch alle 37 Serienbriefe.

      Ich nutze Office 2010 mit allen Updates.

    2. Hallo Saskia,
      danke für den Hinweis, hier hat sich ein kleiner Fehler von meiner Seite in den Makrocode eingeschlichen. Ich habe soeben eine um diesen Fehler bereinigte Version von formletter2pdf online gestellt.
      Bezüglich deines Problems mit den gesamten Dokumenten pro gespeicherten Serienbrief: Du musst formletter2pdf ausführen bevor du eine Aktion unter "Fertig stellen und zusammenführen" auswählst, dann sollte es klappen.
      lg Christian

      1. Hallo Christian,

        Benennung funktioniert nun einwandfrei. Gibt es irgendwo eine Referenz für die möglichen automatischen Einträge im Namen, wie zum Beispiel {%Timestamp%} oder {%Counter%}?

        Leider packt er mir immer noch alle Briefe in jede Datei, obwohl ich von "Fertig stellen und zusammenführen" ganz brav die Finger lasse.

        Leider scheint es auch zu ignorieren, wenn man die Empfängerliste filtert. Zumindest werden mir in diesem Augenblick 100 PDFs mit 100 Seiten erstellt, obwohl es 2 Dateien mit jeweils 1 Seite sein sollten :)

        1. Den letzten Absatz nehme ich zurück, filtern geht.

          Einseitig dennoch nicht :(

        2. Hallo Saskia,
          {%Timestamp%} und {%Counter%} sind die einzigen beiden automatisch bereitgestellten Marker. Für den Rest des Dateinamens kannst du dann ja mittels Marker die einzelnen Feldwerte einfügen.
          Zu deinem Problem mit allen Seiten in jedem PDF habe ich jetzt aus dem Stegreif leider keine Antwort, werde mir das allerdings noch genauer ansehen und dir bescheid geben.
          lg Christian

        3. Hallo Saskia,
          ich konnte dein Problem mit allen Seiten in jedem Dokument bei mir nachstellen und habe eben eine neue Version von formletter2pdf online gestellt.
          lg Christian

  53. Hi!
    Super Makro, vielen Dank!
    Allerdings:
    Nachdem ich formletter2pdf ausgeführt habe, kann ich keine Aktion unter "Fertigstellen und zusammenführen" auswählen, da das Makro dann direkt loslegt.
    Wann genau soll ich den Serienbrief fertigstellen, um für jeden Brief ein einzelnes doc. zu bekommen?

    1. Hallo Richard,
      vielleicht geht das aus der Beschreibung auf der Website noch nicht eindeutig genug hervor. Du musst formletter2pdf unbedingt vor dem Zusammenführen und Fertigstellen ausführen, ansonsten kann das Makro gar keine Einzeldateien speichern. D.h. Serienbrief-Modus starten, Adressen auswählen, Text schreiben, Marko ausführen, fertig.
      lg Christian

  54. Vielen Dank für den Code. Funktioniert super!!!

    Ich nutze es um Outlook-Signaturen zu erstellen. Hierfür sind .txt .rtf und .htm erforderlich. Die ersten beiden lassen sich problemlos erzeugen. Htm prinzipell auch, aber dann fehlt leider der htm-Ordner der von Word beim "Speichern unter" erzeugt wird. Haben Sie einen Ratschlag? Mein Versuch mit

    ActiveDocument.SaveAs FileName:=htmBrief, FileFormat:=wdFormatHTML

    scheitert. Der erste Datensatz wird korrekt erstellt. Dann bricht es mit einer Fehlermeldung ab. Es wird wohl immer ein weiteres geöffnetes Word-Dokument erzeugt und das scheint "schuld" zu sein?

    Vielen Dank Schoppes

    1. Sorry für den Post vom 16.04. 21:14:

      kann gelöscht werden. Habe schon den ganzen Tag probiert und keine Lösung gefunden. Ist aber ganz simpel:

      Es muss

      FileFormat:=wdFormatFilteredHTML

      genutzt werden.
      So funktioniert es.
      Sorry Schoppes

  55. Hallo Christian,

    tolles Makro, ich habe jedoch folgendes Problem:

    Ich möchte aus meiner in Word gewählten Datenquelle bsplw. von 100 Datensätzen nur 50 für ein bestimmtes Schreiben auswählen und zwar aus der Sendungen-Empfängerliste. Wenn ich dort eine bestimmte Auswahl tätige und nicht alle Seriendruckempfänger wähle, kommt es zu einer Fehlermeldung.

    Das Makro ist wie folgt aufgebaut:Sub JederDatensatzInEineEigenstaendigeDatei_2()
    Verzeichnis = individuell"
    Praefix = "_"
    Praefix2 = ","
    Praefix3 = "_"
    Schluessel = "Name"
    Schluessel2 = "Vorname"
    Schluessel3 = "KDNr"
    Dim anzahl As Integer
    Dim i As Integer
    Dim x As Variant
    Dim dsname As String

    With ActiveDocument.MailMerge
    If .MainDocumentType = wdNotAMergeDocument Then
    MsgBox "Das aktive Dokument ist kein Seriendruckhauptdokument."
    Exit Sub
    End If
    .DataSource.ActiveRecord = wdLastRecord
    anzahl = .DataSource.ActiveRecord
    If anzahl = 0 Then
    MsgBox "Es wurden keine Datensätze gefunden."
    Exit Sub
    End If
    'flag = False
    For Each x In .DataSource.DataFields
    If x.Name = Schluessel Then
    flag = True
    Exit For
    End If
    Next
    ' If flag = False Then
    ' Q = Chr(34)
    ' MsgBox "Das nominierte Feld " & Q & Schluessel & Q & _
    ' " existiert nicht in der Datenquelle."
    ' Exit Sub
    ' End If
    .Destination = wdSendToNewDocument
    For i = 1 To anzahl
    .DataSource.ActiveRecord = i
    ' dsname = Verzeichnis & "\" & Praefix & _
    ' .DataSource.DataFields(Schluessel).Value & ".doc"
    .DataSource.FirstRecord = i
    .DataSource.LastRecord = i
    .Execute
    ActiveDocument.Range.Find.Execute FindText:="^b", ReplaceWith:=""
    ActiveDocument.SaveAs FileName:=Verzeichnis & "S_" & Format(Now, "YYYY_MM_DD") & Praefix & _
    .DataSource.DataFields(Schluessel).Value & Praefix2 & _
    .DataSource.DataFields(Schluessel2).Value & Praefix3 & _
    .DataSource.DataFields(Schluessel3).Value & ".doc", AddToRecentFiles:=False
    ActiveDocument.Activate
    Next i
    .DataSource.FirstRecord = 1 'be smart
    End With
    End Sub

    Wähle ich alle Datensätze läuft es fehlerfrei. Es muss doch eine Möglichkeit geben, das ich nur die mit Häkchen ausgewählten Datensätze einzeln abspeichern kann?

    Besten Dank im Voraus!

    René

    1. Hallo René,
      ich hab die Auswahl von Datensätzen eben mit meinem weiterentwickelten Makro formletter2pdf (www.formletter2pdf.com) getestet und dort funktioniert es einwandfrei. Wo der Haken in deinem Code liegt konnte ich auf den ersten Blick nicht erkennen, aber vielleicht hilft dir ein Blick in meinen Code.
      lg Christian

  56. Hallo zusammen
    Erstmal vielen Dank für das Makro. Funktioniert einwandfrei. Eine Frage: Was muss ich ändern, damit der Speicherort nicht abgefragt wird, sondern automatisch an den gewünschten Ort geht.

    1. Hallo Sepp,
      die Abfrage des Speicherorts passiert in den folgenden Codezeilen:

      ' determine path
      Set AppShell = CreateObject("Shell.Application")
      Set BrowseDir = AppShell.BrowseForFolder(0, "Speicherort für Serienbriefe auswählen", 0, 16)

      If BrowseDir = "Desktop" Then
      Path = CreateObject("WScript.Shell").SpecialFolders("Desktop")
      Else
      Path = BrowseDir.items().Item().Path
      End If

      If Path = "" Then GoTo ErrorHandling

      Path = Path & "\Serienbrief-" & Format(Now, "dd.mm.yyyy-hh.mm.ss") & "\"
      MkDir Path

      Ersetzte den ganzen Bereich durch die folgenden beiden Zeilen um den Pfad direkt zu setzen:

      Path = "C:\data\Serienbrief-" & Format(Now, "dd.mm.yyyy-hh.mm.ss") & "\"
      MkDir Path

      lg Christian

  57. Ich bin ziemlich neu mit Makros und bin dazu gezwungen meine Arbeit auf einem Mac zu verrichten. Ich hab den serienbrief erstellt und mir steht nun zur verfügung ob ich die Serienbriefe ausdrucken möchte oder sie in einer neuen datei anzeigen lassen will. Wann verwendet ich das macro? Kann mir jemand die Arbeitsschritte genau für mac erklären?
    MFG Michael

    1. Hallo Michael,
      das Makro wird ausgeführt sobald du zu deinem Serienbrief die Empfänger hinzugfügt hast aber bevor du einer der Optionen mit Fertigstellen oder Drucken anwendest.
      Ich habe das Makro bereits weiterentwickelt und auch für Office for Mac noch einmal optimiert und um eine Step-by-Step-Anleitung ergänzt. - Du findest das Ergebnis unter http://www.formletter2pdf.com.
      lg Christian

      1. Das hab ich auch schon gesehen aber leider fjnktioniert es auf mac nicht so einfach. Allein schon wenn ich die erste datei öffne gibts probleme, dann wenn ich die datei offene habe, gibs links oben kein symbol, dass gleich bei den ersten Arbeitsschrittem verlangt wird.

        1. Hallo Michael,
          die Anleitung ist für Office für Windows - diese Schnelleinstiegs-Icons gibt es unter Office für Mac nicht. Dort musst du das Makro auf dem klassischen Weg über das Menü unter "Extras -> Makro -> Makros..." ausführen.
          lg Christian

  58. Hallo Zusammen,

    das Makro funktioniert eigentlich wunderbar.
    Ich möchte für Datenblätter verschiedene PDF's nach dem Produktnamen anspeichern. Dies wäre z.B. SIGRAFIL® C T24-4.8/240-E100 Nur leider kommt dann immer eine Fehlermeldung. Wenn ich aber eine anderes Feld nehme, funktioniert es einwandfrei. Kann es sein, dass der Name zu lang ist oder -/. weg müsste? Danke

    1. Hallo Rebekka,
      wie du bereits richtig vermutet hast, liegt das Problem an den Sonderzeichen im Dateinamen. Unter Windows dürfen diese die folgenden Zeichen nicht enthalten: : \ / ? : * " |
      Die Weiterentwicklung des Makros formletter2pdf berücksichtigt dies bereits und entfernt die Sonderzeichen automatisch aus dem Dateinamen. Du kannst dir von dort die entsprechenden Codezeilen in dein Makro kopieren.
      lg Christian

  59. Hallo,
    großartiges Makro! Ich hätte allerdings auch noch einen Ergänzungswunsch, den ich alleine nicht hinbekomme: Meine Excel-Quelle enthält auch Verweise zu Grafiken, die im Serienbrief angezeigt werden sollen. Leider aktualisieren sie sich nicht von allein, so dass in jedem einzelnen PDF immer dieselben Grafiken angezeigt werden. Kann man da noch eine Update-Funktion einbauen?
    Grüße! Joch

    1. Hallo Joch,
      das beschriebene Problem sollte sich mit einer kleinen Ergänzung im Quellcode lösen lassen.
      Füge vor der Zeile:
      .Destination = wdSendToNewDocument
      folgende Zeile ein:
      ActiveDocument.Fields.Update
      Damit sollten alle dynamischen Felder innerhalb des Dokuments aktualisiert und somit auch die richtige Grafik eingebunden werden.
      lg Christian

      1. Großartig! Dass es irgendwie mit Fields.Update sein müsste, hatte ich mir gedacht, ich habe aber nicht rausbekommen, wie man es einbauen muss. Jetzt läuft es.
        Danke!

  60. Hallo,
    ich nutze das Makro mit Microsoft Word 2007 auf Windows 7. Es funktioniert soweit einwandfrei.
    Ist es aber dennoch möglich, dass er die Dateien nicht in .doc sondern in .docx abspeichert?
    Wenn ich lediglich die folgende Zeile von .doc in .docx ändere, dann kann Word die vom Makro erstellte Datei nicht öffnen:
    >>> sBrief = Path & .DataFields("ID").Value & ".doc"

    Und wenn ich grad dabei bin beim Fragen, das PDF-Makro läuft auch super, jedoch ist die Dateigröße der mit Word erstellten PDF viel zu groß. Deswegen öffne ich zur Zeit jede einzelne .doc und drucke diese mit "FreePDF" aus.
    Ist es leicht das Makro ähnlich dieser Funktion abzuändern?

    Vielen Dank,

    1. Hallo rk,
      damit du eine docx-Datei speichern kannst musst du nicht nur die Dateiendung im Dateinamen ändern, sondern auch das Ausgabeformat umstellen.
      Ändere dazu die Zeile
      ActiveDocument.SaveAs FileName:=sBrief, FileFormat:=wdFormatPDF
      in
      ActiveDocument.SaveAs FileName:=sBrief, FileFormat:=wdFormatDocumentDefault

      Zu deiner Frage bezüglich der Speicherung mit externen PDF-Generatoren habe ich selbst leider keinen Ansatz, wie das effektiv mit einem Makro umzusetzen ist. Hier besteht die Schwierigkeit darin entweder einen automatisierten Druck-Vorgang anzustoßen oder die Oberflächen der PDF-Plugins zu automatisieren.

      lg Christian

      1. Hallo Christian,
        danke, ich habe das Makro jetzt geändert und ausprobiert und kann jetzt auch die mit Word erstellten .docx öffnen.
        Zu meiner Frage mit den PDFs, habe ich die Antwort in deinem letzten Kommentar zu Ingo's Frage gefunden.
        Ich nutze jetzt PDF24 Creator, um alle .docx gleichzeitig in PDF zu konvertieren.
        Vielen Dank,
        René

  61. Hallo miteinander,
    die ganze History zu dem Artikel ist beeindruckend. Sehr viele gute HIlfestellungen. So habe ich zum ersten mal ein Makro erfolgreich eingebaut und angepasst.

    Hab jetzt auch mehr Mut zukuenftig haeufiger Markos zu verwenden.

    Ich habe allerdings ein Problem, von dem ich nicht weiss ob es loesbar ist.

    Ich wuerde mir gerne die einzelnen Seiten anschauen und editieren bevor Sie gespeichert werden.
    Sprich ich kann ueber die Funktion Finish & Merge, mir die einzelnen Seiten anschauen und Zeilen loeschen, einfuegen etc. Allerdings oeffnet er dazu ein eigenstaendigen Dokument, das kein Serienbrief ist. Somit kann ich das Makro hier nicht anwenden. Kann ich es so dahingehend anpassen, dass er die Seiten fuer ein normales Word Dokument speichert. Dabei ist es mir jedoch wichtig, dass er weiterhin bestimmte Informationen aus dem Dokument nutzt um den Dateinamen zu erstellen. Ich glaube beides geht nicht :(

    1. Hallo Ingo,
      das Makro funktioniert so, dass es im Hintergrund für jedes einzelne PDF eine eigene Word-Datei erzeugt, die nur die Seiten des Empfängers beinhaltet. Eine Funktion um nur gewisse Seiten aus einem Word-Dokument zu speichern, so wie du es benötigen würdest, ist zumindest mir nicht bekannt. Vor allem ist mir dazu auch keine über die Oberfläche von Word zugängliche Funktion bekannt, die man eventuell per Makro ansprechen könnte.

      Vielleicht ist es eine Lösung für dich, das Makro einzelne Word-Dokumente speichern zu lassen, die du dann bearbeiten kannst. Es gibt genügend PDF-Tools die es dann erlauben mehrere Word-Dateien auf einmal zu konvertieren (Stapelverarbeitung).
      lg Christian

    2. Hallo Christinan,

      vielen Dank fuer deine Antwort, mittlerweile bin ich auch schon etwas weiter gekommen, aber das Problem mit den Zeilen editieren laesst mich nicht los.

      Ich habe etwas gegooglet und vielleicht funktioniert es irgendwie mit folgendem excel makro, dass sich auf word anwenden laesst.

      Private Sub leere_Zeilen_ausblenden()
      Dim c As Range

      For Each c In Range("C2:C1000")
      If c.Value "" Then
      c.EntireRow.Hidden = False
      Else
      c.EntireRow.Hidden = True
      End If
      Next c

      End Sub

      Ich stelle es mir so vor, dass er waehrend dem abspeichern in den einzelnen Seiten die leeren zeilen sucht und ausblendet.

      Um es vielleicht etwas anschaubarer zu machen beschreibe ich mal was ich mache:

      Ich moechte einen Serienbrief fuer das Schreiben von Bestellungen verwenden.

      Die Lieferanten beliefern uns aber nicht immer nur mit einem Artikel, sondern haeufig mit mehreren. Das Makro das hier verwendet wird, hilft schon deutlich diesen Vorgang zu beschleunigen. Im Moment habe ich die Moeglichkeit entweder jeden Artikel fuer einen Lieferanten pro Seite zu erstellen (1 Zeile) oder ich lasse in meinem Serienbrief bspw. 10 leere Zeilen in denen ich alle Artikel unterbringen kann, habe dann aber immer ueberschuessige Zeilen, die ich im Nachgang manuell loeschen muss.

      Vielleicht hat jemand einen klugen Einfall,

      wuerde mich sehr freuen ;)

      1. Hallo Ingo,
        da habe ich vielleicht wirklich einen Ansatz für dich. Es gibt in Word die Möglichkeit die Serienbrieffelder (Feldfunktionen) manuell zu bearbeiten und dort Bedingungen hineinzupacken. Unter anderem auch die Möglichkeit einen Zeilenumbruch nur dann einzufügen, wenn ein Datenfeld auch wirklich einen Wert enthält/anzeigt. Sie dazu http://www.tippscout.de/word-serienbrief-leere-zeilen_tipp_4969.html
        lg Christian

  62. Hallo,

    danke für dieses tolle Makro. Gibt es noch eine Möglichkeit folgende Optionen einzubauen:

    - Qualität
    - Papierformat wie Dokument

    Das Logo welches ich verwende wird komprimiert und die Zeilenabstände (Ränder, etc.) stimmen nicht ganz mit dem Word Dokument überein (hängt sicher von der PDF Option in Word ab) - hier könnte man sicher Parameter mitgeben oder?

    Danke!

    LG

    1. Hallo Hannes,
      das Makro nutzt die eingebaute PDF-Exportfunktion von Microsoft Word die in dieser Hinsicht keine Einstellungen erlaubt. Das Papierformat sollte aber immer dem Papierformat des Dokumentes entsprechen. Das von dir geschilderte Problem mit den nicht passenden Abständen oder fehlenden Grafiken bzw. Linien bei Tabellen konnte ich selbst des Öftern schon beobachten. Hier schafft nur das verändern der Vorlage Abhilfe.
      lg Christian

  63. Zur hier vor einiger Zeit gestellten Frage, warum immer nur ein Dokument gespeichert wird, habe ich inzwischen herausgefunden, dass die passiert, wenn die Verknüpfung mit einer Excel-Datei über DDE geschieht.
    Wird die Excel-Datei über eine OLE-Verbindung eingebunden werden auch alle Dateien gespeichert.

    1. Hallo Peter,
      vielen Dank für den Hinweis, dieser Umstand war mir bisher nicht bewusst.
      lg Christian

    2. Hallo,

      Gibts es hier schon eine Lösung?

      1. Hallo Pohl,
        von meiner Seite aus gibt es aktuell keine andere Variante des Makros.
        lg Christian

  64. Hallo,

    tolles Makro, erspart viel Arbeit. Aber ist es möglich das Makro so anzupassen das immer eine gerade und die nachfolgende ungerade Seite abgespeichert werden?

    Hat folgenden Hintergrund...Wir haben in ein Anschreiben (gerade Seitenzahl) und anschließend ein Formular (ungerade Seitenzahl).

    1. Hallo Stephan,
      das Makro speichert immer den gesamten Serienbrief. Besteht dieser Serienbrief aus mehreren Seiten (z.B. 1. Seite Anschreiben und 2. Seite Formular) so werden diese beiden Seiten immer zusammen in ein PDF-Dokument gespeichert.
      lg Christian

  65. Wie kann ich den Speicherort fest auf einen Laufwerksbuchstaben einstellen.
    z.B. D:\Serienbriefe
    Sonst muss ich jedesmal den Speicherort manuell einstellen.

    1. Hallo Roland,
      am einfachsten ersetzt du die Zeile

      Set BrowseDir = AppShell.BrowseForFolder(0, "Speicherort für Serienbriefe auswählen", 0, 16)

      durch

      Set BrowseDir = "D:\Serienbriefe"

      Achte darauf hier keinen abschließenden Slash anzugeben.

      lg Christian

  66. hi,
    supertolles skript! funktioniert einwandfrei!
    ich benötige allerdings eine ergänzung:
    z.b. sollen serienbriefe mit der gleichen adresse "arbeitergasse" in einem pdf zusammengefügt werden, die adresse "xy" in der nächsten. also nicht immer nur ein brief pro pdf, sondern alle briefe mit dem gleichen strassennamen.
    kann mir dabei bitte jemand helfen?
    danke,
    -tomba

    1. Hallo Tomba,
      das Makro generiert für jeden Serienbrief ein eigenes Dokument, genau in der Reihenfolge wie die Adressdaten in deiner Empfängerliste vorkommen. Eine schnelle Lösung gibt es dafür nicht, da zunächst die Empfängerliste nach Adressen geordnet werden müsste und das Makro dann erkennen muss von wo bis wo die gleichen Adressen vorkommen. Dann könnte das Makro entsprechend nur die Empfänger für diese Adresse als Quelle heranziehen.
      lg Christian

    2. danke für die rasche antwort. hat dafür jemand ev. einen code?

      danke,
      tomba

  67. Vielen vielen Dank!

    Wahnsinn!!! Super Makro! Das erleichtert mir die Arbeit soooo sehr!
    Eine Frage hab ich doch noch. Gibt es auch eine Möglichkeit, in das Serienbriefdokument automatisch ein Formularfeld und einen Blattschutz samt Passwort einzufügen bevor die Dateien dann einzeln gespeichert werden?

    Ansonsten müsste ich wohl jede Datei erneut öffnen und schützen (

    Danke schon mal

    1. Hallo Alex,
      das Formularfeld solltest du bereits in die Vorlage einbauen können und müsste damit auch in den fertigen Einzeldokumenten enthalten sein. Bezüglich Blattschutz nehme ich an, dass sich dies mittels Makro-Code bewerkstelligen lässt, habe es allerdings selbst noch nicht probiert. Eine schnelle Google-Suche hat folgenden Lösungsansatz gebracht: http://www.office-loesung.de/ftopic383220_0_0_asc.php
      lg Christian

      1. Vielen Dank,

        Ja das hab ich auch bereits entdeckt, allerdings feht mir in den Dateien dann sowieso mal das Formulartextfeld, wo eben noch was vom Kunden eingetragen gehört,und ansonsten ist bloß nur mein Hauptformular gänzlich geschützt!
        Aber ich werd mir das morgen dann in einer ruhigen Minute nochmal ansehen,das muss doch irgendwie zu schaffen sein :)

  68. Hallo Christian
    Ich bin totaler Makro Neuling. Hab alles nach Anleitung gemacht.
    Als ich das Makro beim ersten mal geöffnet habe. Kam ich bis zum speichern, danach kam einen Fehlermeldung mit Zahl.
    Hab, dann alles noch einmal nachgeschaut, korrigiert und noch mal laufen lassen und jetzt funktioniert es überhaupt nicht mehr :(
    also ich hab eine Word-Vorlage mit Makro generiert und ein Exceltabelle als Datenquelle.
    Da ich den Brief schon ausgedruckt habe, hab ich ja die Zusammenführung schon gemacht. Liegt es evt. an dem??
    Ich hab ja jetzt das Dokument offen, dann geh ich auf Makro. Wähle Serienbrief und dann "erstellen" und da geb ich doch deine Formell ein, oder?
    ich ändere, was geändert werden muss. wenn ich es aber laufen lasse, dann kommt "Fehler beim Kombilieren. Sub und Funktion nicht definiert."
    Was um Himmelswillen mach ich den falsch???
    lg und Danke
    Sandra
    PS Arbeite mit Word 2007

    1. Hallo Sandra,

      das Makro muss definitiv vor dem Zusammenführen des Dokuments ausgeführt werden, das könnte also ein Grund sein. Das Makro kannst du unabhängig vom Zustand des Dokuments anlegen. Ich empfehle dir als Neuling auf mein Tool formletter2pdf (www.formletter2pdf.com) umzusteigen. Auf der Website findest du auch eine Schritt-für-Schritt-Anleitung mit Screenshots.

      lg Christian

  69. Hallo,

    ich verwende als Serienbrief-Grundlage eine Excel Tabelle. Da diese auch Datumsangaben enthält, nutze ich eine DDE-Verknüpfung, um die Daten in deutschem Format (TT.MM.JJJJ) einzufügen.

    Wenn das Makro in einem DDE-verknüpften Serienbief ausgeführt wird, wird ledigleich das erste Anschreiben als PDF-Gespeichert. Unter OLE DB funktioniert es einwandfrei. Gibt es eine Lösung für dieses Problem?

    Gruß

    Klaus

    1. Hallo Klaus,
      von meiner Seite aus leider nicht, da die Art der Verbindung für mich bisher noch kein Thema gewesen ist und ich bei der Erstellung auch über keine Alternativen der Art der Umsetzung gestoßen bin. Der Verbindungstyp OLE DB hat DDE abgelöst bzw. erweitert, daher nehme ich an, dass Microsoft hierfür auch nicht mehr alle Funktionalitäten bereitstellt.
      lg Christian

  70. Hallo,
    erste einmal vielen Dank für das super Marko. Es hat mir die Arbeit schon sehr erleichtert. Ich habe leider keine Ahnung von VBA und hoffe, dass ich hier Hilfe finde.
    Ich würde gerne als Speicherort einen bestimmten Pfad vorgeben und nicht immer bei "Desktop" starten müssen. Was muss ich wo eintragen? Vielen Dank schon einmal für die Hilfe.

    1. Hallo Hans,

      dazu musst du die Zeile

      Set BrowseDir = AppShell.BrowseForFolder(0, "Speicherort für Serienbriefe auswählen", 0, 16)

      in

      Set BrowseDir = AppShell.BrowseForFolder(0, "Speicherort für Serienbriefe auswählen", 0, "C:\Directory")

      abwandeln. Der letzte Parameter gibt das Startverzeichnis an - im Beispiel "C:\Directory".

      lg Christian

      1. Super ... vielen Dank ... ich bin immer mehr begeistert von dem Makro und Deinem Support ... Wahnsinn!
        VG Hans

  71. Hallo Christian,

    ich habe das Makro zum Laufen gebracht - funktioniert toll. Danke dafür. Allerdings wird die Schriftart bei manchen Seriendruckfeldern nicht korrekt eingesetzt. Ich habe die Schriftarten in der Datein eingebettet - bei Acrobat auch. Kannst du da helfen?

    VG, Philipp

    1. Hallo Philipp,

      Eine Lösung habe ich jetzt auch nicht parat - Word hat beim Export als PDF oft seine Tücken. Wenn du den Brief über die Speichern bzw. Export-Funktion von Word als PDF speicherst, tritt dann das Problem auch auf? Wenn ja, hilft es oft die Felder zu verändern (Verschieben, andere Schriftart setzen und wieder zurück, Schriftgröße ändern, etc.)

      lg Christian

  72. Hallo Christian,

    dein Makro-Code ist unser heiliger Gral. Er nimmt mir viel Arbeit ab und arbeitet einfach sauber. Großes Lob dafür!

    Allerdings benötige ich in einem Fall nur den Durchlauf des ersten Datensatzes. Dies möchte ich mich mit dem Makro machen, da das Makro automatisch die Seriendruckfelder in normalen Text umwandelt. Wenn ich die normale "Speichern"-Funktion von Word wähle, bleiben die Seriendruckfelder erhalten :-(

    Kann ich das Makro auf den ersten Datensatz beschränken?

    Viele Grüße
    Moritz

    1. Hallo Moritz,
      ja, das kannst du mit den Word-Boardmitteln sehr einfach lösen. Gehe dazu im Reiter "Sendungen" auf die Funktion "Empfängerliste bearbeiten" und wähle nur jene Datensätze aus für die du ein PDF generieren möchtest.
      lg Christian

  73. Guten Morgen Christian,

    vielen Dank für Deine schnelle Antwort. Allerdings benötige ich den Output als Doc damit ich bei Änderungen, dieses im Nachhinein noch einpflegen kann. Und Dein Makro hat die schöne Angewohnheit, die Mergefelder rauszunehmen, so dass ich den unveränderlichen Stand habe, aber bei Bedarf trotzdem den Brief nochmal korrigieren und ausdrucken kann. Daher wäre die Frage, ob es eine Möglichkeit gibt, dass er nur den ersten Datensatz als einzelnes Dokument in .doc speichert.

    Viele Grüße
    Moritz

    1. Hallo Moritz,
      ich denke das Verhalten liegt in der Natur der Serienbriefe. Das Makro speichert fertig gemergte Briefe und nicht die Ausgangsversionen. Prinzipiell kannst du mit dem Makro nicht nur PDF-Dateien sondern auch Word-Dateien speichern, aber ich denke, das hast du schon ausprobiert.
      lg Christian

    2. Kann ich denn irgendwie im Makro selber einstellen, dass er nur einen bzw. den ersten Serienbrief ausgibt? Also so a la Ende nach Druck des ersten Serienbriefs?

      Viele Grüße
      Moritz

    3. Hallo Moritz,

      du kannst die Schleife so verändern, dass die Ausgabe auf den ersten Datensatz beschränkt wird, indem du die Bedingungen in der Schleife, von

      If .DataSource.ActiveRecord < .DataSource.RecordCount Then
      .DataSource.ActiveRecord = wdNextRecord
      Else
      Exit Do
      End If

      auf

      Exit Do

      abänderst. Allerdings wird das Ergebnis das selbe bleiben, als wie wenn du über die in der ersten Antwort beschriebenen Word-Boardmittel die Anzahl der Empfänger einschränkst.

      lg Christian

    4. Hallo Christian,

      das ist genau die Lösung, die ich gesucht habe :-) Vermutlich habe ich mich nicht so ganz korrekt ausgedrückt, aber genau das ist die Lösung.

      Bei mir funktioniert es so, allerdings bricht das Makro bei meiner Kollegin ab und wirft Fehlercode 5152 aus. Außerdem erhalten ich, wenn ich das Makro speichere, ein Dialogfeld ob ich die Normal.dot speichern möchte. Dies ist nur bei meiner Kollegin der Fall. Bei mir funktioniert alles.

      Hast Du eine Idee?

      Viele Grüße
      Moritz

    5. Hallo Moritz,

      die Fehlermeldungen von Word sind leider wenig aussagekräftig und auch das Problem mit Normal.dot lässt sich nicht eindeutig fest machen.
      Funktioniert genau dasselbe Dokument bei dir einwandfrei oder handelt es sich beim Dokument deiner Kollegin um ein anderes? - Dann würde ich hier das Dokument neu erzeugen und den Inhalt per Copy & Paste transferieren. Vielleicht hilft es auch das Makro nicht in Normal.dot sondern in das aktive Dokument zu kopieren.

      lg Christian

  74. Hallo zusammen,

    ich hoffe, dass ich hier richtig bin.
    Ich habe mir ein ähnliches Makro aus dem Internet gesucht, habe jedoch immer das gleiche Problem.
    Bei gleichem Nachnamen in 2 Serienbriefen, was hier der "ID" entspricht, jedoch unterschiedlichen Vornamen wird immer nur eine der Dateien mit gleichem Nachnamen exportiert.

    Ich stelle euch hier das Makro mal rein und hoffe, dass ihr mir helfen könnt:

    Sub Serienbrief_im_PDF_Format_speichern()
    ' set variables
    Dim iBrief As Integer, sBrief As String
    Dim AppShell As Object
    Dim BrowseDir As Variant
    Dim Path As String

    ' catch any errors
    On Error GoTo ErrorHandling

    ' determine path
    Set AppShell = CreateObject("Shell.Application")
    Set BrowseDir = AppShell.BrowseForFolder(0, "Speicherort für Serienbriefe auswählen", 0, 16)

    If BrowseDir = "Desktop" Then
    Path = CreateObject("WScript.Shell").SpecialFolders("Desktop")
    Else
    Path = BrowseDir.items().Item().Path
    End If

    If Path = "" Then GoTo ErrorHandling

    Path = Path & "\Serienbrief-" & Format(Now, "dd.mm.yyyy-hh.mm.ss") & "\"
    MkDir Path

    On Error GoTo ErrorHandling

    ' hide application for better performance
    MsgBox "Serienbriefe werden exportiert. Dieser Vorganag kann einige Minuten dauern - Microsoft Word wird während dieser Zeit ausgeblendet", vbOKOnly + vbInformation
    Application.Visible = False

    ' create bulkletter and export as pdf
    With ActiveDocument.MailMerge
    .DataSource.ActiveRecord = 1
    Do
    .Destination = wdSendToNewDocument
    .SuppressBlankLines = True
    With .DataSource
    .FirstRecord = .ActiveRecord
    .LastRecord = .ActiveRecord
    sBrief = Path & .DataFields("Nachname").Value & ".pdf"
    End With
    .Execute Pause:=False

    If .DataSource.DataFields("Nachname").Value > "" Then
    ActiveDocument.SaveAs FileName:=sBrief, FileFormat:=wdFormatPDF
    End If
    ActiveDocument.Close False

    If .DataSource.ActiveRecord 0 Then
    MsgBox "Unbekannter Fehler: " & Err.Number & " - Bitte Makro erneut ausführen.", vbOKOnly + vbCritical
    Else
    MsgBox "Serienbriefe erfolgreich exportiert", vbOKOnly + vbInformation
    End If

    End Sub

    1. Hallo Peter,

      das ist auch nicht weiter verwunderlich, da du mit der Code-Zeile

      sBrief = Path & .DataFields("Nachname").Value & ".pdf"

      bei gleichen Nachnamen auch immer gleiche Dateinamen generierst und sich die Dateien daher gegenseitig überschreiben. Du musst hier zumindest noch den Vornamen einfügen.

      Schau dir doch auch mal meine Weiterentwicklung formletter2pdf (http://www.formletter2pdf.com) an. Dort kannst du den Dateinamen komfortabel über eine Oberfläche setzen.

      lg Christian

  75. Guten Abend
    So ich hab es nun wieder mal versucht. Hab Vorlage mit Makro erstellt. Makro erstellt. Serienbrief erstellt, Serienbrief fertig gestellt und wollte nun das Marko laufen lassen und jetzt kommt die Fehlermeldung

    Fehler beim Kompilieren:
    Methode oder Datenobjekt nicht gefunden

    Wo liegt nun der Wurm drin??

    1. ups sorry war vorhin zu schnell mit abschicken. Habe den Fehler gefunden. Nun sagt er aber immer das Desktop kein gültiger Speicherort ist :/
      auch wenn ich einen Neuen Ordner wähle kommt diese Meldung. ist die Bezeichnung falsch??

    2. Hallo Sandra,

      hast du den Code 1:1 verwendet und nur die genutzten Spaltennamen angepasst oder auch andere Änderungen vorgenommen. Mir scheint du hast im ganzen keinen vollständigen bzw. gültigen Pfadnamen generiert.

      formletter2pdf (www.formletter2pdf.com) nimmt dir die Arbeit des Code-Anpassens für dier Erstellung von Wunschdateinamen übrigens ab - hast da dir das Marko schon mal angesehen?

      lg Christian

  76. Hallo Christian,

    wie muss ich dein Standardmakro verändern, damit beim Makro kein Ordner erzeugt wird, in dem die Datei abgelegt wird, sondern ich konkret einen bestimmten Ordner auswählen kann. Also Beispiel: Wir nutzen dies für die Sachbearbeitung bei Mitarbeitern. Nun möchten wir einzelne Vertragsdokumente in dem Ordner des Mitarbeiters ablegen ohne dass ein Unterordner "Serienbrief DD.MM.YYYY" erzeugt wird. Ich habe schon probiert selber am Path rumzuschreiben, hat aber nicht geklappt.

    Viele Grüße
    Moritz

    1. Hallo Moritz,

      damit kein zusätzlicher Ordner erzeugt wird, sondern die Dateien direkt im angegebenen Pfad gespeichert werden, musst du die beiden folgenden Zeilen im Code

      Path = Path & "\Serienbrief-" & Format(Now, "dd.mm.yyyy-hh.mm.ss") & "\"
      MkDir Path

      durch die Folgende ersetzten

      Path = Path & "\"

      lg Christian



Zu diesem Artikel können keine neuen Kommentare mehr abgegeben werden.