Anzeige
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

Seitenanzahl sämtlicher pdf-Dateien(VBA)

Forumthread: Seitenanzahl sämtlicher pdf-Dateien(VBA)

Seitenanzahl sämtlicher pdf-Dateien(VBA)
25.11.2020 14:33:40
Fabian
Hallo Zusammen,
ich versuche mich gerade an einem Code, der dazu führen soll, dass sämtliche pdf Dateien innerhalb eines Ordners erfasst werden und ich zu den pdf Dateien die jeweilige Seitenanzahl erhalte. Hierzu verwende ich eine Function, die für sich allein genommen bereits funktioniert. Hierbei muss allerdings der Pfad jeder einzelnen pdf-Datei manuell eingetragen werden. Die jeweiligen Pfade habe ich mittels makro (ist nicht Bestandteil des folgenden Codes, da irrelevant) erzeugt und in ein Tabellenblatt eintragen lassen.
Wenn ich nun die Function aufrufe und dabei als Argument die Pfade aus dem Tabellenblatt verwende, funktioniert dies leider nicht wie gewünscht. Kann mir Jemand bei dem Problem weiterhelfen?
Der Code dazu sieht wie folgt aus:
Option Explicit
Sub AufrufPDFCounter()
Dim PfaPDF(1000) As String
Dim i As Integer
Range("A2").Select
For i = 2 To 4
Cells(i, 1).Select
PfaPDF(i) = Chr(34) & "C:\Users\Hans\Desktop\Test897" & Selection.Value & Chr(34)
PDFCounter (PfaPDF(i))
Debug.Print PfaPDF(i) ' um die Ausgabe zu testen
Next
Range("A1").Select
End Sub

Function PDFCounter(strfile As String) As Long
Dim buf As String
Dim fso As Object 'Scripting.FileSystemObject
Dim pdf As Object 'Scripting.TextStream
Dim posA As Long
Dim posE As Long
Dim bufLen As Long
Dim temp As String, temp2 As String
Dim posP As Long
Dim pages As Long
Set fso = CreateObject("Scripting.FileSystemObject")
Set pdf = fso.OpenTextFile(strfile)
Do While pages = 0 And (Not pdf.AtEndOfStream)
temp = pdf.ReadLine
If Left(temp, 3) = "obj" Or InStr(1, temp, " obj") > 0 Then
' Achtung es können mehrere "obj" vorkommen!
buf = temp
ElseIf Len(buf) > 0 Then
buf = buf & temp
End If
If Len(buf) > 0 Then
If InStr(1, temp, "endobj") > 0 Then
'Zeilenumbrüche entfernen
buf = Replace(buf, vbCr, vbNullString)
buf = Replace(buf, vbLf, vbNullString)
'Zeichenlänge für do-loop-Prüfung
bufLen = Len(buf)
posE = 1
Do
'Start finden:
posA = InStr(posE, buf, "obj If posA > 0 Then
posA = posA + 5
'Ende finden:
posE = InStr(posA, buf, "endobj")
If posE > 0 Then
temp2 = Mid(buf, posA, posE - posA)
'Bedingung: /Pages und /Count muss innerhalb obj>endobj vorhanden sein
If InStr(1, temp2, "/Pages") > 0 Then
posP = InStr(1, temp2, "/Count")
If posP > 0 Then 'Eintrag gefunden
pages = Val(Mid(temp2, posP + 6))
Exit Do
End If
End If
posE = posE + 6
Else
Exit Do
End If
Else 'Abbruch
Exit Do
End If
Loop While posE buf = vbNullString
End If
End If
Loop
PDFCounter = pages
Debug.Print PDFCounter
End Function

Anzeige

4
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Web-Link
25.11.2020 15:45:10
Fennek
Hallo,
die suchmaschien fand
https://www.extendoffice.com/documents/excel/5330-excel-vba-pdf-page-count.html
Der Kern des Codes ist:

Set RegExp = CreateObject("VBscript.RegExp")
RegExp.Global = True
RegExp.Pattern = "/Type\s*/Page[^s]"
xFileNum = FreeFile
Open (xFdItem & xFileName) For Binary As #xFileNum
xStr = Space(LOF(xFileNum))
Get #xFileNum, , xStr
Close #xFileNum
Cells(I, 2) = RegExp.Execute(xStr).Count
mfg
(PDFs sind in der Struktur so variabel, dass es Abfragen erschwert)
Anzeige
AW: Seitenanzahl sämtlicher pdf-Dateien(VBA)
25.11.2020 15:00:47
Nepumuk
Hallo Fabian,
teste mal (die Seitenzahl wird in Spalte B ausgegeben):
Option Explicit

Public Sub AufrufPDFCounter()
    Dim i As Long
    For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row
        Cells(i, 2).Value = PDFCounter("C:\Users\Hans\Desktop\Test897\" & Cells(i, 1).Value)
    Next
End Sub

Private Function GetPageCount(ByVal pvstrFileName As String) As Long
    
    Dim strText As String
    Dim strLinearized As String, astrCount() As String
    Dim ialngIndex As Long
    Dim objFileSystemObject As Object, objTextFile As Object
    Dim objRegEx As Object, objMatch As Object, objItem As Object
    Dim blnFound As Boolean
    
    GetPageCount = -1
    
    Set objFileSystemObject = CreateObject("Scripting.FileSystemObject")
    Set objTextFile = objFileSystemObject.OpenTextFile(pvstrFileName, 1, False, 0)
    
    Do Until objTextFile.AtEndOfStream
        
        strText = objTextFile.ReadLine
        strText = Replace(strText, vbLf, vbNullString)
        
        If Cbool(InStr(1, strText, "/Linearized")) Then
            
            If Len(strText) > 20 Then
                
                strLinearized = strText
                blnFound = True
                Exit Do
                
            End If
        End If
        
        If Cbool(InStr(1, strText, "/Count ")) Then
            
            Redim Preserve astrCount(ialngIndex)
            astrCount(ialngIndex) = strText
            ialngIndex = ialngIndex + 1
            blnFound = True
            
        End If
    Loop
    
    Call objTextFile.Close
    
    Set objTextFile = Nothing
    Set objFileSystemObject = Nothing
    
    If blnFound Then
        
        Set objRegEx = CreateObject("VBScript.RegExp")
        
        With objRegEx
            
            .MultiLine = True
            .Global = True
            .IgnoreCase = False
            
            If strLinearized <> vbNullString Then
                
                .Pattern = "\/N.?(\d+).?"
                
                Set objMatch = .Execute(strLinearized)
                
                If objMatch.Count > 0 Then _
                    GetPageCount = Clng(objMatch(0).SubMatches(0))
                
            Else
                
                If ialngIndex = 1 Then
                    
                    .Pattern = "\/Count.?(\d+)"
                    
                    Set objMatch = .Execute(astrCount(0))
                    
                    If objMatch.Count = 1 Then
                        
                        GetPageCount = Clng(objMatch(0).SubMatches(0))
                        
                    Else
                        
                        For Each objItem In objMatch
                            
                            GetPageCount = WorksheetFunction.Max( _
                                GetPageCount, Clng(objItem.SubMatches(0)))
                            
                        Next
                    End If
                Else
                    
                    .Pattern = "\/Count.?(-?\d+)"
                    
                    For ialngIndex = 0 To UBound(astrCount)
                        
                        Set objMatch = .Execute(astrCount(ialngIndex))
                        
                        GetPageCount = WorksheetFunction.Max( _
                            GetPageCount, Clng(objMatch(0).SubMatches(0)))
                        
                    Next
                End If
            End If
            
        End With
        
        Set objMatch = Nothing
        Set objRegEx = Nothing
        
    End If
End Function

Gruß
Nepumuk
Anzeige
AW: Seitenanzahl sämtlicher pdf-Dateien(VBA)
25.11.2020 15:58:09
Fabian
Hi Nepumuk,
vielen Dank für deine Hilfe, wirklich ganz großes Kino ;)
Habe den Code kurz angepasst und es klappt soweit ich das sehe.
Selbstverständlich auch vielen Dank den Anderen, die sich dem Problem angenommen haben!
;
Anzeige

Infobox / Tutorial

Seitenanzahl sämtlicher PDF-Dateien in Excel mit VBA ermitteln


Schritt-für-Schritt-Anleitung

Um die Seitenanzahl sämtlicher PDF-Dateien in einem Ordner mithilfe von VBA zu ermitteln, folge diesen Schritten:

  1. Öffne Excel und drücke ALT + F11, um den VBA-Editor zu öffnen.

  2. Füge ein neues Modul hinzu: Rechtsklick auf "VBAProject (DeineArbeitsmappe)" > Einfügen > Modul.

  3. Kopiere und füge den folgenden Code ein:

    Option Explicit
    
    Public Sub AufrufPDFCounter()
       Dim i As Long
       For i = 2 To Cells(Rows.Count, 1).End(xlUp).Row
           Cells(i, 2).Value = PDFCounter("C:\Users\Hans\Desktop\Test897\" & Cells(i, 1).Value)
       Next
    End Sub
    
    Function PDFCounter(strfile As String) As Long
       Dim buf As String
       Dim fso As Object
       Dim pdf As Object
       Dim pages As Long
       Set fso = CreateObject("Scripting.FileSystemObject")
       Set pdf = fso.OpenTextFile(strfile)
    
       Do While Not pdf.AtEndOfStream
           buf = pdf.ReadLine
           If InStr(1, buf, "/Count") > 0 Then
               pages = Val(Mid(buf, InStr(buf, "/Count") + 7))
               Exit Do
           End If
       Loop
       PDFCounter = pages
       pdf.Close
    End Function
  4. Schließe den VBA-Editor und kehre zu Excel zurück.

  5. Trage die PDF-Dateinamen in Spalte A deines Arbeitsblattes ein, beginnend ab Zelle A2.

  6. Führe das Makro AufrufPDFCounter aus, um die Seitenanzahl in Spalte B auszugeben.


Häufige Fehler und Lösungen

  • Fehler: "Datei nicht gefunden"

    • Stelle sicher, dass der Pfad zur PDF-Datei korrekt ist. Überprüfe, ob die Datei im angegebenen Verzeichnis existiert.
  • Fehler: "Typ nicht definiert"

    • Überprüfe, ob alle verwendeten Objekte korrekt deklariert sind. Möglicherweise benötigst du eine Referenz zu "Microsoft Scripting Runtime".
  • Seitenanzahl wird nicht ausgegeben

    • Achte darauf, dass die PDFs tatsächlich die /Count-Information enthalten. Manche PDFs sind nicht standardkonform.

Alternative Methoden

Eine alternative Methode zur Ermittlung der Seitenanzahl ist die Verwendung von regulären Ausdrücken. Hier ist ein vereinfachter Ansatz:

Sub CountPDFPagesWithRegex()
    Dim RegExp As Object
    Dim xFileNum As Integer
    Dim xStr As String
    Dim pages As Long

    Set RegExp = CreateObject("VBScript.RegExp")
    RegExp.Global = True
    RegExp.Pattern = "/Count\s*(\d+)"

    xFileNum = FreeFile
    Open "C:\Users\Hans\Desktop\Test897\beispiel.pdf" For Binary As #xFileNum
    xStr = Space(LOF(xFileNum))
    Get #xFileNum, , xStr
    Close #xFileNum

    If RegExp.Test(xStr) Then
        pages = RegExp.Execute(xStr)(0).SubMatches(0)
    End If
    Debug.Print pages
End Sub

Praktische Beispiele

Beispiel 1: Angenommen, du hast die Dateien Dokument1.pdf, Dokument2.pdf in deinem Ordner. Nach Ausführung des Makros in Excel erhältst du in Spalte B die Anzahl der Seiten für jede Datei.

Beispiel 2: Verwende den Regex-Code, um die Seitenanzahl einer spezifischen PDF-Datei zu zählen, indem du den Dateinamen in der Open-Anweisung anpasst.


Tipps für Profis

  • Verwende Fehlerbehandlung: Implementiere On Error Resume Next, um sicherzustellen, dass dein Makro nicht bei einem Fehler stoppt.

  • Optimiere die Performance: Schalte die Bildschirmaktualisierung und Berechnung aus, während das Makro läuft, um die Ausführungsgeschwindigkeit zu erhöhen:

    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    ' ... dein Code ...
    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
  • Erweiterte Regex-Nutzung: Nutze komplexere Muster, um zusätzliche Informationen aus PDFs zu extrahieren.


FAQ: Häufige Fragen

1. Frage
Wie kann ich die Seitenanzahl für mehrere PDF-Dateien gleichzeitig ermitteln?
Antwort: Verwende das oben beschriebene Makro AufrufPDFCounter, um die Seitenanzahl für alle in Spalte A aufgelisteten PDFs in Spalte B zu ermitteln.

2. Frage
Gibt es Einschränkungen bei bestimmten PDF-Dateien?
Antwort: Ja, einige PDFs können verschlüsselt oder nicht standardkonform sein, was die Erkennung der Seitenanzahl erschwert.

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Entdecke mehr
Finde genau, was du suchst

Die erweiterte Suchfunktion hilft dir, gezielt die besten Antworten zu finden

Suche nach den besten Antworten
Unsere beliebtesten Threads

Entdecke unsere meistgeklickten Beiträge in der Google Suche

Top 100 Threads jetzt ansehen
Anzeige