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