Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.02.2012, 23:50   #1
tae1980
Форумчанин
 
Регистрация: 02.02.2009
Сообщений: 842
По умолчанию Подсчет количества страниц в PDF

Сегодня продолжил добивать тему PDF. В результате удалось написать одну функцию которую считаю весь полезной для себя. Возможно она будет интересна и кому-то еще. Эта функция возвращает количество страниц в PDF файле. Не идеал кода, но сегодня все проверки она прошла успешно.

Код:
Function PDFCount(PDFИмя As String)
'Функция определяет сколько страниц в PDF файле.
'Для этого она построчно читает файл и ищет в нем строку "/Count N". Где N - кол-во страниц.
'Если такой строки нет в файле, принимаем его размер в 1 страницу.
    PDFCount = 1
    Ищем = "/Count"
    Разделитель = Chr(10)
    Open PDFИмя For Binary Access Read Lock Read As #1
    'Читаем файл.
    Do While Not EOF(1)
        Line Input #1, fstr
        If InStr(fstr, Ищем) > 0 Then
            PDFCount = word(Right(fstr, Len(fstr) - InStr(fstr, Ищем) - Len(Ищем)), 1, Разделитель)
            Exit Do
        End If
    Loop
    Close #1
End Function

Function word(str, Number, Optional Разделитель = "") As String
'Функция возвращает n-ное слово в указанной строке. Аналог команды Rexx.
'На входе:
'str           - Строковая переменная.
'Number        - Номер слова.
'Разделитель   - Символ разделитель. При отсутствие за разделитель принимаются пробел и таб.
'На выходе:
'word          - n-ное слово или пустую строку если слова с таким номером нет.

    If Number > words(str, Разделитель) Then
            word = ""
    Else
        If Разделитель = "" Then
            word = Split(Application.Trim(Replace(str, vbTab, " ")), " ")(Number - 1)
        Else
            word = Application.Trim(Replace(Split(Application.Trim(Replace(Replace(str, " ", Chr(160)), Разделитель, " ")), " ")(Number - 1), Chr(160), " "))
        End If
    End If
End Function
С уважением, Алексей.
tae1980 вне форума Ответить с цитированием
Старый 27.07.2016, 13:23   #2
vsevtu
Новичок
Джуниор
 
Регистрация: 27.07.2016
Сообщений: 4
По умолчанию

Здравствуйте!

Подскажите чайнику, как получить результат работы этой функции?

Что необходимо проделать, чтобы получился результат?

Делал макрос в Excel, но сдается мне что код изложенный выше не относится к макросам... Подскажите пожалуйста!
vsevtu вне форума Ответить с цитированием
Старый 27.07.2016, 13:52   #3
IgorGO
Новичок
СтарожилДжуниор
 
Аватар для IgorGO
 
Регистрация: 05.02.2008
Сообщений: 9,487
По умолчанию

1. в одну ячейку пишите полное имя ПДФ-файла (диск:\все_папки\сколько_потребуетс я\имя_файла)
2. в другую =PDFCount(и ссылку на ячейку п.1
3. понятно, что к этому моменту текст макроса должен уже быть в программном модуле файла, в котором Вы это все проделаете.
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете
IgorGO вне форума Ответить с цитированием
Старый 27.07.2016, 16:35   #4
vsevtu
Новичок
Джуниор
 
Регистрация: 27.07.2016
Сообщений: 4
По умолчанию

Цитата:
Сообщение от IgorGO Посмотреть сообщение
1. в одну ячейку пишите полное имя ПДФ-файла (диск:\все_папки\сколько_потребуетс я\имя_файла)
2. в другую =PDFCount(и ссылку на ячейку п.1
3. понятно, что к этому моменту текст макроса должен уже быть в программном модуле файла, в котором Вы это все проделаете.
Спасибо за ответ!

В редакторе VBA ввел изложенный код, функция появилась.
В ячейку А1 ввел путь до файла, выглядит он так:
U:\ИЮЛЬ_2016_г\Печатается\4200 Nikita\коробка_1\Гарболово д, 1 34, 1 334657 000338508 61272 .pdf
В ячейке В1 пишу =pdfcount(A1), ругается..., результат вычислений выглядит как "#знач!"

Ссылка на файл выглядит как гиперссылка, но при открытии выдает ошибку "Не удается открыть указанный файл"

Где я мог сделать что-то не так?

Последний раз редактировалось vsevtu; 27.07.2016 в 16:43.
vsevtu вне форума Ответить с цитированием
Старый 27.07.2016, 16:47   #5
IgorGO
Новичок
СтарожилДжуниор
 
Аватар для IgorGO
 
Регистрация: 05.02.2008
Сообщений: 9,487
По умолчанию

у меня тоже не работает не знает что такое
words(str, Разделитель) Then
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете
IgorGO вне форума Ответить с цитированием
Старый 27.07.2016, 16:59   #6
vsevtu
Новичок
Джуниор
 
Регистрация: 27.07.2016
Сообщений: 4
По умолчанию

то есть код не функционален?
vsevtu вне форума Ответить с цитированием
Старый 27.07.2016, 19:37   #7
Aleksandr H.
2 the Nation Glory
Старожил
 
Аватар для Aleksandr H.
 
Регистрация: 27.05.2014
Сообщений: 3,289
По умолчанию

Цитата:
Сообщение от IgorGO Посмотреть сообщение
у меня тоже не работает не знает что такое
words(str, Разделитель) Then
Вот что значит работать без Option Explicit
Кто умер, но не забыт, тот бессмертен.
Лао-Цзы.
Aleksandr H. вне форума Ответить с цитированием
Старый 27.07.2016, 21:20   #8
doober
Старожил
 
Аватар для doober
 
Регистрация: 02.05.2009
Сообщений: 3,907
По умолчанию

Вот вам рабочий код.
Код:
Function PDFCount(PDFИмя As String)
'Функция определяет сколько страниц в PDF файле.
'Для этого она построчно читает файл и ищет в нем строку "/Count N". Где N - кол-во страниц.
'Если такой строки нет в файле, принимаем его размер в 1 страницу.
    PDFCount = 1
    Ищем = "/Count"
    Разделитель = Chr(10)
    Open PDFИмя For Binary Access Read Lock Read As #1
    'Читаем файл.
    Do While Not EOF(1)
        Line Input #1, fstr
        If InStr(fstr, Ищем) > 0 Then
            PDFCount = word(fstr)
            Exit Do
        End If
    Loop
    Close #1
End Function

Public Function word(S) As String
    Set RegExp = CreateObject("VBScript.RegExp")
    RegExp.Pattern = "/Count\s?(\d+)"
    If RegExp.test(S) Then
    Set oMatches = RegExp.Execute(S)
    word = oMatches(0).subMatches(0)
    End If
End Function
Анализ,обработка данных Недорого
doober вне форума Ответить с цитированием
Старый 28.07.2016, 10:01   #9
vsevtu
Новичок
Джуниор
 
Регистрация: 27.07.2016
Сообщений: 4
По умолчанию

Огромное спасибо!!!

Работает шикарно!

Написал макрос записи имени файла и полного пути до него в столбец А1, в B1 использую функцию предложенную Вами, с аргументом "А1":"А*", остается только сопоставить полученные данные с имеющимися в реестре за прошлые периоды и никаких нудных открываний тысячи с лишним файлов чтобы узнать кол-во страниц в них =)

Еще раз, спасибо!

Последний раз редактировалось vsevtu; 28.07.2016 в 10:13.
vsevtu вне форума Ответить с цитированием
Старый 29.08.2016, 17:54   #10
LeJandr
Новичок
Джуниор
 
Регистрация: 29.08.2016
Сообщений: 2
По умолчанию

Привет всем, зарегистрировался специально, чтобы отписаться.

За две недели я достаточно развился в исследовании структуры PDF-файла для написания PDF-сплиттера на VBA, чтобы сказать, что первый попавшийся "/Count N" не гарантирует, что N - это общее количество страниц в документе.

Слово "Count" относится к свойствам объекта "набор страниц" (/Type/Pages). А их в PDF может быть от одного до нескольких из-за древовидной структуры страниц внутри исходного кода файла PDF. Так что правильнее будет исходить от корневого объекта - /Type/Catalog, узнать ID подчиненного к нему набора страниц /Type/Pages, найти этот набор по ID, считать значение его параметра Count. Но здесь я сделаю проще - отпарсю регулярками значения всех Count-ов и узнаю наибольшее значение.

Ниже выкладываю подредактированную версию кода (пока не проверялся).

Код:
Function PDFCount(PDFpath As String)
'Функция определяет сколько страниц в PDF файле.
'Для этого она построчно читает файл и ищет в нем строку "/Count N"
'с наибольшим N, где N - кол-во страниц.
'Если такой строки нет в файле, принимаем его размер в 1 страницу.
    PageSetCount = 1
    TotalCount = 1
    strSearch= "/Count"
    Delim= Chr(10)
    Open PDFpath For Binary Access Read Lock Read As #1
    'Читаем файл.
    Do While Not EOF(1)
        Line Input #1, strLine
        PageSetCount = word(strLine)
        If TotalCount < PageSetCount Then
            TotalCount = PageSetCount
        End If
    Loop
    Close #1
    PDFCount = TotalCount
End Function

Public Function word(S) As Integer
    Set RegExp = CreateObject("VBScript.RegExp")
    RegExp.Pattern = "/Count (\d+)"
    Set oMatches = RegExp.Execute(S)
    If oMatches.Count > 0 Then
        word = val(oMatches(0).subMatches(0))
    End If
End Function
Вдруг у кого выводимое число не совпадает с реальным. PDF-ки разные бывают. Пример одного "монстра" (архив 25 МБ с PDF-файлом на 500 стр): https://vk.com/doc273848965_420670974
LeJandr вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
[QT] подсчет количества символов Unknown Lady Помощь студентам 0 24.11.2011 15:06
Определение количества страниц на печать tsar_ Общие вопросы Delphi 0 06.04.2011 10:00
Подсчет количества слов Driver_09 Помощь студентам 2 24.10.2010 17:14
вставка страниц из другого файла PDF Kavaler2i Общие вопросы Delphi 0 20.01.2010 18:58
Подсчет количества и частоты Ensoph Помощь студентам 6 08.05.2008 10:16