При формировании сложных печатных форм или нестандартных отчетов программисты часто сталкиваются с задачей, когда после вывода основного блока данных (строк) необходимо добавить еще один блок информации справа. Основная сложность заключается в том, что стандартный метод Вывести() добавляет данные вниз, а метод Присоединить() — справа от последней выведенной области. Если нам нужно, чтобы правый блок начинался с самой первой строки отчета, а не «висел» где-то внизу, требуются специальные приемы работы с объектом ТабличныйДокумент.
В этой статье мы подробно разберем несколько способов решения этой задачи: от классического использования областей макета до работы с независимыми табличными документами и методом прямой адресации ячеек.
Один из наиболее простых и изящных способов — это формирование двух независимых табличных документов, которые затем «склеиваются» по горизонтали. Этот метод позволяет не заботиться о том, какая строка сейчас является текущей в основном документе.
Рассмотрим алгоритм действий:
ТабличныйДокумент (основная часть отчета) и заполняем его данными с помощью Вывести().ТабличныйДокумент (правая часть) и заполняем его отдельно, также начиная с первой строки.Присоединить() основного документа, передавая в него второй документ.Посмотрим на пример кода:
// Создаем два временных табличных документа
ТабДокОсновной = Новый ТабличныйДокумент;
ТабДокПраваяЧасть = Новый ТабличныйДокумент;
// Заполняем основную часть
ОбластьМакета = Макет.ПолучитьОбласть("СтрокаДанных");
Для Каждого Стр Из ДанныеОсновнойЧасти Цикл
ОбластьМакета.Параметры.Заполнить(Стр);
ТабДокОсновной.Вывести(ОбластьМакета);
КонецЦикла;
// Заполняем правую часть (она может быть короче или длиннее основной)
ОбластьПраво = Макет.ПолучитьОбласть("ДопДанные");
Для Каждого Стр Из ДополнительныеДанные Цикл
ОбластьПраво.Параметры.Заполнить(Стр);
ТабДокПраваяЧасть.Вывести(ОбластьПраво);
КонецЦикла;
// Присоединяем второй документ к первому
// 1С автоматически сопоставит строки: 1-я ко 1-й, 2-я ко 2-й и т.д.
ТабДокОсновной.Присоединить(ТабДокПраваяЧасть);
Этот метод хорош тем, что 1С берет на себя управление геометрией. Если в правой части строк меньше, чем в основной, нижние ячейки справа останутся пустыми. Если больше — строки основной части будут дополнены пустыми ячейками слева.
Проанализируем ситуацию, когда структура макета позволяет разделить его на вертикальные полосы. В 1С можно обращаться к пересечениям областей. Например, область макета может быть определена как Шапка|ЛеваяЧасть и Шапка|ПраваяЧасть.
Разберем по шагам, как это реализовать в цикле:
Вывести(ОбластьЛево), а затем сразу Присоединить(ОбластьПраво).Однако, если нам нужно вывести ВСЮ левую часть, а потом ВСЮ правую (с возвратом к первой строке), этот метод в чистом виде не сработает без использования индексации строк.
Если левая часть отчета уже сформирована, мы можем «вернуться» в любую ячейку, зная её координаты (номер строки и номер колонки). Рассмотрим подробнее, как это сделать. В 1С объект ТабличныйДокумент позволяет работать с произвольной областью по принципу Excel.
Проанализируем пример, где мы заполняем правую колонку после вывода всего документа:
// Предположим, ТабДок уже содержит 100 строк данных
// Нам нужно заполнить колонку №5 данными, начиная с 1-й строки
НомерСтроки = 1;
Для Каждого ЗначениеИзСписка Из МоиДопДанные Цикл
// Получаем конкретную ячейку по адресу R(строка)C(колонка)
ТекущаяЯчейка = ТабДок.Область(НомерСтроки, 5, НомерСтроки, 5);
ТекущаяЯчейка.Текст = ЗначениеИзСписка;
// Можно также задать оформление
ТекущаяЯчейка.ЦветТекста = ЦветаСтиля.ЦветОтрицательногоЧисла;
НомерСтроки = НомерСтроки + 1;
КонецЦикла;
Этот подход максимально гибок. Вы можете не просто вставлять текст, но и менять форматирование, устанавливать расшифровки или объединять ячейки в уже готовом документе. Главное — точно знать индекс колонки, с которой начинается «правая область».
Метод ВставитьОбласть() — это мощный инструмент для динамического изменения структуры таблицы. Он позволяет «раздвинуть» существующие ячейки и вставить туда новые данные.
Выясним причину, по которой этот метод часто предпочитают обычному заполнению: он копирует область вместе со всеми свойствами (ширина колонок, шрифты, примечания, картинки). Если вам нужно вставить справа не просто текст, а сложную структуру из макета, используйте этот код:
// Исходная область в макете
ОбластьМакета = Макет.ПолучитьОбласть("ПраваяПанель");
// Область-приемник в итоговом документе (куда вставлять)
// Например, вставляем начиная с 1-й строки и 10-й колонки
ОбластьПриемник = ТабДок.Область(1, 10, 1, 10);
// Используем смещение по горизонтали, чтобы не затереть существующие данные
ТабДок.ВставитьОбласть(ОбластьМакета, ОбластьПриемник, ТипСмещенияТабличногоДокумента.ПоГоризонтали, Истина);
Важный момент: при использовании ВставитьОбласть крайне важно следить за параметром ЗаполнятьПараметры. Если в области макета есть параметры типа [ИмяПараметра], 1С попытается их заполнить из текущего контекста или структуры, переданной в метод.
Иногда «область справа» — это не табличные данные, а некая информационная справка, график или логотип, который должен располагаться сбоку от текста. В этом случае мы можем использовать объекты типа РисунокТабличногоДокумента.
Посмотрим на пример добавления текстового блока поверх сетки или справа от неё:
Рисунок = ТабДок.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Текст);
Рисунок.Текст = "Это пояснительный текст справа";
// Устанавливаем координаты в миллиметрах или привязку к ячейкам
Рисунок.Верх = 5; // 5 мм от верха листа
Рисунок.Лево = 150; // 150 мм от левого края (справа от данных)
Рисунок.Ширина = 40;
Рисунок.Высота = 20;
Рисунок.ГраницаСверху = Ложь; // Убираем рамку, если нужно
Рисунки позволяют игнорировать сетку строк и колонок, что удобно для вывода рекламных блоков, печатей или вертикальных надписей.
При использовании любого из методов присоединения справа (кроме метода с двумя документами), мы часто сталкиваемся с проблемой «разъезда» высоты строк. Чтобы отчет выглядел аккуратно, придерживайтесь следующих правил:
АвтоВысотаСтроки = Истина для областей в макете.Область(), заранее задайте ширину колонок в макете или программно через ТабДок.Область(, НомерКолонки).ШиринаКолонки = 20;.Объединить() для создания большой области под текст.Проанализировав все способы, можно сделать вывод: для большинства стандартных отчетов оптимально подходит Способ №1 (склейка двух документов), так как он наиболее прост в отладке и поддержке. Для интерактивных форм, где данные могут меняться динамически, лучше использовать Способ №3 с прямой адресацией ячеек R1C1.