Как разработать сложную печатную форму в 1С с динамическими колонками и объединением ячеек?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Разработка печатных форм в 1С — это стандартная задача, которая, однако, может стать серьезным вызовом, если требуется реализовать сложную логику отображения данных. К таким задачам относятся: скрытие или отображение колонок в зависимости от условий, вывод иерархических структур (подстрок) с объединением родительских ячеек и корректная нумерация страниц в формате «Страница X из Y» в шапке документа. Разберем подробно, как реализовать эти требования программными методами.

Реализация условного вывода колонок

Для решения задачи, когда одна из колонок (например, в середине таблицы) должна выводиться только при определенных условиях, мы не рекомендуем создавать несколько разных макетов. Это затрудняет дальнейшую поддержку кода. Вместо этого проанализируем метод горизонтальных секций и использование метода Присоединить().

Суть метода заключается в разделении макета на несколько вертикальных областей. Например, в макете мы выделяем области Шапка_Лево, Шапка_Условие и Шапка_Право. При формировании документа мы будем «собирать» строку из этих частей.

Рассмотрим пример программного кода для реализации такой логики:


// Получаем области из макета
ОбластьЛево = Макет.ПолучитьОбласть("Строка|ЛеваяЧасть");
ОбластьУсловие = Макет.ПолучитьОбласть("Строка|УсловнаяКолонка");
ОбластьПраво = Макет.ПолучитьОбласть("Строка|ПраваяЧасть");

// Выводим левую часть строки
ТабДок.Вывести(ОбластьЛево);

// Проверяем условие для вывода центральной колонки
Если УсловиеВыполнено Тогда
    ТабДок.Присоединить(ОбластьУсловие);
КонецЕсли;

// Присоединяем правую часть
ТабДок.Присоединить(ОбластьПраво);

Важно помнить, что при использовании метода Присоединить(), 1С дописывает данные в ту же строку табличного документа, пока не будет вызван метод Вывести() для новой строки. Это позволяет динамически изменять ширину таблицы «на лету».

Вывод подстрок и вертикальное объединение ячеек

Вторая задача — вывод подстрок для основной строки, при котором данные основной строки должны быть объединены вертикально. Выясним причину, почему это лучше делать программно: стандартный вывод областей просто создаст дублирующиеся строки или пустоты.

Для правильной реализации выполним следующие шаги:

  1. Зафиксируем номер строки начала вывода данных.
  2. В цикле выведем все подстроки, заполняя только колонки, относящиеся к подстрокам.
  3. Зафиксируем номер строки окончания вывода.
  4. Используем метод Область() для выбора диапазона строк и колонки основной записи.
  5. Вызовем метод Объединить().

Посмотрим на пример кода:


// Номер первой строки данных для основной записи
НомерНачала = ТабДок.ВысотаТаблицы + 1;

Для Каждого СтрокаПодстрока Из Данные.Подстроки Цикл
    ОбластьПодстроки = Макет.ПолучитьОбласть("СтрокаПодстрока");
    ОбластьПодстроки.Параметры.Заполнить(СтрокаПодстрока);
    ТабДок.Вывести(ОбластьПодстроки);
КонецЦикла;

// Номер последней выведенной строки
НомерКонца = ТабДок.ВысотаТаблицы;

// Объединяем ячейки в первой колонке (где основная информация)
Если НомерКонца > НомерНачала Тогда
    ОбластьДляОбъединения = ТабДок.Область(НомерНачала, 1, НомерКонца, 1);
    ОбластьДляОбъединения.Объединить();
    ОбластьДляОбъединения.ВертикальноеПоложение = ВертикальноеПоложение.Центр;
КонецЕсли;

Обратите внимание, что при объединении ячеек часто требуется установить свойство ВертикальноеПоложение в значение Центр, чтобы текст основной строки красиво располагался посередине относительно всех своих подстрок.

Как узнать общее количество листов до завершения печати

Проблема вывода общего количества страниц в шапке (например, на первой странице) заключается в том, что 1С не знает, сколько страниц получится, пока документ не сформирован полностью. Проанализируем ситуацию: стандартные колонтитулы решают проблему, если номер нужно вывести в самом верху или внизу листа. Но если номер страницы является частью тела документа (в макете), потребуется другой подход.

Наиболее надежный способ — двухпроходное формирование документа:

  1. Создаем временный объект ТабличныйДокумент.
  2. Выполняем весь алгоритм формирования печатной формы в этот временный документ.
  3. Используем метод ТабДок.КоличествоСтраниц(), чтобы получить итоговое число.
  4. Очищаем или создаем новый ТабличныйДокумент и запускаем формирование заново, передавая полученное количество страниц в параметр шапки.

Разберем нюансы этого метода. Чтобы количество страниц в первом и втором проходах совпало, необходимо жестко задать параметры печати перед началом расчетов:


ТабДок.ИмяПринтера = "ИмяВашегоПринтера";
ТабДок.АвтоМасштаб = Истина;
ТабДок.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;
// ... другие настройки
ВсегоСтраниц = ТабДок.КоличествоСтраниц();

Если вы хотите избежать двойного прохода из-за производительности, рассмотрите использование метода ПроверитьВывод(). Этот метод позволяет проверить, помещается ли очередная область на текущую страницу, и таким образом самостоятельно отслеживать разрывы страниц и их количество в процессе формирования.

Работа с колонтитулами

Если же дизайн формы позволяет вывести нумерацию в нижнем или верхнем поле страницы, лучше воспользоваться встроенным механизмом колонтитулов. Это проще и не требует двойного формирования документа.


ТабДок.НижнийКолонтитул.Выводить = Истина;
ТабДок.НижнийКолонтитул.ТекстСлева = "Страница [&НомерСтраницы] из [&СтраницВсего]";
ТабДок.НижнийКолонтитул.Шрифт = Новый Шрифт("Arial", 10);

Специальные подстановочные конструкции [&НомерСтраницы] и [&СтраницВсего] будут автоматически заменены платформой при выводе на печать или в режиме предварительного просмотра.

Подводя итог, можно сказать, что гибкость табличного документа 1С позволяет реализовать практически любые требования к оформлению. Главное — комбинировать методы Вывести, Присоединить и программное управление областями через Объединить.

← На главную