При формировании печатных форм и отчетов в 1С часто возникает задача вывести динамический набор колонок (например, список детей или дополнительных реквизитов) напротив соответствующей строки родителя или основного объекта. Если вызывать вывод горизонтальной области через метод Вывести(), а затем пытаться добавить вертикальную секцию через Присоединить() без учета структуры пересечений макета, ячейки таблицы "плывут" или выставляются со смещением.
Рассмотрим причину возникновения этой проблемы и разберем по шагам правильный алгоритм работы с горизонтальными и вертикальными секциями в табличном документе 1С.
Проанализируем механику работы основных методов объекта ТабличныйДокумент:
Вывести() — выводит область макета на новую строку (ниже всех ранее выведенных ячеек) и сбрасывает указатель текущей колонки на крайнее левое положение.Присоединить() — добавляет область строго справа от последней выведенной области в рамках той же строки, которая была создана вызовом Вывести().Если в макете выбрана вся горизонтальная строка (без ограничений по вертикальным колонкам), метод Вывести() забирает под себя всю ширину печатной формы. В этом случае последующий вызов Присоединить() разместит вертикальную секцию в первой свободной колонке далеко справа. При переходе к следующей итерации вызов Вывести() сместит всё вниз, образуя лестничный вывод данных.
Чтобы данные отображались строго напротив родительской строки в нужных колонках, необходимо разбить макет не только на горизонтальные полосы, но и на вертикальные секции (колонки).
Синтаксис получения области-пересечения выглядит следующим образом:
ИмяОбласти = Макет.ПолучитьОбласть("ИмяГоризонтальнойСекции|ИмяВертикальнойСекции");
Пошагово разберем порядок действий при настройке макета и написании кода:
В макете выделяем горизонтальную секцию (например, Контакты) и две вертикальные секции: левую для родителя (например, ШапкаКолонок или РодительКолонка) и правую для динамических данных (например, РебенокКолонка).
В цикле по родительским объектам получаем область пересечения строки родителя и его вертикальной колонки, заполняем параметры и выводим её через метод Вывести().
Во вложенном цикле по подчиненным элементам получаем область пересечения той же строки с вертикальной колонкой подчиненных данных, заполняем параметры и вызываем метод Присоединить().
Посмотрим на практический пример реализации вывода родительских контактов и подчиненного списка детей напротив каждого родителя:
Пока Выборка.Следующий() Цикл
// Получаем область родителя как пересечение горизонтальной и вертикальной секций
ОбластьРодитель = Макет.ПолучитьОбласть("Контакты|РодительКолонка");
ОбластьРодитель.Параметры.ИнформационнаяКарта = текЧек.ДисконтнаяКарта.ВладелецКарты;
// Выводим левую часть строки (перевод каретки на новую строку)
ТабДок.Вывести(ОбластьРодитель);
// Вложенный цикл по подчиненным данным (детям)
Для Каждого Стр Из текЧек.ДисконтнаяКарта.ВладелецКарты.Дети Цикл
// Получаем область ребенка на пересечении той же горизонтальной строки и колонки ребенка
ОбластьРебенок = Макет.ПолучитьОбласть("Контакты|РебенокКолонка");
ОбластьРебенок.Параметры.ИмяРебенка = Стр.Имя;
// Присоединяем колонку справа в ту же строку
ТабДок.Присоединить(ОбластьРебенок);
КонецЦикла;
КонецЦикла;
Важно: При таком подходе метод ТабДок.Вывести() фиксирует начало новой строки таблицы для каждого родителя, а метод ТабДок.Присоединить() добавляет каждого ребенка последовательно вправо в пределах этой же строки. В результате табличный документ будет сформирован корректно и без смещения ячеек.