Дисклеймер
Если в процессе прочтения кто-то заподозрит, что у автора есть проблемы, он технически неграмотен, на кого-то обижен, не умеет сложить 2+2 и всегда получает 22 в итоге. То мой ответ тут только один: вы вправе так считать. Поэтому свои комментарии в данном контексте можете оставить при себе. Когда выйдет последняя статья, все встанет на свои места. Можете относиться к этой статье, как к вечернему чтиву, от старца, который просто решил немного поворчать.
Важность печатных форм в эпоху ЭДО и безбумажной жизни
В темные времена, когда надо было носить документы на бумаге в различные органы – печатная форма играла роль «хранилища данных». Например, вот сдали вы бухгалтерский баланс, и все. Неважно, что при этом вы изменили в программе – подайте уточненный баланс, иначе не считается.
Потом темные времена сменились на «время ЭЦП», и все уверовали в безбумажный документооборот. Самые отважные посчитали, что печатные формы уже не важны. Однако, эти «бравые ребята» не учли тот фактор, что люди не умеют читать эти ваши XML. И почему-то по-прежнему хотят увидеть какую-то человеко-читаемую бумажку, пусть даже в формате PDF. Я бы не хотел вдаваться сейчас в подробности ЭДО и форматов электронных документов. Но одно стоит упомянуть, важность человеко-читаемой и машиночитаемой части нельзя недооценивать. Последние изменения в формате PDF как бы намекают, что это все неотделяемые друг от друга части.
Поэтому в современное "светлое время будущего" и наступающего равенства, я лично считаю, что любой электронный документ, (внутренний или внешний) должен иметь две части: первую можно открыть и глазками посмотреть, а вторую часть отдать машине на чтение. И конечно же, именно такой «пакет» и должен подписываться ЭЦП… впрочем, опять я не на свою полянку лезу.
Надеюсь, я смог убедить вас, что печатные формы - это важный элемент любой программы.
Где-то здесь хочется упомянуть об особо одаренных компаниях, которые делают примерно так:
- печатают документ на принтере
- некоторые даже подписывают вручную
- кладут бумажку в сканер
- электронную скан-копию прикрепляют в программу (ДО, бухгалтерия и т.д.)
- подписывают ЭЦП и отправляют по маршруту бизнес-процесса
Тут где-то должен быть смайлик рука-лицо. Но увы, это не сарказм, это реальность. Хотя специально для них, я бы печатные формы сначала ограничил, а потом вернул назад. Ну когда процесс перевоспитания будет окончен.
Проблема печатных форм в 1С
Начнем с того, что в настоящее время правил и стандартов формирования печатных форм нет.
Конечно, вы можете возразить, мол, в стандартах разработки что-то есть. Да, есть, но это рекомендации и вот они:
- Формирование печатных форм
- Разработка печатных форм с учетом возможного внесения изменений в макет пользователем
- Названия печатных форм учетных документов и команд по их выводу на печать
Более того, я практически уверен, что эти рекомендации не появились бы без БСП (библиотека стандартных подсистем) с ее подсистемой Печать. С помощью которой, сначала в стандарт ввели множественную печать. Потом когда дали возможность менять макет, добавили про разработку. В результате собственно рекомендации и появились. Ну кроме рекомендации про названия команд, ОК.
На текущий момент можно найти условно 2 базовых сценария формирования и вывода печатных форм:
- Сбор и вывод данных в процессе формирования печатной формы. Назовем его "метод все в одном"
- Сбор данных отдельно, вывод в печатную формы отдельно. Ну, а тут соответственно "метод раздельный"
Понятно, что это не «чистые» варианты. Те же периодические данные в 90% случае собираются в процессе вывода данных. Хотя лично меня всегда этот момент расстраивает.
Впрочем, сейчас не вспомню, где я прочитал комментарий в духе «стоит ли заморачиваться о затратах на сбор данных, если вывод в табличный документ занимает, как правило, больше времени». Лично я не совсем согласен с этим утверждением. Скорость работы табличного документа – это дело платформы. Повлиять на него мы не можем, а вот сделать сбор данных эффективным и быстрым можем.
Но давайте вернемся к способам формирования печатных форм. И рассмотрим их подробнее.
Метод "все в одном"
Это тот самый вариант, который пришел к нам из «темных» времен. Ну и с него, как правило, начинают писать молодые и неопытные падаваны (ну или, как там их еще называют, джуниоры, молодняк, гребцы на галерах).
Просто он самый очевидный и простой. Более того невозможно ничего забыть. Пошагово процесс выглядит так:
- рисуем макет со всеми параметрами
- пишем код по выводу области (одна за другой)
- перед выводом области заполняем параметры (да, да, именно тем самым способом Область.Параметры.Имя = …)
- выводим область
- вуаля, печатная форма готова
И вот если здесь, перед присвоением значения параметра, мы вдруг обнаружили что нам не хватает данных, достаем лопату и идем рыть землю в поисках клада. То есть пишем запросы, какие-то вычисления и тому подобное. Более опытные (ну те, которые претендуют на звание middle и зарплату чуть больше, чем бургер с картошечкой) догадываются что:
- запросы в цикле лучше не делать
- данные можно получать через методы общих модулей
- периодические данные надо собирать с учетом даты документа
Ну и конечно же, все это может быть в одном методе, количество строк кода в котором будет сравнимо с повестью русских классиков.
В издательстве рассказом считается текст в среднем до 2х авторских листов. Повесть от 2х до 8ми страниц (320тыс. знаков). Хотя если взять такую классификацию, уверен найдутся те, кто будет претендовать на гордое звание «роман по выводу печатной формы».
Конечно, не всегда удастся избежать огромного метода по выводу печатной формы. Тот же баланс, в принципе, сложно сделать методом из 10 строк. Но, кто видел баланс, знает, что количество вспомогательных методов там большое. Однако, я про другую крайность. Просто представьте счет на оплату, сделанный одним методом. Где в процессе вывода каждой области собираются данные. А например, остаток на складе рассчитывается при выводе каждой строки. Вот именно такие «прекрасные» во всех отношениях, методы как правило рождаются, у многих начинающих.
Метод "раздельный"
Обычно до необходимости отдельного сбора данных добираются очень быстро. Достаточно перешагнуть на уровень, когда задачи не относятся к разряду «не навреди». Ну или развитие разработчика начинает шагать уверенно вперед, и все чаще хочется универсальности и повторного использования кода. И уж тем более, если прочитал стандарты, посмотрел в современные типовые конфигурации и вдруг захотелось чтобы «нормально делай, нормально будет».
Там же где-то обычно идет освоение БСП с ее возможностями множественной печати и изменения макетов.
Пошагово процесс в таком случае несколько изменяется:
- рисуем макет со всеми параметрами
- анализируем возможность унификации сбора данных
- подготавливаем данные складываем их в удобные коллекции
- пишем код по выводу печатной формы каждой ссылки
- заполнение параметров областей делаем при помощи ЗаполнитьЗначенияСвойств
- в идеале получение и вывод областей через их поиск в макете (но как правило это реже происходит, почти не встречал в жизни)
Почему именно множественная печать приводит разработчиков к предварительному сбору данных? Собственно, тут все просто. О том, что запросы в цикле - это зло, трубят из каждого утюга. А когда видишь цикл по ссылкам из массива и вызов метода, внутри которого идет запрос на сбор данных, волей неволей руки чешутся этот запрос выдрать куда-то наружу, результат положить в соответствие и просто получать структуру (массив) с результатом. Ну или как вам нравится (посыпьте любыми коллекциями на свой вкус).
И вот если вдруг, программист уже уверенно так пишет, а его печатные формы не падают, когда неумеха пользователь через БСП «доработал» макет, можно смело требовать гордого звания сеньор (помидор), зарплату в три бургера и Добрый кола © в холодильнике на бесплатной основе.
А что, собственно, не так?
Именно с таким вопросом обычно ко мне приходят по большинстве инициатив, которые я выдвигаю. Поэтому отвечу...
Периодические данные
Почти везде расчет периодических данных выполняется в процессе вывода печатной формы. И я писал выше, что это объясняется тем, что тут мы, мол, и дату знаем, и все такое. А я объясняю это тем, что просто не каждый может написать запрос так, чтобы периодические данные считались в запросе корректно. Соглашусь, вопрос дискуссионный, что лучше - собрать в запросе или при выводе. Но, даже если при выводе, кто-нибудь видел при этом, чтобы они кэшировались? Хотя и тут есть о чем поспорить
Доработка печатных форм
«Взрослые» программисты не любят делать печатные формы. Поэтому они достаются «молодым», а когда такой весь умудренный опытом и знаниями приходит, просто даже доработать печатную форму не настолько сложно, насколько неприятно.
Связь параметров макета и данных
С появлением СКД, например, с отчетами все стало понятно и удобно. Если хорошо понимаешь, как работает СКД, смотришь на отчет и очень быстро «разматываешь», откуда пришли данные. С печатными формами, это всегда детектив и хождение по тропинкам из хлебных крошек.
Версионирование и сравнение
Нечастая проблема – необходимость сравнивать печатные формы. Но когда такая необходимость возникает, всегда сравниваешь отдельно макет и код. А вот связь между ними (см. пункт выше) остается за кадром. Ну и сравнение/объединение может вообще превратить все в пытку. Причем, не важно, как именно написана печатная форма. Одним методом или с предварительным сбором. Хотя честности ради, лично мне второй метод все равно кажется предпочтительнее.
В свое время я пробовал сделать печатные формы на СКД. Однако столкнулся с тем, что в печатных формах чаще встречается конкатенация строк, какая-то дополнительная обработка и провернуть ее на СКД в разы сложнее. В итоге не сказать, что результат становится проще.
Ну и еще чуток...
Ну и вишенка на торте, конструктор печатных форм, который встроен в конфигуратор. Собственно, кто им вообще пользуется? Зачем? Ведь все равно, он не удовлетворяет стандартам, его код приходится выкидывать, а макет дорисовывать. Если печатная форма чуть сложнее чем шапка и табличная часть из колонок документа, он не помогает ничем. От конструктора там только набор деталей, которые как в китайском лего. Не факт, что еще и подходят друг к другу.
Я сознательно не касаюсь вопроса внешних печатных форм...
И что ты предлагаешь?
В ситуации, когда низы не могут, а верхи не хотят обычно происходит революция. Но что делать, если ты в одном лице представляешь обе стороны противоборствующего конфликта?
Как программист, я больше не хотел писать печатные формы, пусть даже в формате раздельного сбора и вывода. А работа заставляла. Как руководитель, я стоял на своем и говорил «работает, не трогай». То есть не изобретай велосипед. Однако, потом руководитель немного услышал голодный бунт и пошел на встречу. Тогда я попытался стандартизировать разработку.
Но об этом в следующей статье…