При разработке печатных форм часто возникает задача, когда в одном макете расположены две разграниченные печатные формы (например, с горизонтальным разделителем), но при печати конкретного документа требуется выводить только одну из них или обе сразу в зависимости от некоторого реквизита — например, пункта доставки. Рассмотрим, как грамотно организовать такую логику, чтобы код оставался поддерживаемым при добавлении новых точек доставки.
Самый простой подход на первый взгляд — это использование условий Если ... ИначеЕсли непосредственно в модуле печати. Выясним, почему этот метод не всегда удобен. Если в системе существует всего две точки доставки, жесткое условие в коде сработает нормально. Однако при увеличении числа торговых точек или контрагентов разработчику придется постоянно править конфигурацию и добавлять новые проверки.
Проанализируем архитектурные решения, которые позволяют избежать постоянного обновления кода и делают систему гибкой.
Наиболее масштабируемый вариант — создание непериодического регистра сведений (например, НастройкиПечатныхФормДоставки). В качестве измерений и реквизитов регистра можно указать:
Разберем алгоритм работы этого решения. Перед формированием табличного документа алгоритм запросом получает параметры из регистра сведений. В зависимости от полученного значения выводятся соответствующие области макета.
Посмотрим на пример кода запроса и формирования печатной формы:
// Получаем настройку из регистра сведений
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Настройки.ТипПечатнойФормы КАК ТипФормы
|ИЗ
| РегистрСведений.НастройкиПечатныхФормДоставки КАК Настройки
|ГДЕ
| Настройки.Доставка = &Доставка";
Запрос.УстановитьПараметр("Доставка", СсылкаНаДокумент.Доставка);
РезультатЗапроса = Запрос.Выполнить();
ТипФормы = 1; // Значение по умолчанию
Если НЕ РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
ТипФормы = Выборка.ТипФормы;
КонецЕсли;
ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("МакетПечати");
// Выводим первую форму, если требуется
Если ТипФормы = 1 ИЛИ ТипФормы = 3 Тогда
ОбластьШапка1 = Макет.ПолучитьОбласть("Шапка1");
// Заполнение параметров шапки первой формы
ТабДок.Вывести(ОбластьШапка1);
// Вывод табличной части первой формы
// ...
КонецЕсли;
// Если выводим обе формы, добавляем разделитель страниц
Если ТипФормы = 3 Тогда
ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
КонецЕсли;
// Выводим вторую форму, если требуется
Если ТипФормы = 2 ИЛИ ТипФормы = 3 Тогда
ОбластьШапка2 = Макет.ПолучитьОбласть("Шапка2");
// Заполнение параметров шапки второй формы
ТабДок.Вывести(ОбластьШапка2);
// Вывод табличной части второй формы
// ...
КонецЕсли;
Если нет возможности создавать отдельный регистр сведений, проанализируем другие доступные способы хранить привязку печатных форм:
ВидПечатнойФормы или булевый флаг ФормироватьВторуюФорму. Это позволит проверять значение напрямую через обращение к объекту или в основном запросе печати.Соответствие в коде обработки печати.Рассмотри важные нюансы работы с табличным документом при выводе нескольких форм:
ВывестиГоризонтальныйРазделительСтраниц() или вывод области с разделителем страниц должен происходить строго перед формированием второй формы и только в том случае, если вторая форма действительно выводится. В противном случае на печать уйдет лишний пустой лист.ПроверитьВывод() табличного документа, передавая в него массив областей перед их выводом.ТабличнаяЧасть.НайтиСтроки() со структурой отбора или производить отбор заранее пакетом запросов.Таким образом, лучшей практикой является вынос логики сопоставления точек доставки и печатных форм в регистр сведений или реквизиты справочника, чтобы избавиться от жесткого кода с множеством условий и обеспечить удобство настройки системы.