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