[Excel] PDF-Dateien auslesen, umbenennen. Mit Word und "Xpdf"...
#1
Moin, 19 

wohl öfters eine Frage in den Foren. Wie kann ich PDF-Dateien auslesen. Im folgenden mit Word und dem Open Source Projekt "Xpdf" gemacht: 21 

Bitte die ReadMeFirst.txt erst lesen. Dort stehen ein paar Stolperfallen. Exclamation 

Hier der Code aus Modul1 (mit Word):
Code:
Option Explicit
' Wenn Word nicht offen ist wird diese Variable auf True
' gesetzt und Word am Ende wieder geschlossen
' War Word schon offen, beleibt es das auch
Dim blnTMP As Boolean
'################################################################################################
' Module    : Modul1
' Procedure : Main_1
' Author    : Case (Ralf Stolzenburg)
' Date      : 13.08.2023
' Purpose  : Aus PDF-Dateien etwas nach Excel auslesen - PDF-Dokumente danach umbenennen
' Purpose  : Werte werden in Excel eingelesen - inklusive alter und neuer Dateiname
' Note      : Funktioniert erst ab Office/Word/Excel 2013!!!!!!!!!!
' Purpose  : Veröffentlicht auf CEF "https://www.clever-excel-forum.de/index.php" am 13.08.2023
' Purpose  : In der Rubrik "Beispiele und Workshops" unter "mit VBA"
'################################################################################################
Public Sub Main_1()
    ' Dimensionieren der Variablen
    Dim objDocument As Object
    Dim strTrenn() As String
    Dim strDatei As String
    Dim strTMP1 As String
    Dim strTMP As String
    ' Wenn benötigt nächste Zeilen auskommentieren
    'Dim objFSO As Object
    'Dim varDir As Object
    Dim strDir As String
    Dim objApp As Object
    Dim lngCalc As Long
    Dim lngTMP As Long
    Dim lngRef As Long
    ' Wenn ein Fehler auftritt gehe zu der angegebenen Sprungmarke
    On Error GoTo Fin
    ' Die Excelapplikation wird ruhig gestellt
    With Application
        ' Keine Bildschirmaktualisiereung
        .ScreenUpdating = False
        ' Falls es ein Ereignismakro gibt (z. B. Worksheet_Change) wir es NICHT aufgerufen
        .EnableEvents = False
        ' Die eingstellte Formelkalkulation wird abgerufen
        lngCalc = .Calculation
        ' Zellbezüge, Zeilen- und Spaltenköpfe, Z1S1- oder A1-Bezugsart wird abgerufen
        lngRef = Application.ReferenceStyle
        ' Die Bezugsart wird auf A1 gestellt - und am Ende wieder auf den ausgelesenen
        ' Wert zurückgestellt
        Application.ReferenceStyle = xlA1
        ' Die Formelkalkulation wird auf "Manuell" gestellt - und am Ende
        ' wieder auf den ausgelesenen Wert zurückgestellt
        .Calculation = xlCalculationManual
        ' Fehler werden nicht angezeigt/beachtet
        ' https://learn.microsoft.com/de-de/office/vba/api/excel.application.displayalerts
        ' Hinweise in der obigen Webseite bitte genau durchlesen
        .DisplayAlerts = False
    End With
    ' Der Objektvariablen objFSO das "FilesystemObject" zuweisen
    'Set objFSO = CreateObject("Scripting.FileSystemObject")
    ' Wenn Du einen Ordnerauswahldialog möchtest
    'Set objShell = CreateObject("Shell.Application")
    'Set varDir = objShell.BrowseForFolder(0, "Ordner", &H4000, 17)
    'If Not varDir Is Nothing Then
        'strDir = varDir.Self.Path
        ' Datei im gleichen Ordner wie Auswertungsdateien
        strDir = ThisWorkbook.Path
        'strDir = "C:\Temp\Los\"  ' Fester Pfad
        strDir = IIf(Right(strDir, 1) <> "\", strDir & "\", strDir)
        Set objApp = OffApp("Word")
        ' Word nicht sichtbar
        'Set objApp = OffApp("Word", False)
        If Not objApp Is Nothing Then
            ' Die erste PDF-Datei im angegebenen Verzeichnis raussuchen
            strDatei = Dir$(strDir & "*.pdf", vbDirectory)
                ' Schleife bis alle PDF-Dateien abgearbeitet sind (Kopfgesteuerte Schleife)
            Do While strDatei <> ""
                ' Prüfen ob schon eine Datei mit mehr als 5 Unterstrichen (_) vorhanden ist
                ' Die ist dann schon ausgelesen und umbenannt
                ' Hast du solche Dateien im Ursprung, dann musst du
                ' ein anderes Kriterium für die Prüfung suchen
                If Not Len(strDatei) - Len(Replace(strDatei, "_", "")) > 5 Then
                    ' Word- Pdf-Dokument öffnen - ab Word 2013!!!!!
                    Set objDocument = objApp.Documents.Open(strDir & strDatei)
                    ' Text an Leerzeichen trennen/aufsplitten
                    strTrenn = Split(objDocument.Range, " ")
                    ' Schleife über das Array von Anfang bis Ende
                    For lngTMP = LBound(strTrenn) To UBound(strTrenn)
                        ' Wenn das Wort Rechnung gefunden wird...
                        If strTrenn(lngTMP) Like "*Rechn*" Then
                            ' ... schreibe den nächsten Wert in Variable strTMP
                            strTMP = Trim(strTrenn(lngTMP + 1))
                        ' Oder wenn das Wort Kunde gefunden wird...
                        ElseIf strTrenn(lngTMP) Like "*Kund*" Then
                            ' ... schreibe den nächsten Wert in Variable strTMP1
                            strTMP1 = Trim(strTrenn(lngTMP + 1))
                        End If
                    Next lngTMP
                    ' Word- Pdf-Dokument ohne speichern schliessen
                    objDocument.Close False
                    ' Schreibe die Variable strTMP1 in Tabelle1 Zelle Ax
                    ' Schreibe die Variable strTMP in Tabelle1 Zelle Bx
                    ' Schreibe die Variable strDatei (alter Dateiname) in Tabelle1 Zelle Cx
                    ' Schreibe den neuen Dateinamen in Tabelle1 Zelle Dx
                    With Tabelle1
                        .Range("A" & .Rows.Count).End(xlUp).Offset(1, 0).Value = strTMP1
                        .Range("B" & .Rows.Count).End(xlUp).Offset(1, 0).Value = strTMP
                        .Range("C" & .Rows.Count).End(xlUp).Offset(1, 0).Value = strDatei
                        .Range("D" & .Rows.Count).End(xlUp).Offset(1, 0).Value = strTMP & _
                            "_" & strTMP1 & Format(Now, "_dd_mm_yyyy_hh_mm_ss") & ".pdf"
                        ' Datei umbenennen mit Datum und Zeit am Ende
                        ' Für Datum und Zeit siehe -      <br/>[i]Dateiupload bitte im Forum! So geht es:<a href="thread-326.html"> Klick mich!</a>[/i]<br/>
                        Name strDir & strDatei As strDir & _
                            .Range("D" & .Rows.Count).End(xlUp).Value
                    End With
                    ' Array und Variablen leeren
                    Erase strTrenn
                    strTMP1 = ""
                    strTMP = ""
                    ' Die nächste Datei nehmen und Objektvariable auf Nothing setzen
                    strDatei = Dir$()
                    Set objDocument = Nothing
                ' Wenn eine Datei mit mehr als 5 Unterstrichen vorhanden ist nimm die nächste
                Else
                    strDatei = Dir$()
                End If
            Loop
        Else
            MsgBox "Applikation nicht installiert!"
        End If
    'End If
Fin:
    If Not objApp Is Nothing Then
        If blnTMP = True Then
            objApp.Quit
            blnTMP = False
        End If
    End If
    ' Objektvariablen leeren
    ' Falls du das "FileSystemObject" genommen hast
    'Set objShell = Nothing
    'Set objFSO = Nothing
    'Set varDir = Nothing
    Set objDocument = Nothing
    Set objApp = Nothing
    ' Die Applikation aufwecken - siehe oben!!!!
    With Application
        .ScreenUpdating = True
        .AskToUpdateLinks = True
        .EnableEvents = True
        .Calculation = lngCalc
        Application.ReferenceStyle = lngRef
        .DisplayAlerts = True
        .CutCopyMode = True
    End With
    ' Wenn ein Fehler auftritt gib ihn aus mit Fehlernummer und Beschreibung
    If Err.Number <> 0 Then MsgBox "Fehler: " & Err.Number & " " & Err.Description
End Sub
'################################################################################################
' Module    : Modul1
' Procedure : OffApp
' Author    : Case (Ralf Stolzenburg)
' Date      : 13.08.2023
' Purpose  : Start Applikation...
' Purpose  : Veröffentlicht auf CEF "https://www.clever-excel-forum.de/index.php" am 13.08.2023
' Purpose  : In der Rubrik "Beispiele und Workshops" unter "mit VBA"
'################################################################################################
Private Function OffApp(ByVal strApp As String, Optional blnVisible As Boolean = True) As Object
    Dim objApp As Object
    On Error Resume Next
    Set objApp = GetObject(, strApp & ".Application")
    Select Case Err.Number
        Case 429
            Err.Clear
            Set objApp = CreateObject(strApp & ".Application")
            blnTMP = True
            If blnVisible = True Then
                On Error Resume Next
                objApp.Visible = True
                Err.Clear
            End If
    End Select
    On Error GoTo 0
    Set OffApp = objApp
    Set objApp = Nothing
End Function

Dann der Code aus Modul2 (mit Xpdf):
Code:
Option Explicit
'################################################################################################
' Module    : Modul2
' Procedure : Main_2
' Author    : Case (Ralf Stolzenburg)
' Date      : 13.08.2023
' Purpose  : Aus PDF-Dateien etwas nach Excel auslesen
' Purpose  : Werte werden in Excel eingelesen - inklusive Dateiname
' Note      : Mit dem Open Source Projekt Xpdf
' Purpose  : Veröffentlicht auf CEF "https://www.clever-excel-forum.de/index.php" am 13.08.2023
' Purpose  : In der Rubrik "Beispiele und Workshops" unter "mit VBA"
'################################################################################################
Public Sub Main_2()
    ' Dimensionieren der Variablen
    Dim strDatei As String
    Dim varArr As Variant
    Dim strTMP1 As String
    Dim strTMP As String
    ' Wenn benötigt nächste Zeile auskommentieren
    'Dim objFSO As Object
    'Dim varDir As Object
    Dim strDir As String
    Dim lngCalc As Long
    Dim lngTMP As Long
    Dim lngRef As Long
    ' Wenn ein Fehler auftritt gehe zu der angegebenen Sprungmarke
    On Error GoTo Fin
    ' Die Excelapplikation wird ruhig gestellt
    With Application
        ' Keine Bildschirmaktualisiereung
        .ScreenUpdating = False
        ' Falls es ein Ereignismakro gibt (z. B. Worksheet_Change) wir es NICHT aufgerufen
        .EnableEvents = False
        ' Die eingstellte Formelkalkulation wird abgerufen
        lngCalc = .Calculation
        ' Zellbezüge, Zeilen- und Spaltenköpfe, Z1S1- oder A1-Bezugsart wird abgerufen
        lngRef = Application.ReferenceStyle
        ' Die Bezugsart wird auf A1 gestellt - und am Ende wieder auf den ausgelesenen
        ' Wert zurückgestellt
        Application.ReferenceStyle = xlA1
        ' Die Formelkalkulation wird auf "Manuell" gestellt - und am Ende
        ' wieder auf den ausgelesenen Wert zurückgestellt
        .Calculation = xlCalculationManual
        ' Fehler werden nicht angezeigt/beachtet
        ' https://learn.microsoft.com/de-de/office/vba/api/excel.application.displayalerts
        ' Hinweise in der obigen Webseite bitte genau durchlesen
        .DisplayAlerts = False
    End With
    ' Der Objektvariablen objFSO das "FilesystemObject" zuweisen
    'Set objFSO = CreateObject("Scripting.FileSystemObject")
    ' Wenn Du einen Ordnerauswahldialog möchtest
    'Set objShell = CreateObject("Shell.Application")
    'Set varDir = objShell.BrowseForFolder(0, "Ordner", &H4000, 17)
    'If Not varDir Is Nothing Then
        'strDir = varDir.Self.Path
        ' Datei im gleichen Ordner wie Auswertungsdateien
        strDir = ThisWorkbook.Path
        'strDir = "C:\Temp\Los\"  ' Fester Pfad
        strDir = IIf(Right(strDir, 1) <> "\", strDir & "\", strDir)
        ' Die erste PDF-Datei im angegebenen Verzeichnis raussuchen
        strDatei = Dir$(strDir & "*.pdf", vbDirectory)
            ' Schleife bis alle PDF-Dateien abgearbeitet sind (Kopfgesteuerte Schleife)
        Do While strDatei <> ""
            ' Prüfen ob schon eine Datei mit mehr als 5 Unterstrichen (_) vorhanden ist
            ' Die ist dann schon ausgelesen und umbenannt
            ' Hast du solche Dateien im Ursprung, dann musst du
            ' ein anderes Kriterium für die Prüfung suchen
            If Not Len(strDatei) - Len(Replace(strDatei, "_", "")) > 5 Then
                ' Hier wird das Array varArr über Filter (nach Doppelpunkt)
                ' Split (die Ausgabe von Wscript.Shell über Exec und schliesslich
                ' StOut.ReadAll am Carriage Return - Linefeed Kombination) getrennt
                '###############################################################################
                ' WENN das Array leer bleibt, BEACHTE die Hinweise in der ReadMeFirst.txt
                ' Hinweis "pdftotext.exe" nicht im richtigen Verzeichnis, oder LEERZEICHEN im
                ' Pfad- oder Dateiname - die müssen dann maskiert werden.
                '###############################################################################
                varArr = Filter(Split(CreateObject("Wscript.Shell").Exec("cmd /c " & _
                    ThisWorkbook.Path & Application.PathSeparator & "pdftotext.exe -raw " & _
                    strDir & strDatei & " -").StdOut.ReadAll, vbCrLf), ":")
                ' Schleife über das Array von Anfang bis Ende
                For lngTMP = LBound(varArr) To UBound(varArr)
                    ' Wenn das Wort Rechnung gefunden wird...
                    If varArr(lngTMP) Like "*Rechn*" Then
                        ' ... schreibe den nächsten Wert nach Leerzeichen in Variable strTMP
                        strTMP = Mid(varArr(lngTMP), InStr(varArr(lngTMP), " ") + 1)
                        'Mid(Text, Instr(Text, "_") + 1)
                    ' Oder wenn das Wort Kunde gefunden wird...
                    ElseIf varArr(lngTMP) Like "*Kund*" Then
                        ' ... schreibe den nächsten Wert nach Leerzeichen in Variable strTMP1
                        strTMP1 = Mid(varArr(lngTMP), InStr(varArr(lngTMP), " ") + 1)
                    End If
                Next lngTMP
                ' Schreibe die Variable strTMP1 in Tabelle2 Zelle Gx
                ' Schreibe die Variable strTMP in Tabelle2 Zelle Hx
                ' Schreibe die Variable strDatei in Tabelle2 Zelle Ix
                With Tabelle2
                    .Range("G" & .Rows.Count).End(xlUp).Offset(1, 0).Value = strTMP1
                    .Range("H" & .Rows.Count).End(xlUp).Offset(1, 0).Value = strTMP
                    .Range("I" & .Rows.Count).End(xlUp).Offset(1, 0).Value = strDatei
                End With
                ' Array und Variablen leeren
                Erase varArr
                strTMP1 = ""
                strTMP = ""
                ' Die nächste Datei nehmen
                strDatei = Dir$()
            ' Wenn eine Datei mit mehr als 5 Unterstrichen vorhanden ist nimm die nächste
            Else
                strDatei = Dir$()
            End If
        Loop
    'End If
Fin:
    ' Objektvariablen leeren
    ' Falls du das "FileSystemObject" genommen hast
    'Set objShell = Nothing
    'Set objFSO = Nothing
    'Set varDir = Nothing
    ' Die Applikation aufwecken - siehe oben!!!!
    With Application
        .ScreenUpdating = True
        .AskToUpdateLinks = True
        .EnableEvents = True
        .Calculation = lngCalc
        Application.ReferenceStyle = lngRef
        .DisplayAlerts = True
        .CutCopyMode = True
    End With
    ' Wenn ein Fehler auftritt gib ihn aus mit Fehlernummer und Beschreibung
    If Err.Number <> 0 Then MsgBox "Fehler: " & Err.Number & " " & Err.Description
End Sub

Nachfolgend noch die ZIP-Datei.
[-] Folgende(r) 1 Nutzer sagt Danke an Gast für diesen Beitrag:
  • schauan
Antworten Top


Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste