Вопрос о необходимости распечатывания в 1С большого количества документов поднимался не раз, и в сети можно найти немалое количество обработок, посвященных решению данной проблемы. Данный вопрос не так давно встал и передо мной в следующей постановке: «Мне нужна обработка, позволяющая распечатать много накладных, печатная форма – “ТОРГ-12 (форма 2011г.)” (есть у нас такая внешняя печатная форма – прим. автора)».
Не мудрствуя лукаво, беру за основу ту самую внешнюю печатную форму, вешаю на диалоговое окно всякие красивости для отбора накладных, подправляю код и, вуаля - все готово! Дальше - больше: «А еще мне нужно массово распечатывать эти накладные, но в печатной форме “ТОРГ-12 (Пром)” (есть у нас и такая внешняя печатная форма – прим. автора). Тут уже нужно было что-то делать более универсальное на случай, если через некоторое время понадобятся опять или новые документы, или новые печатные формы.
Выход я нашел следующий: классы! Суть: каждую внешнюю печатную форму оборачиваем в класс и вызываем его из обработки массовой печати документов. Доработки внешней печатной формы под класс совсем небольшие и занимают меньше времени, чем их описание в этой статье. А доработать необходимо следующее:
- - объявляем экспортными переменную «Докум» и процедуру «Печать()»;
- - решительно удаляем процедуру «ПриОткрытии()»;
- - исходную таблицу копируем из обработки в файл «.mxl» (поскольку класс не увидит ее внутри обработки, на то он и класс) и, соответственно, заменяем выражение типа «Таблица.ИсходнаяТаблица(«Таблица»);» на выражение типа «Таблица.ИсходнаяТаблица(глКаталогПечФорм + «Торг12.mxl»);»;
- - чтобы получить одну портянку с кучей документов, а не кучу портянок по одному документу, убираем объявление типа «Таблица = СоздатьОбъект(«Таблица»);» и «Таблица.ИсходнаяТаблица(глКаталогПечФорм + «Торг12.mxl»);» из процедуры «Печать()» и вставляем его в модуль обработки (добавляем в конец модуля). Соответственно, переменную «Таблица» объявляем переменной модуля;
- - также убираем из процедуры «Печать()» выражение типа «Таблица.Показать()», вместо этого добавляем экспортную процедуру «Показать()» с единственной строкой: «Таблица.Показать();». Этот метод будем вызывать после цикла с методом «Печать();
- - для того, чтобы новый документ печатался на новой странице, в конце процедуры «Печать()» добавляем строку типа «Таблица.НоваяСтраница()»;
- - проверяем модуль на наличие строк типа «Таблица.ПовторятьПриПечатиСтроки();». Иначе будет сюрприз!
- - ну и естественно, предусмотреть загрузку внешней компоненты 1срр.dll (если она у вас до сих пор не предусмотрена) и описать классы в defcls.prm.
В результате мы имеем:
- Обработка является универсальной - ее можно внедрить в любую конфигурацию.
- С помощью примера, приведенного в данной обработке, можно распечатать любой документ в любой внутренней или внешней печатной форме. При выходе в свет новой печатной формы она элементарно добавляется в обработку.
- Код обработки стал до предела кратким и понятным (и содержит порядка сотни строк). Для добавления нового документа нужно добавить лишь несколько строк кода в конец модуля путем копи-паста. Для добавления новой печатной формы к уже существующему документу нужно добавить всего одну строку кода.
- Для непосвященных в ООП это отличный пример, что такое классы и как их применять на практике.
Если процедура вывода на печать находится в модуле формы документа, то логика работы та же самая: процедуру «Печать()» копируем и оборачиваем в класс. Правда, здесь доработок будет побольше: нужно будет добавить ссылку на документ (т.е. то, что передается контекстом во внешнюю печатную форму).
Недостатки: я уже написал по поводу строк кода типа «Таблица.ПовторятьПриПечатиСтроки();», с помощью которых выводится на следующую страницу заголовок табличной части документа. Поскольку у меня подавляющее большинство документов помещалось на одной странице, я закомментировал эти строки и убрал колонтитулы из печатных форм. Если кому-нибудь понадобится выводить эти строки - обработку надо будет доработать. Но это недостаток конкретной реализации, а не самой идеи.