Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1940to1944
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Serienbrief per VBA

Serienbrief per VBA
15.08.2023 06:27:42
Chris
Hallo Forum,

ich möchte per VBA Serienbriefe in Word aus Excel heraus erstellen. Die Serienbriefe sollen für jeden Datensatz als jeweils eine PDF-Datei gespeichert werden.

Anbei Beispieldateien. Enthalten sind:

1x Word-Datei: Die Serienbriefvorlage mit zwei Feldern, Vor- und Nachname. Aus dieser Datei sollen später für jeden Datensatz jeweils eine eigene PDF-Datei erstellt werden.
1x Datenquelle (Excel) für den Serienbrief mit zwei Beispielnamen.
1x Das Makro (Excel). Als Pfad habe ich den Desktop-Pfad genommen. Bitte anpassen.

Das enthaltende Makro erstellt die Serienbriefe, welche jedoch nicht als PDF gespeichert werden. Vielleicht weiß jmd. wie man, was man ergänzen/ändern muss.

Hier der Link:

https://www.herber.de/bbs/user/162158.zip

Schon mal Danke!

Chris

13
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
Word-Funktion...?
15.08.2023 08:00:21
MCO
Guten Morgen!

Ich kann mich irren, aber ist das, was du da beschreibst, nicht der Standard für einen Serienbrief?

WORD ist das führende Programm, zieht sich die Daten aus Excel und druckt die gewünschten Datensätze, wenn gewünscht auch über einen pdf-Drucker.

Hört sich für mich nicht nach einer Anwendung für ein (Excel-)Makro an...

Gruß, MCO
Word-Funktion...?
15.08.2023 10:28:48
Chris
Hallo MCO,

in meiner Anwendung wird das Makro aus Excel heraus gestartet und die Daten werden daraufhin innerhalb Word in die Serienbrief eingefügt. Word ist daher aus meiner Sicht nicht das führende Programm aus dem das Makro gestartet wird.

Gruß
Chris
Anzeige
AW: Serienbrief per VBA
15.08.2023 08:47:39
ralf_b
ich bezweifele das dieses Programm so gelaufen ist.

zweimal "end sub" untereinander. zumindest mein Debugger hat damit ein Problem.
arrNamen wird im Drucken-Makro nicht gefüllt aber verwendet. Auch hier landet man direkt in der Fehlerbehandlung.
Zum speichern als PDF empfiehlt sich ExportasFixedformat.
Serienbrief per VBA
15.08.2023 10:36:42
Chris
Hallo ralf_b,

Danke für deine Hinweise. 2x End sub ist natürlich nicht möglich...ist geändert., ebenso habe ich ExportAs.. eingfügt.

Ich bin nicht der große VBA-Experte. Aus meiner Sicht wird die Variabel arrNamen im Function-Teil gefüllt: Es sind die Seriendruckfelder für den Vor- und Nachnamen.
Vielleicht hast du noch konkrete Änderungs-/Ergänzungstipps in Sachen arrNamen.

Nochmals Danke
Chris



Hier das Makro:




Option Explicit

Public arrNamen() As String
Public PDFpath As String

'Verweise
'DAO 3.6
'Word 1x
Public Function leseDB() As Boolean
On Local Error GoTo leseDBERR
Dim bErgebnis As Boolean
Dim strDatenquelle As String
Dim myDB As Database, myREC As Recordset
Dim lngAnzahl As Long
Dim lngZahler As Long

PDFpath = Environ("userprofile") & "\Desktop\" 'anpassen
strDatenquelle = Environ("userprofile") & "\Desktop\Datenquelle.xlsx" 'anpassen

Dim strConnection As String
strConnection = "Provider=Microsoft.Jet.OLEDB.4.0;" _
& "Data Source=" & strDatenquelle & ";" _
& "Mode=Read;Extended Properties=""HDR=YES;IMEX=1;"";" _
& "Jet OLEDB:Engine"
Set myDB = DAO.OpenDatabase(strDatenquelle)
'!!! SELECT anpasssen !!!
Set myREC = myDB.OpenRecordset("SELECT * FROM B1RDSL$", dbOpenSnapshot)
With myREC
.MoveLast
lngAnzahl = .RecordCount
ReDim arrNamen(2, lngAnzahl - 1)
.MoveFirst
For lngZahler = 0 To lngAnzahl - 1
arrNamen(0, lngZahler) = .Fields("Vorname").Value
arrNamen(1, lngZahler) = .Fields("Nachname").Value
arrNamen(2, lngZahler) = PDFpath & "TestSB" & UCase(.Fields("Nachname").Value) & ", " & .Fields("Vorname").Value & ".pdf"
.MoveNext
'evtl DoEvents
Next lngZahler
.Close
End With
Set myREC = Nothing
myDB.Close
bErgebnis = True
leseDBOUT:
leseDB = bErgebnis
Set myDB = Nothing
Exit Function
leseDBERR:
bErgebnis = False
Resume leseDBOUT
End Function

Public Sub ausDrucken()

On Local Error GoTo ausDruckenERR
Application.DisplayAlerts = False
Dim objWinword As Word.Application, WinDoc As Word.Document
Dim strDatenquelle As String
Dim strWordvorlage As String
Dim newDoc As Word.Document
Dim strBrief As String
Dim lngAbschntitt As Long
Dim lngZahler As Long

strDatenquelle = Environ("userprofile") & "\Desktop\Datenquelle.xlsx" 'anpassen
strWordvorlage = Environ("userprofile") & "\Desktop\Serienbrief.docx" 'Anpassen
PDFpath = Environ("userprofile") & "\Desktop\" 'anpassen
Set objWinword = New Word.Application
With objWinword
.Visible = False
Set WinDoc = .Documents.Open(strWordvorlage)
WinDoc.MailMerge.OpenDataSource Name:= _
strDatenquelle, _
ConfirmConversions:=False, ReadOnly:=False, LinkToSource:=True, _
AddToRecentFiles:=False, PasswordDocument:="", PasswordTemplate:="", _
WritePasswordDocument:="", WritePasswordTemplate:="", Revert:=False, _
Format:=wdOpenFormatAuto, Connection:= _
"Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin;Data Source=" & strDatenquelle & ";Mode=Read;Extended Properties="""";Jet OLEDB:System database="""";Jet OLEDB:Registry Path="""";Jet OLEDB:Engine Type=5;Jet OLEDB:Database" _
, SQLStatement:="SELECT * FROM `B1RDSL$`", SQLStatement1:="", SubType:= _
wdMergeSubTypeAccess
With WinDoc.MailMerge
.Destination = wdSendToNewDocument
.SuppressBlankLines = True
With .DataSource
.FirstRecord = wdDefaultFirstRecord
.LastRecord = wdDefaultLastRecord
End With
.Execute Pause:=False
End With
Set newDoc = objWinword.ActiveDocument
End With
For lngZahler = 0 To UBound(arrNamen, 2) 'newDoc.Sections.Count - 2
strBrief = arrNamen(2, lngZahler)

newDoc.PrintOut Outputfilename:=strBrief, Range:=wdPrintRangeOfPages, Item:= _
wdPrintDocumentWithMarkup, Copies:=1, Pages:="s" & lngZahler + 1, PageType:= _
wdPrintAllPages, Collate:=True, Background:=True, PrintToFile:=True, _
PrintZoomColumn:=0, PrintZoomRow:=0, PrintZoomPaperWidth:=0, _
PrintZoomPaperHeight:=0

newDoc.ExportAsFixedFormat Outputfilename:=strBrief & ".pdf", _
ExportFormat:=wdExportFormatPDF, _
OpenAfterExport:=False, OptimizeFor:=wdExportOptimizeForPrint, Range:= _
wdExportAllDocument, Item:=wdExportDocumentContent, _
IncludeDocProps:=True
Next lngZahler
newDoc.Close SaveChanges:=False
WinDoc.Close SaveChanges:=False
objWinword.Quit
ausDruckenOUT:
Application.DisplayAlerts = True
Set newDoc = Nothing
Set WinDoc = Nothing
Set objWinword = Nothing
Exit Sub
ausDruckenERR:
'MsgBox err .....
Resume ausDruckenOUT
End Sub
Anzeige
Serienbrief per VBA
15.08.2023 10:38:32
Chris
noch offen...
Serienbrief per VBA
15.08.2023 12:13:22
Chris
Ich erhalte folgende Fehlermeldung:

Index außer des gültigen Bereichs bei der Zeile



For lngZahler = 0 To UBound(arrNamen, 2)


Vielleicht weiß jmd., wie man die Variable mit Inhalt füllt...

Gruß
Chris
Serienbrief per VBA
15.08.2023 13:16:20
Rudi Maintaire
Hallo,
in der Druckprozedur muss
arrNamen = LeseDB()

stehen.
Hab ich nicht gefunden.

Gruß
Rudi
Serienbrief per VBA
16.08.2023 08:51:07
Chris
Hallo Rudi,

habe deinen Vorschlag umgesetzt und erhalte die Fehlermeldung "Zuweisung zu einem Datenfeld nicht möglich". Ich weiß nicht, was das bedeutet...

GRuß
Chris
Anzeige
Serienbrief per VBA
16.08.2023 00:20:17
Ulf
Hi Chris,
Da dies mein Kot, hier der auf Excel angepasste und die nötigen Verweise.
Geändert ist die Druckschleife dahingehend, dass Drucken im Hintergrund ausgeschaltet, da nicht synchronisierbar.



Option Explicit

Public arrNamen() As String
Public PDFpath As String

'Verweise
'ACEDAO C:\Program Files\Common Files\microsoft shared\OFFICE14\ACEDAO.DLL
'Word 1x
Public Function leseDB() As Boolean
On Local Error GoTo leseDBERR
Dim bErgebnis As Boolean
Dim strDatenquelle As String
Dim myDB As Database, myREC As Recordset
Dim lngAnzahl As Long
Dim lngZahler As Long
Dim strConnection As String
strDatenquelle = Environ("userprofile") & "\Desktop\Datenquelle.xlsx" 'anpassen
'Für DAO 3.6 ~ MS Access
' strConnection = "Provider=Microsoft.Jet.OLEDB.4.0;" _
' & "Data Source=" & strDatenquelle & ";" _
' & "Mode=Read;Extended Properties=""HDR=YES;IMEX=1;"";" _
' & "Jet OLEDB:Engine"
'Für MDAC-DAO
strConnection = "Excel 12.0 Xml;HDR=YES;IMEX=2;ACCDB=YES;DATABASE=" & strDatenquelle
Set myDB = DBEngine.OpenDatabase(vbNullString, False, False, strConnection)
Set myREC = myDB.OpenRecordset("SELECT * FROM [B1RDSL$]", dbOpenSnapshot)
With myREC
.MoveLast
lngAnzahl = .RecordCount
ReDim arrNamen(2, lngAnzahl - 1)
.MoveFirst
For lngZahler = 0 To lngAnzahl - 1
arrNamen(0, lngZahler) = .Fields("Vorname").Value
arrNamen(1, lngZahler) = .Fields(.Fields(1).Name).Value
arrNamen(2, lngZahler) = PDFpath & "TestSB" & UCase(.Fields(.Fields(1).Name).Value) & ", " & .Fields("Vorname").Value & ".pdf"
.MoveNext
'evtl DoEvents
Next lngZahler
.Close
End With
Set myREC = Nothing
myDB.Close
bErgebnis = True
leseDBOUT:
leseDB = bErgebnis
Set myDB = Nothing
Exit Function
leseDBERR:
Debug.Print Err.Description
bErgebnis = False
Resume leseDBOUT
End Function

Public Sub ausDrucken()
On Local Error GoTo ausDruckenERR
Application.DisplayAlerts = False
Dim objWinword As Word.Application, WinDoc As Word.Document
Dim strDatenquelle As String
Dim strWordvorlage As String
Dim newDoc As Word.Document
Dim strBrief As String
Dim lngAbschntitt As Long
Dim strConnection As String
Dim lngZahler As Long
If Not leseDB() Then
MsgBox "Auslesen der Felder nicht möglich", vbCritical + vbOKOnly, "Fehler"
Exit Sub
End If
strDatenquelle = Environ("userprofile") & "\Desktop\Datenquelle.xlsx"
strWordvorlage = Environ("userprofile") & "\Desktop\Serienbrief.docx"
PDFpath = Environ("userprofile") & "\Desktop\"
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strDatenquelle & ";Mode=Read;Extended Properties="""";Jet OLEDB:System database="""";Jet OLEDB:Registry Path="""";Jet OLEDB:Engine Type=5;Jet OLEDB:Database"
Set objWinword = New Word.Application
With objWinword
.Visible = False
Set WinDoc = .Documents.Open(strWordvorlage)
WinDoc.MailMerge.OpenDataSource Name:=strDatenquelle, ConfirmConversions:=False, ReadOnly:=False, LinkToSource:=True, _
WritePasswordDocument:="", WritePasswordTemplate:="", Revert:=False, Format:=wdOpenFormatAuto, _
Connection:=strConnection, SQLStatement:="SELECT * FROM [B1RDSL$]", SQLStatement1:="", SubType:=wdMergeSubTypeAccess
With WinDoc.MailMerge
.Destination = wdSendToNewDocument
.SuppressBlankLines = True
With .DataSource
.FirstRecord = wdDefaultFirstRecord
.LastRecord = wdDefaultLastRecord
End With
.Execute Pause:=False
End With
Set newDoc = objWinword.ActiveDocument
End With
For lngZahler = 0 To UBound(arrNamen, 2)
strBrief = arrNamen(2, lngZahler)
newDoc.PrintOut OutputFilename:=strBrief, Range:=wdPrintRangeOfPages, Item:= _
wdPrintDocumentWithMarkup, Copies:=1, Pages:="s" & lngZahler + 1, PageType:= _
wdPrintAllPages, Collate:=True, Background:=False, PrintToFile:=True, _
PrintZoomColumn:=0, PrintZoomRow:=0, PrintZoomPaperWidth:=0, _
PrintZoomPaperHeight:=0
newDoc.SaveAs Filename:=strBrief, FileFormat:=wdFormatPDF
Next lngZahler
newDoc.Close SaveChanges:=False
WinDoc.Close SaveChanges:=False
objWinword.Quit
ausDruckenOUT:
Application.DisplayAlerts = True
Set newDoc = Nothing
Set WinDoc = Nothing
Set objWinword = Nothing
Exit Sub
ausDruckenERR:
'MsgBox err .....
Resume ausDruckenOUT
End Sub




Habe Fertig
Anzeige
Serienbrief per VBA
16.08.2023 08:57:29
Chris
Hallo Ulf,

Die Verweise sind gesetzt, die Datei ACODAO existiert bei mir nicht.
Die erste If-Schleife im Druckcode habe ich aus kommentiert, da sie sofort die Fehlermeldung rauswirft, Drucken nicht möglich.

Weiterhin erhalte ich die Meldung "außerhalb des gültigen Bereichs"

bei

For lngZahler = 0 To UBound(arrNamen, 2).

Das ganze scheint wohl wirklich kompliziert zu sein.

Evtl. ist die Seriendruckfunktion ausschließlich innerhalb von Excel einfacher umzusetzen und die Word-Dokumente vorab in Excel zu erstellen?! Hast du Erfahrung damit?

Gruß
Chris
Anzeige
Serienbrief per VBA
16.08.2023 09:35:26
Ulf
Hi Chris,
liegt an fehlendem:
AccessDatabaseEngine_X64.exe
X64 DataAccessObjects
waren vor Win 10 implementiert. Download:
https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=2ahUKEwizqbH60-CAAxUH_KQKHRVGC7EQFnoECB8QAQ&url=https%3A%2F%2Fwww.microsoft.com%2Fen-US%2Fdownload%2Fdetails.aspx%3Fid%3D54920&usg=AOvVaw2HhLtNEPa0MwHjjnNhf0U6&opi=89978449
alles Gewürge mit Excel ist weitaus fehleranfälliger, man kann aber alternativ:
Datenquelle öffnen, Zeilen durchlaufen und wie im Bsp das Array füllen. Datei schliessen.Makro starten
Datenquelle offen halten und Schleife im Druckmakro adhoc füllen. Dann kommt aber der Rattenschwanz mit datei öffnen, ggf geöffnete durchlaufen...
Die Abarbeitung ist aber identisch und da man mit SQL auf Excel zugreifen kann weitaus flexibler wie angegeben (entspricht dem Vorgehen in Word).
hth
Ulf
Anzeige
Serienbrief per VBA
16.08.2023 12:24:44
Chris
Hallo Ulf,

danke für die Rückmeldung. Da ich auf einem Dienstrechner unterwegs bin, scheidet *.exe aus ...

Auch wenn fehleranfälliger werde ich wohl den Weg über Excel gehen. Heißt: Das Worddokument in Excel händisch einmalig abschreiben, und per Schleife die "Seriendruckfelder", d.h. Zellen, aus der Datenquelle füllen. Hab erste Tests gemacht, funktioniert soweit.

Jedenfalls Danke für die Hilfe. Dass dies ohne die *.exe nicht funktionieren wird, ist auch eine Lösung... :-)

OWT.

Gruß
Chris
Serienbrief per VBA
19.08.2023 19:20:30
Oberschlumpf
scheint ja erledigt zu sein, dann muss die Option "Frage noch offen" nicht aktiv sein
Anzeige

Links zu Excel-Dialogen

Anzeige

Infobox zum Thema

EXCEL - Serienbrief per VBA


Inhaltsverzeichnis


Die Fragestellung


Du möchtest mithilfe von VBA in Excel einen Serienbrief erstellen, der Daten aus einer Excel-Tabelle in ein Word-Dokument überträgt und für jeden Datensatz ein individuelles Dokument generiert.


Erläuterung des Problems {#erläuterung-des-problems}


Die Erstellung eines Serienbriefs erfordert normalerweise, dass du eine Datenquelle (z.B. eine Excel-Tabelle) mit einem Word-Dokument verknüpfst, um personalisierte Dokumente zu generieren. Dies kann manuell über die Serienbrief-Funktion in Word erfolgen, aber die Automatisierung mit VBA kann den Prozess effizienter gestalten, besonders wenn er regelmäßig durchgeführt wird.


Lösung des Problems {#lösung-des-problems}


Hier ist ein grundlegendes VBA-Beispiel, das zeigt, wie du einen Serienbrief mit Excel und Word erstellen kannst:

Sub CreateMailMerge()

    Dim wordApp As Object
    Dim wordDoc As Object
    Dim excelSheet As Worksheet
    Dim dataRange As Range
    Dim i As Long

    ' Excel-Datenbereich festlegen, der für den Serienbrief verwendet wird
    Set excelSheet = ThisWorkbook.Sheets("Datenblatt") ' Anpassen an den Namen deines Blattes
    Set dataRange = excelSheet.Range("A1:C10") ' Anpassen an deinen Datenbereich

    ' Word-Instanz erstellen
    Set wordApp = CreateObject("Word.Application")
    wordApp.Visible = True

    ' Neues Word-Dokument erstellen
    Set wordDoc = wordApp.Documents.Add

    ' Serienbrief-Funktion in Word starten
    With wordDoc.MailMerge
        .MainDocumentType = wdFormLetters

        ' Datenquelle festlegen
        .OpenDataSource _
            Name:=ThisWorkbook.FullName, _
            AddToRecentFiles:=False, _
            Revert:=False, _
            Format:=wdOpenFormatAuto, _
            Connection:="Entire Spreadsheet", _
            SQLStatement:="SELECT * FROM `Datenblatt$`" ' Anpassen an den Namen deines Blattes

        ' Serienbrief-Felder einfügen
        For i = 1 To dataRange.Columns.Count
            wordDoc.Content.InsertAfter "<<" & dataRange.Cells(1, i).Value & ">> "
            wordDoc.Content.InsertParagraphAfter
        Next i

        ' Serienbrief ausführen
        .Destination = wdSendToNewDocument
        .Execute Pause:=False
    End With

    ' Aufräumen
    Set wordDoc = Nothing
    Set wordApp = Nothing
    Set excelSheet = Nothing
    Set dataRange = Nothing

End Sub

Dieses Skript erstellt ein neues Word-Dokument und verknüpft es mit dem aktuellen Excel-Arbeitsblatt als Datenquelle für den Serienbrief. Es fügt dann für jede Spalte im definierten Datenbereich ein Serienbrief-Feld in das Word-Dokument ein und führt den Serienbrief aus.


Anwendungsbeispiele aus der Praxis


  • Kundenkommunikation: Erstellen von personalisierten Anschreiben für eine Kundenliste.
  • Event-Management: Versand von Einladungen zu einer Veranstaltung mit individuellen Details für jeden Gast.

Tipps


  • Stelle sicher, dass Word auf deinem Computer installiert ist und dass du Zugriff auf die Word-Objektbibliothek hast.
  • Teste das Skript zunächst mit einer kleinen Datenmenge, um sicherzustellen, dass alles wie erwartet funktioniert.

Verwandte Themenbereiche


  • VBA-Programmierung
  • Automatisierung von Office-Anwendungen
  • Serienbriefe und Dokumentenmanagement

Zusammenfassung


Die Automatisierung eines Serienbriefs mit VBA in Excel kann den Prozess der Erstellung personalisierter Dokumente erheblich beschleunigen. Das obige Beispiel zeigt die grundlegenden Schritte, um eine Verknüpfung zwischen einem Excel-Datenbereich und einem neuen Word-Dokument herzustellen. Dieser Ansatz kann für eine Vielzahl von Anwendungen angepasst werden, um Zeit zu sparen und die Genauigkeit bei der Erstellung von Massendokumenten zu erhöhen.

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige