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