В процессе анализа своего старого кода иногда удивляешься: кто это написал? ну кто так пишет? Всегда хочется это все переделать и оптимизировать.
Наверное у многих так было, когда по мере набора опыта программирования, приходит осознание того, что хочется писать код не только функциональный, но и красивый. Красивый код более читабелен, лучше отлаживается и кроме этого он приносит внутреннее удовлетворение.
Попытаюсь выложить здесь свой "дзен". Хочу поговорить про красоту кода во внешних печатных формах для библиотеки стандартных подсистем.
Версия БСП особо роли не играет. Стандарты написания внешних печатных форм 1С не меняет уже очень давно. Мне кажется еще с 8.0, независимо от типов форм: обычные или управляемые.
Итак, поехали.
Макет печатной формы.
Для себя я выработал несколько правил:
1. Если в печатной форме доступен только один макет - называю его так же как и имя внешней обработки.
2. В общем случае, когда в макете выводится некоторая коллекция - всегда определяю минимум 4 именованные области строк:
- Заголовок - Область выше таблицы
- Шапка - Шапка таблицы. Всегда выделяю отдельной областью. В случае чего позволит повторять шапку на каждой странице
- Строка - Строка коллекции
- Подвал - Строки ниже таблицы
Если в таблице присутствуют итоги - добавляю 5ю область Итог. Имена областей практически во всех печатных формах одинаковые.
3. Имена полей всегда стараюсь писать без сокращений. К примеру, НоменклатураПоставщика вместо НомПост. Допускаю сокращение, если невозможно назвать поле без сокращений короче 30-35 символов.
4. Если заполнение ячейки = Параметр, то для полей, в которых должна выводиться дата желательно всегда задать формат значения в свойстве ячейки. В противном случае, а так же для полей с заполнением = шаблон формат даты придется задавать в коде.
Формирование табличного документа
Чаще всего формирование печатной формы выполняю в функции с именем СформироватьПечатнуюФорму, хотя никто не мешает назвать ее как угодно. Для унификации принял для себя такое правило.
В минимальном варианте в качестве параметров этой функции достаточно одного: МассивОбъектов. В своей конфигурации я много встречал кода других программистов, которые в качестве параметра этой функции передавали только одну ссылку. Я считаю это грубой ошибкой, поэтому хочу отдельно обратить на это внимание.
Функционально можно разделить функцию СформироватьПечатнуюФорму на несколько областей:
- Инициализация переменных
- Запрос
- Обход запроса и формирование табличного документа.
В разделе инициализация переменных я получаю макет печатной формы, определяю области. Так же как и в макете, я стараюсь использовать такие имена переменных, чтобы без дальнейшего чтения кода можно было понять к чему они относятся. Примерно так:
ТабличныйДокумент = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("Макет");
ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
ОбластьИтог = Макет.ПолучитьОбласть("Итог");
ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");
Отдельная переменная для каждой области макета позволит избежать путаницы при заполнении табличного документа.
Запрос.
Самая главная часть печатной формы. От того, насколько удачно вы построите запрос, зависит дальнейшее построение кода.
Практически любая печатная форма любой сложности может быть описана одним запросом или пакетом запросов. Самое главное чтобы все данные были получены в одной транзакции обращения к базе данных.
Имена полей, которые должны выводиться в печатную форму всегда называю так же, как и в макете.
Всегда делаю как минимум один итог в запросе - по ссылке. Это нужно для формирования табличного документа из формы списка, когда выделено несколько объектов.
Заполнение табличного документа.
Запрос построен, теперь надо вывести данные в табличный документ.
Всегда использую замечательную команду ЗаполнитьЗначенияСвойств. Обращение к параметрам макета напрямую - только в исключительных случаях. Это позволит в случае чего быстрее вносить изменения в печатную форму. К примеру, в случае добавления новой колонки в отчете - достаточно просто добавить поле в запрос и в макет с таким же именем. Заполнение в этом случае дорабатывать не надо.
В минимальном варианте код обхода результата запроса примерно такой:
ВыборкаСсылка = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаСсылка.Следующий() Цикл
ЗаполнитьЗначенияСвойств(ОбластьЗаголовок.Параметры, ВыборкаСсылка);
ТабличныйДокумент.Вывести(ОбластьЗаголовок);
ТабличныйДокумент.Вывести(ОбластьШапка);
Выборка = ВыборкаСсылка.Выбрать();
Пока Выборка.Следующий() Цикл
ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, Выборка);
ТабличныйДокумент.Вывести(ОбластьСтрока);
КонецЦикла;
ЗаполнитьЗначенияСвойств(ОбластьИтог.Параметры, ВыборкаСсылка);
ТабличныйДокумент.Вывести(ОбластьИтог);
ЗаполнитьЗначенияСвойств(ОбластьПодвал.Параметры, ВыборкаСсылка);
ТабличныйДокумент.Вывести(ОбластьПодвал);
ТабличныйДокумент.ВывестиГоризонтальныйРазделительСтраниц();
КонецЦикла;
// Ну и в конце формирования обязательно задаем параметры страницы
ТабличныйДокумент.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;
ТабличныйДокумент.Автомасштаб = Истина;
Причем этот код подойдет к печатной форме любой сложности, если все данные для заполнения присутствуют в запросе.
Отладка.
Ну и в завершение пару слов про отладочную форму обработки.
Я использую следующие реквизиты формы:
- Ссылка - ссылка на объект, для которого формируется печатная форма
- ТабличныйДокумент - для просмотра сформированной формы
- Команда формы Сформировать
На форму вывожу Ссылку и ТабличныйДокумент. Кнопку Сформировать в командную панель.
У формы устанавливаю свойство АвтоматическоеСохранениеДанныхВНастройках = Использовать,
у кнопки "Сформировать" устанавливаю галочку КнопкаПоУмолчанию
У реквизита "ссылка" ставлю галочку "Сохранение"
Ну и код формы всегда одинаков:
&НаСервере
Процедура СформироватьНаСервере()
МассивОбъектов = Новый Массив;
МассивОбъектов.Добавить(Ссылка);
ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
ТабличныйДокумент = ОбработкаОбъект.СформироватьПечатнуюФорму(МассивОбъектов);
КонецПроцедуры
&НаКлиенте
Процедура Сформировать(Команда)
СформироватьНаСервере();
КонецПроцедуры
Заключение.
В процессе работы заметил, что соблюдение описанных правил в обязательном порядке - максимально сократило время создания новых печатных форм с нуля. Фактически мне не нужны готовые шаблоны, т. к. основное время на программирование печатной формы уходит на запрос и рисование макета.
Тестировалось на конфигурации Управление торговлей 11, Но можете использовать на любой конфигурации, основанной на библиотеке стандартных подсистем начиная с версии 2.1 и выше.