Eine Frage zu VBA per Excel 2010 zur Seitenauslese von PDF-dateien
Moin Moin,
ich habe eine Frage bzw. ein Problem mit einem VBA-Script zum auslesen der Seitenanzahl von PDF-Dateien.
Die Dateien liegen alle in einem Verzeichnis. Ich habe folgendes Script welches mich aber bei der Ausführung nach einer Datei fragt, was aber umständlich ist, denn eig kann/soll es einfach durch das Verzeichnis der Dateien drüberlaufen und die Seitenanzahl ausgeben. Und wenn ich einen Dateiname eingebe, kommt der Fehler "53" - Datei nicht gefunden, aber die Datei ist definitif da und auch i.O.
Hier mal der AKTUELLE Quellcode:
Kann mir jemand einen Tipp geben, wo ich gerade falsch denke?
Thx vorab.
ich habe eine Frage bzw. ein Problem mit einem VBA-Script zum auslesen der Seitenanzahl von PDF-Dateien.
Die Dateien liegen alle in einem Verzeichnis. Ich habe folgendes Script welches mich aber bei der Ausführung nach einer Datei fragt, was aber umständlich ist, denn eig kann/soll es einfach durch das Verzeichnis der Dateien drüberlaufen und die Seitenanzahl ausgeben. Und wenn ich einen Dateiname eingebe, kommt der Fehler "53" - Datei nicht gefunden, aber die Datei ist definitif da und auch i.O.
Hier mal der AKTUELLE Quellcode:
Sub PDFCounter()
Dim buf As String, fil As String, i As Integer
Dim fso, pdf, pos As Integer, p2 As Integer
a = FreeFile
Filename = InputBox("Bitte Dateinamen (ohne Erweiterung) eingeben:", "Öffnen...")
If Filename = "" Then Exit Sub
FilePath = "D:\Rechnungen\" & Filename & ".pdf"
Set fso = CreateObject("Scripting.FileSystemObject")
Set pdf = fso.OpenTextFile(FilePath)
Do While Not pdf.AtEndOfStream
buf = pdf.ReadLine
pos = InStr(1, buf, "/Count")
If pos > 0 Then
buf = Mid(buf, pos + 7)
p2 = InStr(1, buf, Chr(13))
If p2 <> 0 Then
buf = Left(buf, p2 - 1)
End If
i = CLng(buf)
Exit Do
End If
Loop
Range("a3") = i
End Sub
Thx vorab.
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 155819
Url: https://administrator.de/forum/eine-frage-zu-vba-per-excel-2010-zur-seitenauslese-von-pdf-dateien-155819.html
Ausgedruckt am: 23.12.2024 um 12:12 Uhr
18 Kommentare
Neuester Kommentar
Hallo Phade!
z.B.
Versuchs mal so:
Gruß Dieter
InputBox(Anzeigetext, Titel, Default) |
InputBox("Bitte ...", "Öffnen...", "D:\Rechnungen\" |
Versuchs mal so:
FileName = InputBox("Bitte Dateinamen (ohne Erweiterung) eingeben:", "Öffnen...")
If FileName = "" Then Exit Sub
FilePath = "D:\Rechnungen\" & FileName & ".pdf"
Set fso = CreateObject("Scripting.FileSystemObject")
Set pdf = fso.OpenTextFile(FilePath)
Gruß Dieter
Hallo Phade!
Sollte sich dann etwa so machen lassen:
Noch eine Anmerkung zur Variablendeklaration mit "
... und: die ermittelte Seitenanzahl hätte sich vielleicht auch einen etwas "sprechenderen" Namen (als "i") verdient.
Zur Kontrolle würde es vermutlich (zumindest während der Testphase) auch nicht schaden, zusätzlich den Dateinamen in die Tabelle einzutragen - dann würde ich in Zeile 13 die Spalte durch Angabe der Nummer (1) anstelle des Buchstabens festlegen und als Zeile 40a
verwenden (die Deklaration von "Column" als "String" ist dann auch nicht mehr korrekt).
Eine Vereinfachung hinsichtlich der Prüfung des Dateinamens ergäbe sich noch, wenn entweder sichergestellt ist, dass sowohl Dateimaske als auch Dateityp hinsichtlich Groß-/Kleinschreibung exakt sind (also zB "pdf" immer in Kleinbuchstaben vorliegt) oder mit "
zu
zusammengefasst und die Zeile 21 auf
verkürzt werden.
Grüße
bastla
Sollte sich dann etwa so machen lassen:
Option Explicit
Sub PDFCounter()
Dim buf As String, fil As String, i As Integer
Dim FilePath As String, FileMask As String, FileExt As String
Dim Column As Integer, Row As Long
Dim fso, File, pdf, FileName As String, pos As Integer, p2 As Integer
FilePath = "D:\Rechnungen\"
FileMask = "*-E" 'genau hinsichtlich Groß-/Kleinschreibung
FileExt = "pdf" 'in Kleinbuchstaben
Column = 1 'Einträge in Spalte "A" ...
Row = 3 '... ab Zeile 3
Set fso = CreateObject("Scripting.FileSystemObject")
For Each File In fso.GetFolder(FilePath).Files 'alle Dateien des vorgegebenen Ordners durchgehen ...
FileName = File.Name
'.... und nur passende verarbeiten
If fso.GetBaseName(FileName) Like FileMask And LCase(fso.GetExtensionName(FileName)) = FileExt Then
Set pdf = fso.OpenTextFile(File.Path)
Do While Not pdf.AtEndOfStream
buf = pdf.ReadLine
pos = InStr(1, buf, "/Count")
If pos > 0 Then
buf = Mid(buf, pos + 7)
p2 = InStr(1, buf, Chr(13))
If p2 <> 0 Then buf = Left(buf, p2 - 1)
i = CLng(buf)
Exit Do
End If
Loop
Cells(Row, Column) = i 'Seitenzahl eintragen
Cells(Row, Column + 1) = FileName 'Dateinamen eintragen
Row = Row + 1 'Zeilennummer erhöhen
End If
Next
End Sub
Dim
": So richtig sinnvoll wird diese erst in Kombination mit "Option Explicit
", da dann keine nicht deklarierten (weil zB falsch geschriebenen) Variablen akzeptiert werden - daher entweder alle Variablen deklarieren oder (fast) keine ...... und: die ermittelte Seitenanzahl hätte sich vielleicht auch einen etwas "sprechenderen" Namen (als "i") verdient.
Zur Kontrolle würde es vermutlich (zumindest während der Testphase) auch nicht schaden, zusätzlich den Dateinamen in die Tabelle einzutragen - dann würde ich in Zeile 13 die Spalte durch Angabe der Nummer (1) anstelle des Buchstabens festlegen und als Zeile 40a
Cells(Row, Column + 1) = File.Name 'Dateinamen eintragen
Eine Vereinfachung hinsichtlich der Prüfung des Dateinamens ergäbe sich noch, wenn entweder sichergestellt ist, dass sowohl Dateimaske als auch Dateityp hinsichtlich Groß-/Kleinschreibung exakt sind (also zB "pdf" immer in Kleinbuchstaben vorliegt) oder mit "
Option Compare Text
" vorweg die Berücksichtigung von Groß-/Kleinschreibung ausgeschaltet wird - dann könntenFileMask = "*-E" 'genau hinsichtlich Groß-/Kleinschreibung
FileExt = "pdf" 'in Kleinbuchstaben
FileMask = "*-E.pdf" 'genau hinsichtlich Groß-/Kleinschreibung
If FileName Like FileMask Then
Grüße
bastla
Hallo Phade!
Wobei in bastlas Code, die Codezeilen 24 - 38 noch durch folgende Codezeilen ersetzt werden könnten:
Gruß Dieter
[edit] auf bastlas Anregung geändert und funktioniert mit anderen Test-Pdf's doch nicht. Siehe weiter unten [/edit]
Wobei in bastlas Code, die Codezeilen 24 - 38 noch durch folgende Codezeilen ersetzt werden könnten:
'Dim Text as Variant, i As Long
Do Until Pdf.AtEndOfStream
Text = Split(WorksheetFunction.Clean(Pdf.ReadLine), "/Count ")
If UBound(Text) = 1 Then i = CLng(Split(Text(1))(0)): Exit Do
Loop
Gruß Dieter
[edit] auf bastlas Anregung geändert und funktioniert mit anderen Test-Pdf's doch nicht. Siehe weiter unten [/edit]
@Dieter
An eine Vereinfachung hatte ich auch schon gedacht, war allerdings noch nicht dazu gekommen; außerdem dürfte das ohne genaue Kenntnis der von Phade verwendeten PDF auch nicht ganz so einfach sein, da ich bei einem ersten Test mit dem neuen Code bereits eine nicht auswertbare Datei (Fehler: "Type mismatch" - was bei einem Wert von "2 >> endobjxref0 126 0000000000 65535 f" für Text(1), resultierend aus der Tatsache, dass die Zeile mit "CR" abgeschlossen war, auch nicht weiter verwundert) vorfand.
Mit
sollte es aber etwas sicherer sein ...
Grüße
bastla
Wobei in bastlas Code, die Codezeilen 24 - 38 ...
Ehre, wem Ehre gebührt : die Zeilen hatte Phade schon selbst mitgebracht ...An eine Vereinfachung hatte ich auch schon gedacht, war allerdings noch nicht dazu gekommen; außerdem dürfte das ohne genaue Kenntnis der von Phade verwendeten PDF auch nicht ganz so einfach sein, da ich bei einem ersten Test mit dem neuen Code bereits eine nicht auswertbare Datei (Fehler: "Type mismatch" - was bei einem Wert von "2 >> endobjxref0 126 0000000000 65535 f" für Text(1), resultierend aus der Tatsache, dass die Zeile mit "CR" abgeschlossen war, auch nicht weiter verwundert) vorfand.
Mit
If UBound(Text) = 1 Then i = CLng(Split(Text(1))(0)): Exit Do
Grüße
bastla
Hallo bastla!
Bei meinen Test's ist dieser Fehler leider nicht aufgetreten. Von daher danke für die Unterstützung
Meine Test-Pdf's enthielten auch nur LF's und keine CR's, was wohl auch sehr unterschiedlich ist und die PDF's als Text-Dateien zu bearbeiten ist auch schon eine Sache für sich
Die betreffenden Codezeilen in Deinem Code gegebenenfalls zu ändern, bezogs sich auch nur insofern auf Deinen Code, weil dieser im Prinzip ja schon ein Endprodukt darstellt. Und das Du den Code nur 1:1 übernommen hast, ist mir durchaus bewusst
Gruß Dieter
Bei meinen Test's ist dieser Fehler leider nicht aufgetreten. Von daher danke für die Unterstützung
Meine Test-Pdf's enthielten auch nur LF's und keine CR's, was wohl auch sehr unterschiedlich ist und die PDF's als Text-Dateien zu bearbeiten ist auch schon eine Sache für sich
Die betreffenden Codezeilen in Deinem Code gegebenenfalls zu ändern, bezogs sich auch nur insofern auf Deinen Code, weil dieser im Prinzip ja schon ein Endprodukt darstellt. Und das Du den Code nur 1:1 übernommen hast, ist mir durchaus bewusst
Gruß Dieter
Hallo bastla!
Habe noch ne andere Variante gefunden, d.h. mein obiger Codeschnippsel funktioniert doch nicht
Also doch auf Ziffern prüfen
Gruß Dieter
Habe noch ne andere Variante gefunden, d.h. mein obiger Codeschnippsel funktioniert doch nicht
Text(1) = "1/Type/Pages/Kids[13 0 R]>>" |
Also doch auf Ziffern prüfen
Do Until Pdf.AtEndOfStream
Text = Split(WorksheetFunction.Clean(Pdf.ReadLine), "/Count ")
If UBound(Text) = 1 Then
i = 1
Do While IsNumeric(Mid(Text(1), i, 1)): i = i + 1: Loop
i = CLng(Left(Text(1), i - 1)): Exit Do
End If
Loop
Gruß Dieter
Hallo Dieter!
... oder gleich Nägel mit Köpfen machen :
[Edit] Dieters Vorschläge (siehe unten) integriert [/Edit]
Grüße
bastla
... oder gleich Nägel mit Köpfen machen :
Option Explicit
Option Compare Text
Sub PDFCounter()
Dim FilePath As String, FileMask As String, FileExt As String
Dim Column As Integer, Row As Long
Dim fso, rE, File, pdf, FileName As String
Dim Match, Pages As Long
FilePath = "D:\Rechnungen\"
FileMask = "*-E" 'genau hinsichtlich Groß-/Kleinschreibung
FileExt = "pdf" 'in Kleinbuchstaben
Column = 1 'Einträge in Spalte "A" ...
Row = 3 '... ab Zeile 3
Set fso = CreateObject("Scripting.FileSystemObject")
Set rE = CreateObject("VBScript.Regexp")
rE.Pattern = "/Count (\d*)" 'Sucbegriff = "/Count <Ziffer(n)>"
For Each File In fso.GetFolder(FilePath).Files 'alle Dateien des vorgegebenen Ordners durchgehen ...
FileName = File.Name
'.... und nur passende verarbeiten
If fso.GetBaseName(FileName) Like FileMask And LCase(fso.GetExtensionName(FileName)) = FileExt Then
Set pdf = fso.OpenTextFile(File.Path) 'Datei öffnen ...
Do Until pdf.AtEndOfStream '... und notfalls bis zum Dateiende durchgehen
For Each Match In rE.Execute(Pdf.ReadLine) 'Zeile einlesen, durchsuchen und, wenn gefunden ....
Pages = CLng(Match.SubMatches(0)) '... Seitenzahl (<Ziffer(n)>) auslesen
Cells(Row, Column) = Pages 'Seitenzahl eintragen
Cells(Row, Column + 1) = FileName 'Dateinamen eintragen
Row = Row + 1 'Zeilennummer für Tabelle erhöhen
Exit Do 'Datei muss nicht weiter ausgelesen werden
Next
Loop
pdf.Close 'der Ordnung halber: Datei schließen
End If
Next
End Sub
Grüße
bastla
Hallo bastla!
Toll! Das ist natürlich die wesentlich bessere Variante, die auch bei meinen unterschiedlichen Pdf's einwandfrei funktioniert Und als Zugabe auch noch kommentiert
Gruß Dieter
PS.
Die Codezeile 26 könnte man aber noch entfernen und die Codezeile 27 gleich so schreiben:
und nach dem Loop eventuell noch ein
einfügen
Toll! Das ist natürlich die wesentlich bessere Variante, die auch bei meinen unterschiedlichen Pdf's einwandfrei funktioniert Und als Zugabe auch noch kommentiert
Gruß Dieter
PS.
Die Codezeile 26 könnte man aber noch entfernen und die Codezeile 27 gleich so schreiben:
For Each Match In rE.Execute(Pdf.ReadLine) 'Zeile durchsuchen und wenn gefunden ...
Pdf.Close
Hallo bastla!
War ja nur ein Vorschlag
Aber eine kleine Sache wäre da noch und zwar:
Funktioniert die Gleichbehandlung der Klein/Großschreibung mit dem Like-Operator ("*-E.PDF" gleich "*-e.pdf") nur, wenn die Option "Option Compare Text" gesetzt wird.
Gruß Dieter
[OT]
Ich versuche mich gerade an der ClipBoard-Geschichte aus nem anderen Thread.
Dieser Code funktioniert z.B. in Excel aber in VBS ClipBoard.SetData nicht.
Und dieser Code funktioniert zwar in VBS, aber es kommt beim Zugriff mit ClipBoard.SetData immer erst eine Sicherheitsabfrage
Hast Du ne Idee, wie ich die Sicherheitsabfrage unterbinden kann?
[/OT]
War ja nur ein Vorschlag
Aber eine kleine Sache wäre da noch und zwar:
Funktioniert die Gleichbehandlung der Klein/Großschreibung mit dem Like-Operator ("*-E.PDF" gleich "*-e.pdf") nur, wenn die Option "Option Compare Text" gesetzt wird.
Gruß Dieter
[OT]
Ich versuche mich gerade an der ClipBoard-Geschichte aus nem anderen Thread.
Dieser Code funktioniert z.B. in Excel aber in VBS ClipBoard.SetData nicht.
Set Html = CreateObject("HtmlFile")
Set ClipBoard = Html.ParentWindow.ClipboardData
ClipBoard.SetData "Text", "Text für die Zwischenablage"
Set Html = CreateObject("InternetExplorer.Application")
Html.Navigate "about:blank"
Set ClipBoard = Html.Document.ParentWindow.ClipboardData
ClipBoard.SetData "Text", "Text für die Zwischenablage"
Hast Du ne Idee, wie ich die Sicherheitsabfrage unterbinden kann?
[/OT]
Hallo Dieter!
[OT]
Zum "Clipboard"-Thema: Die Sicherheitsabfrage lässt sich vermutlich eliminieren, indem die Sicherheitseinstellungen des IE weit genug nach unten geschraubt werden - aber sollten die das wirklich?
Der Workaround unter Verwendung der "clip.exe" (geeignet, solange nur in die Zwischenablage kopiert werden soll) ist da für mich das kleinere Übel ...
[/OT]
Grüße
bastla
Funktioniert die Gleichbehandlung der Klein/Großschreibung mit dem Like-Operator ("*-E.PDF" gleich "*-e.pdf") nur, wenn die Option "Option Compare Text" gesetzt wird.
Habe ich zumindest (in der Online-Hilfe) so gelesen und ist auch das Ergebnis meiner Tests ...[OT]
Zum "Clipboard"-Thema: Die Sicherheitsabfrage lässt sich vermutlich eliminieren, indem die Sicherheitseinstellungen des IE weit genug nach unten geschraubt werden - aber sollten die das wirklich?
Der Workaround unter Verwendung der "clip.exe" (geeignet, solange nur in die Zwischenablage kopiert werden soll) ist da für mich das kleinere Übel ...
[/OT]
Grüße
bastla
Hallo bastla!
Also bei mir ergibt z.B. dieser Vergleich ohne "Option Compare Text" False
und mit "Option Compare Text" True
Was auch in der VBA-Hilfe zum Like-Operator bestätigt wird.
Zitat:
Das Verhalten des Operators Like hängt von der Option Compare-Anweisung ab (Standard ist Compare Binary)
Option Compare Text führt zu Zeichenfolgenvergleichen, die die im Gebietsschema des Systems gewählte Sortierreihenfolge für Zeichen verwenden (wobei keine Unterschiede in der Groß- und Kleinschreibung berücksichtigt werden).
Gruß Dieter
[OT]
Klar ist die Variante per Clip wesentlich einfacher, aber aus reinem Ergeiz hätte ich auch gerne die andere Variante zum Laufen gebracht.
Was mich bei der Clip-Variante etwas verwundert, ist die Tatsache, dass diese funktioniert, obwohl auf meinem System keine Clip.Exe zu finden ist.
[/OT]
Also bei mir ergibt z.B. dieser Vergleich ohne "Option Compare Text" False
If "*-e.pdf" Like "*-E.pdf" Then x = 1
If "*-e.pdf" Like "*-E.pdf" Then x = 1
Zitat:
Das Verhalten des Operators Like hängt von der Option Compare-Anweisung ab (Standard ist Compare Binary)
Option Compare Text führt zu Zeichenfolgenvergleichen, die die im Gebietsschema des Systems gewählte Sortierreihenfolge für Zeichen verwenden (wobei keine Unterschiede in der Groß- und Kleinschreibung berücksichtigt werden).
Gruß Dieter
[OT]
Klar ist die Variante per Clip wesentlich einfacher, aber aus reinem Ergeiz hätte ich auch gerne die andere Variante zum Laufen gebracht.
Was mich bei der Clip-Variante etwas verwundert, ist die Tatsache, dass diese funktioniert, obwohl auf meinem System keine Clip.Exe zu finden ist.
[/OT]
Hallo Dieter!
Da hatte ich nicht genau genug gelesen bzw missverstanden, was Du gemeint hattest - natürlich wird nur dann nicht zwischen Groß- und Kleinschreibung unterschieden, wenn (um mich selbst zu zitieren - siehe Kommentar 26.11.2010, 22:23:48 Uhr)
Grüße
bastla
Da hatte ich nicht genau genug gelesen bzw missverstanden, was Du gemeint hattest - natürlich wird nur dann nicht zwischen Groß- und Kleinschreibung unterschieden, wenn (um mich selbst zu zitieren - siehe Kommentar 26.11.2010, 22:23:48 Uhr)
... mit "
- insofern sollte ich das tatsächlich noch in der vorläufig endgültigen Version ergänzen (und mache es auch gleich) ...Option Compare Text
" vorweg die Berücksichtigung von Groß-/Kleinschreibung ausgeschaltet wird ...Grüße
bastla
Hallo bastla!
Gruß Dieter
Zitat von @bastla:
Da hatte ich nicht genau genug gelesen bzw missverstanden, was Du gemeint hattest ....
- insofern sollte ich das tatsächlich noch in der vorläufig endgültigen Version ergänzen (und mache es auch gleich) ...
Da bin ich aber Froh, dass wir dieses Missverständnis nun doch noch klären konntenDa hatte ich nicht genau genug gelesen bzw missverstanden, was Du gemeint hattest ....
- insofern sollte ich das tatsächlich noch in der vorläufig endgültigen Version ergänzen (und mache es auch gleich) ...
Gruß Dieter