При разработке отчетов на платформе 1С:Предприятие с использованием Системы компоновки данных (СКД) программисты часто сталкиваются с жесткими стандартными правилами вывода информации. По умолчанию СКД группирует все ресурсы в крайних правых колонках таблицы, а детальные записи и группировки выводит слева. Но что делать, если дизайн-макет требует иного расположения? Например, когда часть детальных сведений должна находиться слева, далее должны следовать числовые показатели (ресурсы), а справа — сопутствующая детальная информация (например, ответственные лица, цеха или статусы).
В этой статье мы подробно разберем четыре эффективных метода решения этой задачи: от простых манипуляций в настройках схемы компоновки до программного перехвата вывода и оптимизации структуры запроса для предотвращения зависания системы.
Рассмотрим самый быстрый способ изменить стандартное поведение СКД без написания кода и создания сложных макетов. Этот вариант идеально подходит, если структура вашего отчета линейная или представляет собой простую иерархию строк.
По умолчанию СКД автоматически сдвигает все ресурсы в конец строки (вправо). Чтобы управлять их положением вручную, выполним следующие шаги:
Номенклатура, Характеристика (детальные поля слева), затем ресурс Количество, а следом — поля Склад и Ответственный (детальные поля справа).Важное ограничение: данный метод прекрасно работает в простых плоских таблицах. Однако в сложных кросс-таблицах, где присутствуют динамические группировки колонок, этот механизм может скрывать общие итоги или выводить данные некорректно. В таких случаях перейдем к более гибким методам.
Проанализируем частую архитектурную ошибку разработчиков. На форуме автор упоминает, что пытался связать детальные записи с данными по цехам через связи наборов данных в СКД, что привело к нехватке памяти и зависанию системы. Это происходит из-за того, что СКД пытается выполнить соединения таблиц (аналог LEFT JOIN) в оперативной памяти компьютера пользователя или сервера приложений без использования индексов СУБД.
Чтобы избежать подобных проблем и одновременно получить возможность гибкой группировки, перенесем всю тяжелую логику обработки данных на уровень СУБД (в текст SQL-запроса) и настроим стандартную таблицу СКД.
Выясним причину зависания: если данные по цехам изначально хранятся в «плоском» виде (в виде отдельных колонок Цех1, Цех2 и так далее), то построить динамическую таблицу очень сложно. Нам необходимо транспонировать (развернуть) эти колонки в строки прямо в запросе с помощью объединения таблиц.
Посмотрим на пример такого запроса:
ВЫБРАТЬ
Продажи.Номенклатура КАК Изделие,
"Цех №1" КАК ИмяЦеха,
Продажи.ОбъемЦех1 КАК ЗначениеПоказателя
ИЗ
РегистрНакопления.Продажи КАК Продажи
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
Продажи.Номенклатура,
"Цех №2",
Продажи.ОбъемЦех2
ИЗ
РегистрНакопления.Продажи КАК Продажи
Теперь, когда данные нормализованы, мы можем легко настроить структуру таблицы в СКД:
Изделие, Характеристика).ИмяЦеха. Таким образом, цеха будут выводиться динамически справа от строк.ЗначениеПоказателя, который будет автоматически рассчитываться на пересечении строк и колонок.Если требования к оформлению отчета слишком специфичны и стандартными настройками СКД не обойтись, наиболее надежным решением станет пост-обработка сформированного табличного документа. Этот метод не нагружает оперативную память на этапе компоновки и позволяет реализовать абсолютно любую структуру вывода.
Для реализации этого метода переопределим процедуру ПриКомпоновкеРезультата в модуле объекта отчета. Разберем по шагам алгоритм работы:
СтандартнаяОбработка = Ложь.Посмотрим на пример программной реализации этого метода:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Получаем схему и настройки
СхемаКомпоновкиДанных = ПолучитьМакет("СхемаКомпоновкиДанных");
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
// Инициализируем макет компоновки
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
// Выполняем компоновку
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки, Истина);
// Выводим во временный документ
ВременныйТабДок = Новый ТабличныйДокумент;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ВременныйТабДок);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
// Алгоритм переноса колонок:
// Предположим, нам нужно перенести колонку 3 в конец таблицы (например, колонка 6)
ВсегоСтрок = ВременныйТабДок.ВысотаТаблицы;
Если ВсегоСтрок > 0 Тогда
Для СтрокаИндекс = 1 По ВсегоСтрок Цикл
// Получаем область ячейки, которую нужно перенести
ОбластьИсточник = ВременныйТабДок.Область(СтрокаИндекс, 3);
ОбластьПриемник = ВременныйТабДок.Область(СтрокаИндекс, 6);
// Копируем значение и оформление
ЗаполнитьЗначенияСвойств(ОбластьПриемник, ОбластьИсточник);
ОбластьПриемник.Текст = ОбластьИсточник.Текст;
// Очищаем старую ячейку
ОбластьИсточник.Очистить();
КонецЦикла;
// Удаляем теперь уже пустую исходную колонку
ВременныйТабДок.УдалитьОбласть(ВременныйТабДок.Область(, 3, , 3), ТипСмещенияТабличногоДокумента.ПоГоризонтали);
КонецЕсли;
// Копируем итоговый результат в выходной документ
ДокументРезультат.Вывести(ВременныйТабДок);
КонецПроцедуры
На форумах часто советуют использовать «Произвольный макет» (Создание собственного макета оформления). Однако у этого подхода есть существенный минус: разработчику приходится вручную описывать каждую ячейку, рамку и шрифт всего отчета, что крайне трудоемко. Но мало кто знает, что в СКД можно переопределить макет не для всего отчета, а только для конкретной группировки строк или колонок.
Рассмотрим подробнее, как переопределить макет только для шапки или детальных записей, сохранив автоматическую генерацию остальной части таблицы:
ДетальныеЗаписи) и тип макета (например, Заголовок или Тело).Параметры.ПолеСлева и Параметры.ПолеСправа), а средние ячейки будут отведены под ресурсы.Такой гибридный подход позволяет кастомизировать сложную часть таблицы (например, разделить данные на левую и правую стороны вокруг ресурсов), сохранив при этом все преимущества автоматического формирования итогов и расшифровок СКД в других частях отчета.