Какой генератор отчетов выбрал я

Вместо пролога

Частенько в различных форумах встречаю вопрос: “А где взять новую версию ReportBuilder-а” или “А где найти кряк для ReportBuilder-а” на который имеется один единственный ответ: “Выкинь это дерьмо и используй FastReport!!!”.
К сожалению жизнь показала, что не всегда дерьмо является дерьмом, а просто неплохую вещь не могут правильно использовать. Ниже я написал с какими проблемами сталкивался я лично, и как я их решал. Почитайте, может быть вам не понадобиться наступать на те грабли, на которые наступил я.

Постановка задачи
В конце 2001 года начальство озадачило меня разработкой программы для массовой печати газовых квитанций. Реальная печать производится на принтерах HP 8150 со скоростью печати около 32 страниц А4 формата в минуту. Для передачи БД использовался формат базы данных DBase-IV и компонент Карпова VKDBF для прямого доступа. Кстати компонент очень крут, и я всем его советую попробовать, пока он бесплатный. Машины, с которых производится (до сих пор кстати) генерация и печать отчета имеют следующую конфигурацию:
1. AMD-233, 128Mb ОЗУ, 10Гб HDD
2. Celeron-333, 128Mb ОЗУ, 10Гб HDD
Операционная система Windows NT WS с установленным сервиспаком 5.

Вначале было …
Использовать встроенный генератор отчетов QuickReport, который появился в Delphi 2, я пробовал. В принципе он – бы как раз решил процентов 70 моих проблем. Однако самый сильный его недостаток – отсутствие дизайнера (визуального построителя) для рантайма. Это сразу калечит психику разработчика на этапе опытной эксплуатации. Представьте себе: глюк со шрифтом и чтобы это поправить – поехали домой. Или у заказчика на машине ставить Delphi, да еще и исходники разворачивать. Сколько раз заказчик в такой ситуации уводит исходные тексты – рассказывать не буду. Готовые построители сторонних разработчиков были мною посмотрены и забракованы, поскольку в них не было и половины от того, что есть в QuickReporte. Кроме того он широко известен своими проблемами с нестандартными форматами бумаги.
Потуги в сторону Crystal Reports были сразу же “убиты” его размерами. Хотя, наверное, это и был наиболее оптимальный вариант. Однако мой проект всего 2.6 мегабайта – вполне автономный исполняемый файл. Можете сами сравнить с Crystal даже в минимальной установке.
В общем, для ускорения разработки, был использован FastReport версии 2.4 (извините, но времени писать свой генератор отчетов у меня не было). Разработка была сделана очень быстро и процесс, как говориться, пошел. Но объемы начали расти (сейчас около 23500 страниц ежемесячно). Были замечены следующие недостатки данного продукта:
1. скорость формирования отчета оставляет желать лучшего, поскольку сначала производится формирование “предварительного просмотра”, а уже только потом постановка задания в очередь.
2. отчет формируется целиком в памяти машины, которая тратится в неимоверных количествах, а вот на что – я поясню чуть ниже. В связи с этим у меня возникли проблемы, которые связаны с производителями железа и “кривизной рук” разработчиков операционной системы, которая уже всем набила мозоль на языке, и которые, чтобы уши и глаза не мозолить, я тут приводить не буду.
3. каждая страница отчета занимает в очереди принтера порядка 800 килобайт. При скорости порта около 2 мегабит получается что в минуту на принтер будет толкаться что-то порядка 18-20 страниц.
“Что-то тут не так” – подумал я и начались…

“Танцы с бубнами”
Первую задачу, которую я начал решать – повышение скорости печати. Первую проблему решить не удалось. Написал разработчику, и они почти клятвенно заверили меня, что они уже сами думали в этом направлении, и “через пару месяцев выйдет новая версия, которая это все может быть реализует”… “Понятно”, подумал я, и решил зайти с другого конца. Мысль, которая мне пришла в голову: “почему Access может печатать 32 страницы в минуту, FoxPro тоже может, а FastReport – нет?” Ответ крылся в 3 проблеме. Дело было в том, что при формировании отчета эти 2, мягко сказано, СУБД используют язык PCL, а вот как??? Пример простой печати через TPrinter был взят из советов Озерова. Простая тестовая программка, которая выводила на печать 1 строку текста, просто рисуя на канве принтера, сформировала файл в очереди принтера порядка 45 килобайт. При увеличении количества строк до 20 размер файла в очереди практически не изменился. “Так” – подумал я, “а как же сделано в FastReporte???”. Поглядел в исходных текстах (слава богу, что их дают), и через пару дней разобрался.

Так делать нельзя!
Разработчики FastReport-а пошли по пути самого меньшего сопротивления. Они формируют свою канву в виде окна, рисуют на ней страницу, которая получается в виде битовой карты, затем растягивают ее по размеру канвы принтера и печатают. Дешево и сердито. К чему там всякие пересчеты дюймов в миллиметры и обратно… В результате вот вам и 800 кил в очереди вместо 50. Вот вам и память для хранения каждой страницы в памяти. Представьте себе: у меня отчет на 2000 страниц, умножаем на 800 = 1600 Мегабайт памяти + еще столько же в системном каталоге Windows, пока это все не “ляжет” в очередь печати и будет “лежать”, пока не выйдет на принтер. Естественно такого ОЗУ не у кого нет, все это “свопится”, так что “тормоза” жуткие и система “крешится” постоянно. Возник извечно русский вопрос: А что делать?
Поскольку Word и Excel формируют страницу таким же образом, занимает она столько же, а именно родные 800 килобайт. Поэтому варианты с написанием отчетов на них отметаются сразу. Accecc и FoxPro – теряется автономность программы. В результате глубинного рытья “всемирной информационной помойки”, под буржуйским названием InterNet, на свет было извлечено решение…

Новое – хорошо забытое старое!
“Когда деревья и компьютеры были большими, мы – маленькими и глупыми, а одной бутылки пива хватало для запаха…” фирма Borland выпустила первую версию Delphi, в которой присутствовал ReportSmith – наш первый генератор отчетов, который был незаслуженно забыт и заменен убогим и глючным QuickReport-ом. Порывшись на задворках интернета нашел аналог – ReportBuilder, который бурно распространяется на пиратских компактах. Вытянул версию поновее, попробовал – получил желаемое 200 килобайт в очереди (можно и меньше, но у меня используется штрихкод, который идет в растре, в идеале страница без графики занимает в очереди порядка 45-50 килобайт). 200 килобайт – это примерно 70-73 страницы в минуту!!! Кроме того, можно печатать без предварительного просмотра, т.е. сходу формируя задания по время первого прохода по базе. Естественно, порылся на хакерских сайтах, нашел кряк и использую до сих пор. Возникшее желание его купить было сразу же убито ценой (порядка 300 баксов). Однако не бывает простых путей…

Проблемы ReportBuilder-а
Проблема с пожиранием памяти вылечилась выключением CashePages. В результате прога в памяти занимает максимум около 16 мегабайт на отчете в 2500 страниц. Проблема с производительностью Windows NT WS немного сложнее. Скорость формирования у меня с запасом, однако системе надо порядка 30-40% производительности для того, чтобы успевать SpoolManager-ом проталкивать задание на принтер, поскольку интерфейс все таки параллельный. Думаю, что на USB принтерах и оснащенных сетевыми картами этих проблем не возникнет. Напрашивалось еще решение – поставить NT Server, у которого не должно быть подобных проблем, повесить на него оба принтера, объединить их в пул (опция pooling) и формировать задания на одной машине. В этом случае, я думаю, листы вылетали бы на любой из свободных принтеров. Однако начальство сказало – break, систему мы менять не будем . Пришлось повесить на таймер процедуру, которая тормозила программу на 31 процент и при старте формирования задания (процент задержки был вычислен экспериментально для этих рабочих станций, для других конфигураций наверное другой, но на машине Celeron 800, система WinXP и принтере LaserJet6L spooler кушает 20-30% ресурсов, все таки никуда не деться – параллельный интерфейс). Еще я меняю приоритет задачи с нормального на низкий, по окончанию естественно возвращаю назад. Как это сделать посмотрите в советах Озерова – там есть примеры. Была еще идея динамически измерять загрузку системы и формировать динамическую задержку, но как это сделать я пока не знаю. Может кто-то знает – отпишите тогда. Однако все вылечить не удалось. Остались проблема с системой. Программа перестала жрать память и начала ее культурно кушать. Однако ядро ее как “жрало”, так и “жрет”. Причем после отработки задания и даже по завершении программы ее не освобождает. В результате, когда занятая ядром память превышает “железные” 128 мегабайт – система частенько “крешится”. Частенько возникают глюки со шрифтами используемыми в формах. Почему-то форма сделанная в одной версии ОС не всегда может использовать те же шрифты на другой. Но это уже мелочь…

Мораль
Мораль проста: FastReport очень хорош, когда отчет 10-20 или даже 200 страниц и скорость печати принтера до 15 страниц в минуту или вообще не важна. Надежность и простота в сочетании с мощностью и простотою встроенного скриптового языка завоевала сердца миллионов и не обошла стороною и меня. ReportBuilder, как говорится, “ему и в подметки не годится”, но когда важна скорость, производительность и аппаратные ресурсы – FastReport просто оставляет желать лучшего. Так что слово Fast в названии этого продукта оправдывает себя только в одном смысле, а именно можно быстро и просто нарисовать 99% возможных вариантов печатных форм.

 

PS:
Если кто-то реши проблемы, которые не смог решить я – отпишите по адресу: kya@ufps.sura.ru – буду благодарен. Если кому-то помог решить свои проблемы – виртуальное пиво заливайте туда же.

 

PS2:
Во время написания этой статьи наткнулся на опрос на Delphi Plus, где было опрошено более 700 человек и большинство из них – 28% используют ReportBuilder, а FastReport – только на 3 месте (15%), уступает даже QuickReport-у (22%). Так что делайте выводы – коллеги!!!

Copyright© 2002 Кузнецов Ю.А.  Специально для Delphi Plus


От DelphiPlus:
В статье автор ссылается на голосование, которое проходило три года тому назад (начавшееся 17.09.1999). 18.11.2002 у нас в разделе Опросы прошло новое голосование – Что Вы используете для генерации отчетов?

Comments are closed.