Как программно вывести дополнительное поле на определенном уровне группировки в Построителе отчета?

Программист 1С v8.3 (Обычные формы) Управленческий учет IT и автоматизация бизнеса
← На главную

При разработке отчетов с использованием объекта ПостроительОтчета нередко возникает задача вывести дополнительную информацию (например, адрес хранения, штрихкод или артикул из регистра сведений) не в детальных записях самого нижнего уровня, а строго в строке определенной группировки — например, на уровне номенклатуры (ТМЦ). Разберем причины стандартного поведения платформы и практические варианты решения этой задачи.

Выясним причину поведения платформы

Проанализируем, как ПостроительОтчета распределяет поля по секциям:

  1. Разделение на измерения и реквизиты: Для построителя признаком принадлежности поля к измерению строки является путь к данным через точку от метаданных объекта (например, ТМЦ.ЕдиницаХраненияОстатков). Если поле получено из внешней таблицы или регистра через левое соединение (например, АдресХранения), платформа воспринимает его как отдельное поле выборки, а не свойство группировки ТМЦ.
  2. Размещение детальных полей: По умолчанию все неагрегированные поля детальных записей выводятся под последней (самой глубокой) группировкой строк отчета. Если в отчете настроены группировки «СчетУчета», «ТМЦ», «Партия», то детальное поле будет отображаться только внутри секции партий.
  3. Ограничения секции ИТОГИ: В отличие от Системы компоновки данных (СКД), где в ресурсах можно гибко указать «Рассчитывать по...», в классическом предложении ИТОГИ агрегатная функция (например, МИНИМУМ(АдресХранения)) рассчитывается платформой для всех уровней, перечисленных в предложении ПО, включая общие итоги и вышестоящие измерения («СчетУчета»).

Рассмотрим подробнее способы решения данной проблемы.

Способ 1. Программная постобработка сгенерированного макета

Наиболее прямолинейный и рабочий способ — сформировать макет построителя по умолчанию, после чего программно обойти области группировок, где вывод этого поля не требуется, и очистить соответствующие ячейки.

Посмотрим на пример процедуры очистки поля АдресХранения во всех строках измерений, кроме группировки ТМЦ:


Процедура ОформитьПолеАдресаХранения()
    
    // Инициализируем генерацию макета по умолчанию
    ПостроительОтчетаОстаткиТМЦНаСкладах.Макет = Неопределено;
    Макет = ПостроительОтчетаОстаткиТМЦНаСкладах.Макет;
    
    Для Каждого Группировка Из ПостроительОтчетаОстаткиТМЦНаСкладах.ИзмеренияСтроки Цикл 
        Если Группировка.ПутьКДанным = "ТМЦ" Тогда 
            // Пропускаем целевую группировку, на ее уровне поле должно остаться
            Продолжить; 
        Иначе 
            ИменаОбластей = Новый Массив; 
            ИменаОбластей.Добавить(Группировка.Имя); 
            ИменаОбластей.Добавить(Группировка.Имя + "Иерархия"); 
            
            Для Каждого ИмяГруппировки Из ИменаОбластей Цикл 
                Область = Макет.Области.Найти(ИмяГруппировки); 
                Если Область <> Неопределено Тогда 
                    ТекущаяОбласть = Неопределено; 
                    Пока Истина Цикл 
                        // Ищем вхождение параметра в пределах строки группировки
                        ТекущаяОбласть = Макет.НайтиТекст("АдресХранения", ТекущаяОбласть, Область, Истина, Истина, Истина, Ложь);
                        Если ТекущаяОбласть <> Неопределено Тогда 
                            Если ТекущаяОбласть.Параметр = "АдресХранения" Тогда 
                                // Очищаем значение ячейки
                                ТекущаяОбласть.Очистить(Истина, Ложь, Ложь);
                            КонецЕсли;
                        Иначе 
                            Прервать; 
                        КонецЕсли; 
                    КонецЦикла;
                КонецЕсли;
            КонецЦикла;
        КонецЕсли;
    КонецЦикла;
    
    // Присваиваем измененный табличный документ обратно в построитель
    ПостроительОтчетаОстаткиТМЦНаСкладах.Макет = Макет;    
    
КонецПроцедуры

Важный нюанс: Чтобы данный параметр вообще присутствовал в макете на уровне строк группировок, в тексте запроса построителя поле необходимо включить в блок ИТОГИ с агрегатной функцией (например, МИНИМУМ(АдресХранения)), а строковые поля обязательно типизировать с помощью ВЫРАЗИТЬ(... КАК СТРОКА(N)).

Способ 2. Использование измерения-сателлита

Разберем альтернативный метод без перебора областей макета. Если связь между ТМЦ и адресом хранения является однозначной («один к одному»), поле АдресХранения можно сделать дополнительным измерением строки.

  1. В запросе поле АдресХранения оставляем в секции ВЫБРАТЬ и добавляем его в СГРУППИРОВАТЬ ПО.
  2. В настройках построителя добавляем его в состав измерений строк сразу после номенклатуры:
    
    ПостроительОтчетаОстаткиТМЦНаСкладах.ИзмеренияСтроки.Добавить("СчетУчета");
    ПостроительОтчетаОстаткиТМЦНаСкладах.ИзмеренияСтроки.Добавить("ТМЦ");
    ПостроительОтчетаОстаткиТМЦНаСкладах.ИзмеренияСтроки.Добавить("АдресХранения");
    ПостроительОтчетаОстаткиТМЦНаСкладах.ИзмеренияСтроки.Добавить("Партия");
    
  3. Управляем отображением с помощью свойства:
    
    ПостроительОтчетаОстаткиТМЦНаСкладах.РазмещениеИзмеренийВСтроках = ТипРазмещенияИзмерений.Вместе;
    

При таком подходе значение поля выводится в одной строке рядом с наименованием ТМЦ и не дублируется на вышестоящих счетах и нижестоящих партиях.

Способ 3. Передача данных через ОписаниеИсточникаДанных

Если требуется строго штатное поведение реквизитов (использование свойств РазмещениеРеквизитовИзмеренийВСтроках и РазмещениеРеквизитовИзмеренийВКолонках), запрос можно выполнить отдельно, а построитель инициализировать через источник данных.

Проанализируем логику механизма:

  1. Выполняем запрос в промежуточную таблицу значений или выгружаем результат запроса.
  2. В результирующей структуре переименовываем колонку адреса, используя точечную нотацию: ТМЦ.АдресХранения.
  3. Передаем данные в построитель: ПостроительОтчета.ИсточникДанных = Новый ОписаниеИсточникаДанных(Результат);

При наличии точки в имени поля объект ОписаниеИсточникаДанных автоматически сопоставляет колонку как подчиненный реквизит соответствующего измерения (ТМЦ). В результате платформа сама помещает значение в строку номенклатуры согласно системным настройкам размещения реквизитов.

← На главную