Frage von jklfgvhbr, 73

Wie extrahiere ich bestimmte Daten aus pdfs?

Hi Leute,

Die bisherige Kontaktliste von einem übernommenen kleinen Unternehmen besteht aus einem PDF Dokument mit ca.1600 Seiten. Jede Seite ist gleich aufgebaut (Name, Email, Phone etc.). Ich suche nun nach einer Möglichkeit von jeder Seite die Kontaktdaten in ein exelsheet zu extrahieren. Vorweg, ich habe keinerlei Kenntnisse bzgl VBA.

Ich hoffe Ihr könnt mir helfen, vielen Dank schon Mal und liebe Grüße, Alex

Expertenantwort
von Ninombre, Community-Experte für Excel, 27

Wenn Du das komplette PDF in Excel hast, kann man (bei halbwegs systematischem Aufbau) auch ohne VBA die relevanten Daten rausziehen. Dazu wäre allerdings einen anonymisierten Screenshot oder ähnliches der Datei zwingend notwendig (oder Du müsstest den Aufbau wirklich griffig beschreiben), damit passende Formeln und Ideen geliefert werden können.

Nur als Ansätze: 

Wenn die Reihenfolge gleich ist, kann man über die Zeilendifferenzen gehen (1. Zeile = Firma, 2. Zeile = Ansprechpartner, 3. Zeile = Adresse etc.)

E-Mail Adressen enthalten immer @ - das kann man suchen

Postleitzahlen als 5stellige Werte finden sich auch recht einfach
usw.


edit: sehe gerade das ich das gleiche wie Iamiam geschrieben hab. War zwar dann unnötige Schreibarbeit, zeigt aber das die Idee vielleicht nicht ganz abwegig ist.


Kommentar von jklfgvhbr ,

Und genau da liegt das Problem. Wir haben ein anderes Unternehmen übernommen und die Customerdetails sind leider auf über 1600 Seiten verteilt. Die meisten Seiten sind halbwegs gleich aufgebaut, aber selbst bei diesen Seiten sind die Daten nicht konsistent...

Kommentar von Ninombre ,

Das löst ein Makro aber auch nicht ohne Definition wie man die relevanten Informationen erkennt. Es führt kein Weg an einer Analyse vorbei. Vielleicht sind es auch mehrere Regeln, die man nacheinander durchgehen muss um die verschiedenen Varianten zu sortieren 

Expertenantwort
von Iamiam, Community-Experte für Excel, 37

ich kopiere immer die infragekommenden Stellen in die Zwischenablage (oft mit Titelzeile pro Seite), füge das einfach so in xl ein (ggf mit Tabstopps=>Text in Spalten) und bearbeite das dann mit Formeln. Ggf vorher sortieren und so Titelzeilen sammeln und rauswerfen. Oder ein exotisches Zeichen vor die Titelzeilen-Kopie machen und diese per Wenn(links(A1;1)="_";;)-Bedingung ausschließen etc, je nach Aufbau.

Bei 10 Seiten kann man das aber auch manuell noch machen


Kommentar von jklfgvhbr ,

so würde ich das normalerweise aus machen, aber nicht bei über 1600 Seiten mit mehreren Werten pro Seite =(

Kommentar von Iamiam ,

müsste man sehen, wie die Seiten bzw Einträge aufgebaut sind. Es lässt sich fast immer was finden, aber nur sehr spezifisch!

Kannst Du ein oder 2  Musterseiten hochladen (anonymisiert, natürlich, aber schon so, dass man erkennen kann, welche Veränderungen auftreten können

Kommentar von Iamiam ,

am besten schon nach xl kopierte Demo-Seiten!

Antwort
von regex9, 52

Hast du folgendes schon einmal versucht: http://www.wikihow.com/Create-an-Excel-Spreadsheet-from-a-PDF-File? 

Kommentar von jklfgvhbr ,

Hi regex9,

ja ich habe die online tools bereits ausprobiert. Diese geben mir jeweils das komplette PDF in excel wieder aus.

Da ich aber leider wie erwaehnt keine Kenntnisse in vba habe, kann ich mit dem excel sheet nicht viel anfangen.

Ich benoetige etwas, dass mir nur die spezifischen Teile widergibt, quasi: "gehe durch das Dokument und extrahiere mir alle emailadressen, phonenumbers mit den daneben stehenden Namen in ein excel sheet"

Kommentar von regex9 ,

Zuerst einmal kannst du die Lösung aus diesem Forum versuchen: https://www.administrator.de/frage/pdf-auslesen-vba-excel-schreiben-239601.html. Ich habe es jetzt nur oberflächlich überflogen, ich denke, die PDF wird erst in eine Textdatei gespeichert und dann in eine Excel-Datei eingetragen.

Die Zeilen 33-45 musst du entfernen / ändern. An dieser Stelle werden die Daten aus der (nun) Textdatei gelesen.

Unter Zeile 55 erstellst du zuerst eine neue Sub und eine neue Function:

Sub SetCell(rngLastRow As Range, y As Integer, title As String, value As String)

rngLastRow.Cells(1, y).Value = title
rngLastRow.Cells(2, y).Value = value
End Sub

Function GetRegex(pattern As String) As Object
Dim regex = CreateObject("vbscript.regexp")
regex.MultiLine = True
regex.Pattern = pattern
GetRegex = regex
End Function

Die Function dient dazu, einen neuen regulären Ausdruck zu erstellen, der über die Textdatei schaut und die Vorkommen einer bestimmten Zeichenfolge sucht. Die Sub soll später die Werte in die Excel-Datei eintragen.

So, zurück zu Zeile 33. Dort fügst du folgende Zeilen ein:

Dim yStart As Integer = 1
Dim line As Integer = 1
Dim y As Integer

' ebenso fuer alle anderen Felder anlegen
Dim nameRegex As Object
nameRegex = GetRegex("^Wirtschaftsdaten kompakt: ([^\r\n]+)")
Set nameMatches = nameRegex.Execute(strTXT)

Die letzten 3 Zeilen musst du nochmals für jedes andere Feld, was du auslesen lassen möchtest (E-Mail, Phone, etc.) anlegen. Benenne in jedem Fall den Bezeichner nameRegex passend um (z.B. in mailRegex, etc.), die Namen müssen für das Skript eindeutig sein. Des Weiteren ist der reguläre Ausdruck noch falsch.

^Wirtschaftsdaten kompakt: ([^\r\n]+)

Dieser prüft momentan auf "Wirtschaftsdaten kompakt:" und speichert im Submatch die Zeichenfolge, die dahinter kommt (und mit einem Zeilenumbruch endet). Dein Regex könnte ungefähr so lauten:

^Name: ([^\r\n]+)

Jedes Feld (Mail, Phone, ...) bekommt also seinen eigenen Regex.

So. Nun gehe ich davon aus, dass jeder deiner Kontakte einen Namen hat. Demnach müsste die Anzahl gefundener Namen alle anderen Felder in der Menge abdecken (Beispiel: 10 Seiten mit 10 Personen = 10 Namen, maximal 10 Mail-Adressen - wobei es auch nur 9 sein könnten, oder?)

Also müssen alle Vorkommen durchlaufen werden, die jeweiligen Werte werden in die Excel-Datei gesetzt:

For y = yStart To nameMatches.Count

SetCell(rngLastRow, line, "Name", nameMatches(y).submatches(0))
line = line + 1

If mailMatches.Count > y
SetCell(rngLastRow, line, "E-Mail", mailMatches(y).submatches(0))
line = line + 1
End If
Next

Wieder muss für jedes Feld, das eingelesen werden soll, ein Block hinzugefügt werden. Exemplarisch habe ich das hier für E-Mails gemacht. Der Block besteht aus einem If, der sichergeht, dass nicht versucht wird, auf etwas zuzugreifen, was womöglich nicht existiert (z.B. die 10. Mail, obwohl es nur 9 gibt). Es garantiert allerdings keine logische Sicherheit. Gibt es bei der 3. Person beispielsweise keine E-Mail, so rutscht wohl die der 4. Person nach oben. Wenn deine PDF-Seiten aber so aufgebaut sind, dass jede Person immer die gleichen Felder hat, auch wenn der Wert leer ist, sollte dieses Problem nicht auftreten, es sei denn, der Regex ist noch falsch.

In SetCell wird also die Zelle gesetzt - in Spalte A der Bezeichner, in Spalte B der Wert. Wenn zwischen jeder Person eine Zeile frei bleiben soll, muss line = line + 1 vor Next nochmals ausgeführt werden.

Die Lösung ist allerdings ungetestet, falls Verbesserungsvorschläge vorliegen, gern.

Keine passende Antwort gefunden?

Fragen Sie die Community

Weitere Fragen mit Antworten