Разработка печатных форм в 1С — это стандартная задача, которая, однако, может стать серьезным вызовом, если требуется реализовать сложную логику отображения данных. К таким задачам относятся: скрытие или отображение колонок в зависимости от условий, вывод иерархических структур (подстрок) с объединением родительских ячеек и корректная нумерация страниц в формате «Страница X из Y» в шапке документа. Разберем подробно, как реализовать эти требования программными методами.
Для решения задачи, когда одна из колонок (например, в середине таблицы) должна выводиться только при определенных условиях, мы не рекомендуем создавать несколько разных макетов. Это затрудняет дальнейшую поддержку кода. Вместо этого проанализируем метод горизонтальных секций и использование метода Присоединить().
Суть метода заключается в разделении макета на несколько вертикальных областей. Например, в макете мы выделяем области Шапка_Лево, Шапка_Условие и Шапка_Право. При формировании документа мы будем «собирать» строку из этих частей.
Рассмотрим пример программного кода для реализации такой логики:
// Получаем области из макета
ОбластьЛево = Макет.ПолучитьОбласть("Строка|ЛеваяЧасть");
ОбластьУсловие = Макет.ПолучитьОбласть("Строка|УсловнаяКолонка");
ОбластьПраво = Макет.ПолучитьОбласть("Строка|ПраваяЧасть");
// Выводим левую часть строки
ТабДок.Вывести(ОбластьЛево);
// Проверяем условие для вывода центральной колонки
Если УсловиеВыполнено Тогда
ТабДок.Присоединить(ОбластьУсловие);
КонецЕсли;
// Присоединяем правую часть
ТабДок.Присоединить(ОбластьПраво);
Важно помнить, что при использовании метода Присоединить(), 1С дописывает данные в ту же строку табличного документа, пока не будет вызван метод Вывести() для новой строки. Это позволяет динамически изменять ширину таблицы «на лету».
Вторая задача — вывод подстрок для основной строки, при котором данные основной строки должны быть объединены вертикально. Выясним причину, почему это лучше делать программно: стандартный вывод областей просто создаст дублирующиеся строки или пустоты.
Для правильной реализации выполним следующие шаги:
Область() для выбора диапазона строк и колонки основной записи.Объединить().Посмотрим на пример кода:
// Номер первой строки данных для основной записи
НомерНачала = ТабДок.ВысотаТаблицы + 1;
Для Каждого СтрокаПодстрока Из Данные.Подстроки Цикл
ОбластьПодстроки = Макет.ПолучитьОбласть("СтрокаПодстрока");
ОбластьПодстроки.Параметры.Заполнить(СтрокаПодстрока);
ТабДок.Вывести(ОбластьПодстроки);
КонецЦикла;
// Номер последней выведенной строки
НомерКонца = ТабДок.ВысотаТаблицы;
// Объединяем ячейки в первой колонке (где основная информация)
Если НомерКонца > НомерНачала Тогда
ОбластьДляОбъединения = ТабДок.Область(НомерНачала, 1, НомерКонца, 1);
ОбластьДляОбъединения.Объединить();
ОбластьДляОбъединения.ВертикальноеПоложение = ВертикальноеПоложение.Центр;
КонецЕсли;
Обратите внимание, что при объединении ячеек часто требуется установить свойство ВертикальноеПоложение в значение Центр, чтобы текст основной строки красиво располагался посередине относительно всех своих подстрок.
Проблема вывода общего количества страниц в шапке (например, на первой странице) заключается в том, что 1С не знает, сколько страниц получится, пока документ не сформирован полностью. Проанализируем ситуацию: стандартные колонтитулы решают проблему, если номер нужно вывести в самом верху или внизу листа. Но если номер страницы является частью тела документа (в макете), потребуется другой подход.
Наиболее надежный способ — двухпроходное формирование документа:
ТабличныйДокумент.ТабДок.КоличествоСтраниц(), чтобы получить итоговое число.ТабличныйДокумент и запускаем формирование заново, передавая полученное количество страниц в параметр шапки.Разберем нюансы этого метода. Чтобы количество страниц в первом и втором проходах совпало, необходимо жестко задать параметры печати перед началом расчетов:
ТабДок.ИмяПринтера = "ИмяВашегоПринтера";
ТабДок.АвтоМасштаб = Истина;
ТабДок.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;
// ... другие настройки
ВсегоСтраниц = ТабДок.КоличествоСтраниц();
Если вы хотите избежать двойного прохода из-за производительности, рассмотрите использование метода ПроверитьВывод(). Этот метод позволяет проверить, помещается ли очередная область на текущую страницу, и таким образом самостоятельно отслеживать разрывы страниц и их количество в процессе формирования.
Если же дизайн формы позволяет вывести нумерацию в нижнем или верхнем поле страницы, лучше воспользоваться встроенным механизмом колонтитулов. Это проще и не требует двойного формирования документа.
ТабДок.НижнийКолонтитул.Выводить = Истина;
ТабДок.НижнийКолонтитул.ТекстСлева = "Страница [&НомерСтраницы] из [&СтраницВсего]";
ТабДок.НижнийКолонтитул.Шрифт = Новый Шрифт("Arial", 10);
Специальные подстановочные конструкции [&НомерСтраницы] и [&СтраницВсего] будут автоматически заменены платформой при выводе на печать или в режиме предварительного просмотра.
Подводя итог, можно сказать, что гибкость табличного документа 1С позволяет реализовать практически любые требования к оформлению. Главное — комбинировать методы Вывести, Присоединить и программное управление областями через Объединить.