1.6k Aufrufe
Gefragt in Textverarbeitung von ahorn38 Experte (3.2k Punkte)
Hallo,

ich habe eine word-Datei die aus mehreren Seiten mit identischem Aufbau besteht. (vormals Serienbrief)
Ich möchte aus der Adresse jeweils den Namen "auslesen" und in einer gesonderten Datei (Excel-Sheet) speichern.
Der Name steht auf jeder Seite an gleicher Position/Zeile (jeweils unter der Anrede "Herr" oder "Frau").
Ich bin in VBA allerdings absoluter Neuling, so dass ich über die Makro-Aufzeichnung auch nicht weitergekommen bin.
Hat jemand einen Tipp, wie ich mein Problem angehen kann? Danke für jeden Hnweis!
VG A.

14 Antworten

0 Punkte
Beantwortet von
Hallo Andreas,

na so ein schlimmer Neuling bist du ja nun auch nicht mehr. Stell dein
Licht nicht so unter den Scheffel ;-)

Serienbrief mal rückwärts? Auch nicht schlecht! Was sind denn die
Bedingungen? Sollen die Daten in eine neue Exceldatei oder eine
bestehende fortgeschrieben werden? In lezterem Fall: Ist die Excel-
Datei bereits geöffnet oder soll sie erst über Pfad geöffnet werden?
Und soll das Ganze einmalig oder regelmäßig ausgeführt werden?

Gruß Mr. K.
0 Punkte
Beantwortet von
Hier mal der einfachste und üblichste Weg die Daten in ein neues
ExcelDokument zu bekommen. Im Word im fertigen Serienbrief
sollte in einem beliebigen Modul inetwa dieser Code stehen, den du
z.B. über F5 oder über Ansicht -> Makro -> Ausführen startest:

Sub NamenAuslesen()

Dim exl As Object

Zeile = 3 'Zeile in der der Name steht. (bei Zeilenumbruch mit Enter)
Blatt = "Tabelle1" 'ExcelBlatt in dem die Daten erscheinen sollen.


'Erstellt eine neues ExcelFenster
Set exl = CreateObject("excel.application")
exl.Visible = True

'Erstellt im ExcelFenster eine neue Arbeitsmappe
'wb ist hier die Variable für das Workbook-Objekt
Set wb = exl.workbooks.Add
wb.sheets(Blatt).Cells(1, 1) = "Vorname"
wb.sheets(Blatt).Cells(1, 2) = "Nachname"

'Liest die Namen aus Word aus. Section ist ein Abschnitt, hier eine
Seite
'Paragraphs sind die spiegelverkehrten P-Zeichen (Zeilenumbrüche
mit Enter)
For i = 1 To ActiveDocument.Sections.Count - 1
Person =
ActiveDocument.Sections(i).Range.Paragraphs(3).Range.Text


'sucht das erste Leerzeichen und trennt in Vor- und Nachnamen
Trennung = InStr(1, Person, " ")
If Trennung > 0 Then
Vorname = Left(Person, Trennung - 1)
Nachname = Right(Person, Len(Person) - Trennung)
Else
Nachname = Person
End If

wb.sheets(Blatt).Cells(i + 1, 1) = Vorname
wb.sheets(Blatt).Cells(i + 1, 2) = Nachname

Next i

End Sub

wb ist hier das frisch erstellte Workbook. Alle dahinter stehenden
Eigenschaften sind typische Excel-Eigenschaften und können wie
gewohnt genutzt werden. Da diese aber Word nicht bekannt sind,
werden sie nicht vom VBA-Objekt-Controller automatisch
vorgeschlagen. Man sollte seine Wunsch-Eigenschaften also
kennen, um sie korrekt anzusprechen zu können. Am besten du
probierst deine Befehle zunächst in Excel aus und knüpfst sie erst
dann an das wb.Objekt an.

Gruß Mr. K.
0 Punkte
Beantwortet von
Wenn du lieber auf ein bereits geöffnetes Excel zugreifen willst, kannst
du auch mal hier schauen.
Der Code ist für VB-Express geschrieben. In Word oder Access solltest
du also die erste und letzte Zeile "Public Class" bzw. "End Class"
weglassen, das ist hier dein Modul. Außerdem solltest du vor den
Objektzuweisungen den Schlüsselbefehl Set mitgeben. Set Exl =
GetObject(, "Excel.Application")
Das ist in Office wichtig aber in VB-
Express nicht nötig. Ansonsten dürfte der Code genauso auch hier
funktionieren.

Gruß Mr. K.
0 Punkte
Beantwortet von ahorn38 Experte (3.2k Punkte)
Hallo Mr.K,

danke für deine schnelle Antwort. Im Vergleich mit dir bin ich trotzdem der absolute Anfänger! Nur im excel kenne ich mich ein bißchen aus (auch Danke deiner vielfältigen Unterstützung!), im word allerdings gar nicht!
Du hast mit deinem Code schon im wesentlichen den Kern getroffen. Die Ausgabe soll in eine neue leere Excel-Datei.

Allerdings hakt der Code noch bei

Person = ActiveDocument.Sections(i).Range.Paragraphs(3).Range.Text

""Element nicht in der Sammlung"

Ich habe das Muster der Datei mal zum Hochladen:
http://www.xup.in/dl,15149509/Testdatei_SB.docx/

Danke und viele Grüße!
A.
0 Punkte
Beantwortet von
Also bei mir klappts. Sowohl mit Office 2000 als auch mit 2010

Allerdings bin ich von einem aus einem Seriendruck heraus entstandenen Dokument ausgegangen, bei dem jede Seite mit einem "Abschnittswechsel, nächste Seite" endet.

Leider kann ich deine Datei nicht öffnen, da sie von meinem Browser als unsicher geblockt wurde. Versuch mal einen anderen FileHoster oder die Dropbox.

Mr. K.
0 Punkte
Beantwortet von ahorn38 Experte (3.2k Punkte)
Hallo,

sicher stimmt da noch was in meiner Struktur nicht....
Aber noch eine Frage: Du hast in deinem Code Zeile=3 für die Seitenposition des Namen definiert. Im Code selbst wird "Zeile" aber nicht wieder verwendet. Hat das einen Grund?

Ich habe die Musterdatei noch mal woanders hochgeladen, vlt. klappt es jetzt.
http://www.file-upload.net/download-11683547/TestdateiSB.docx.html

VG
Andreas
0 Punkte
Beantwortet von
Hallo Andreas,

auch mit deiner Testdatei funktioniert das bei mir. Allerdings habe ich
noch ne Kleinigkeit entdeckt, die evtl. der Grund für dein Problem sein
könnte. ---sorry für den Bug.

Ersetze
Person =
ActiveDocument.Sections(i).Range.Paragraphs(3).Range.Text
durch
Person =
ActiveDocument.Sections(i).Range.Paragraphs(Zeile).Range.Text

Nach deiner Testdatei solltest du oben im Makro der Variable Zeile noch
den Wert 9 zuweisen. dann müsste es klappen.

Unter umständen solltest du auch in der For To Zeile das -1 entfernen.
Bei mir war es nötig um den von dir genannten Fehler auszuschließen.
Kann aber sein, dass (je nach Aufbau deiner Datei) dadurch dann bei
dir der letzte Wert fehlt.
0 Punkte
Beantwortet von
Natürlich sollte Person = ... in nur einer Zeile stehen. Das Fenster hier
ist einfach viel zu schmal :-(
0 Punkte
Beantwortet von ahorn38 Experte (3.2k Punkte)
Hallo,

noch mal Danke für deine Geduld und deine wirklich tolle Unterstützung!!!
Dein Code funktioniert und ist genau die Lösung meines Problems, aber....

Der Code funktioniert in der Testdatei, aber nicht in meinem Seriendokument. Ich vermute den Fehler darin, dass der Code die "Sections" nicht identifizieren kann, weil die Seiten nicht durch Sonderzeichen voneinander getrennt sind. Der Code wird mein Seriendokument als fortlaufenden Text verstehen und nicht Seite für Seite...???

VG A.
0 Punkte
Beantwortet von
Hallo Andreas,

dann ist es nach meiner Einschätzung kein wirkliches
Seriendokument. Oder es wurde auf irgendeine mir unbekannte Art
und Weise nachbearbeitet. Hast du mal geprüft wie die
Seitentrennung erfolgt? Dazu brauchst du in der Symbolleiste nur
das Spiegelverkehrte P (steht für Paragraph) anklicken, dann siehst
du alle Umbruchzeichen. Aber das weißt du sicher.

Wenn es wirklich fortlaufender Text ist, (kann ich mir nicht vorstellen)
könnte man die Schleife so aufbauen. Zähle die Zeilenumbrüche (P-
Zeichen) pro Seite. Sofern kein Wagenrücklaufzeichen (EnterPfeil) zu
sehen ist, kannst du das auch in der Statusleiste ablesen. Definiere
nun oben die neue Variable Seitenzeilen mit diesem Wert (bei mir
57) und schreibe den Code wie folgt um.

Sub NamenAuslesen()

Dim exl As Object

Zeile = 9 'Zeile in der der Name steht. (bei Zeilenumbruch mit Enter)
Seitenzeilen = 57 'Absätze pro Seite bei fortlaufendem Text
Blatt = "Tabelle1" 'ExcelBlatt in dem die Daten erscheinen sollen.


'Erstellt eine neues ExcelFenster
Set exl = CreateObject("excel.application")
exl.Visible = True

'Erstellt im ExcelFenster eine neue Arbeitsmappe
'wb ist hier die Variable für das Workbook-Objekt
Set wb = exl.workbooks.Add
wb.sheets(Blatt).Cells(1, 1) = "Vorname"
wb.sheets(Blatt).Cells(1, 2) = "Nachname"

'Liest die Namen aus Word aus.
'Paragraphs sind die spiegelverkehrten P-Zeichen (Absatzeichen)
For i = Zeile To ActiveDocument.Paragraphs.Count Step Seitenzeilen
k = k + 1
Person = ActiveDocument.Paragraphs(i).Range.Text


'sucht das erste Leerzeichen und trennt in Vor- und Nachnamen
Trennung = InStr(1, Person, " ")
If Trennung > 0 Then
Vorname = Left(Person, Trennung - 1)
Nachname = Right(Person, Len(Person) - Trennung)
Else
Nachname = Person
End If

wb.sheets(Blatt).Cells(k + 1, 1) = Vorname
wb.sheets(Blatt).Cells(k + 1, 2) = Nachname

Next i

End Sub


Gruß Mr. K.
...