Как получить значение расшифровки по номенклатуре в Построителе отчетов 1С?

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

При работе со старыми типовыми конфигурациями (такими как Управление производственным предприятием 1.3, Управление торговлей 10.3 или Комплексная автоматизация 1.1) разработчики часто сталкиваются с механизмом «Универсального отчета», построенного на базе технологического объекта ПостроительОтчета. Этот объект во многом уступает современной Системе компоновки данных (СКД), однако он все еще активно поддерживается и эксплуатируется во многих корпоративных информационных системах.

Типичная проблема, с которой сталкиваются программисты при кастомизации таких отчетов: непонимание того, в какой момент и каким образом ссылка на конкретный объект (например, Номенклатуру) передается в механизм расшифровки и как перехватить это значение программно для реализации собственной логики.

В этой статье мы подробно разберем внутреннюю кухню работы расшифровки Построителя отчетов, выясним назначение ключевых свойств и методов, а также научимся перехватывать и модифицировать эти данные на практических примерах.

Как платформа 1С передает ссылки в расшифровку

Когда ПостроительОтчета выводит результат запроса в табличный документ, за автоматическое формирование расшифровки отвечает свойство объекта: ПостроительОтчета.ЗаполнениеРасшифровки.

Для этого свойства может быть установлено одно из значений системного перечисления ВидЗаполненияРасшифровкиПостроителяОтчета. В универсальных отчетах практически всегда используется значение Расшифровка. Разберем подробнее, что это значит:

  1. Платформа автоматически анализирует выводимые группировки. Если в строке отчета выводится группировка по полю «Номенклатура», платформа связывает эту ячейку со специальной структурой данных.
  2. Формируется объект типа Структура. В качестве ключей этой структуры выступают псевдонимы полей из текста запроса Построителя (например, "Номенклатура", "Склад", "ХарактеристикаНоменклатуры"), а значениями становятся конкретные ссылки из базы данных для текущей строки (например, СправочникСсылка.Номенклатура).
  3. Структура помещается в свойство Расшифровка ячейки. При этом в отличие от СКД, где в ячейке хранится только числовой идентификатор, Построитель отчетов записывает саму структуру непосредственно в свойство Расшифровка области ячеек табличного документа.

Таким образом, когда пользователь производит двойной клик по ячейке с количеством или номенклатурой, процедура-обработчик расшифровки на клиенте получает эту структуру «как есть».

Перехват расшифровки в коде формы отчета

Давайте посмотрим на стандартный шаблон обработки этого события в формах универсальных отчетов. На форме отчета всегда располагается элемент управления «Поле табличного документа» (обычно с именем ПолеТабличногоДокументаРезультат). У этого поля определено событие ОбработкаРасшифровки.

Разберем типичный код этого обработчика:


Процедура ПолеТабличногоДокументаРезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)
    
    // Отключаем стандартный диалог расшифровки платформы
    СтандартнаяОбработка = Ложь;
    
    // Передаем управление в процедуру модуля отчета
    ОбработкаРасшифровки(Расшифровка, ОтчетОбъект);
    
КонецПроцедуры

В процедуре модуля отчета (или общем модуле, если используется типовой механизм универсального отчета) управление передается дальше:


Процедура ОбработкаРасшифровки(Расшифровка, Объект) Экспорт
    
    ДополнительныеПараметры = Неопределено;
    УниверсальныйОтчет.ОбработкаРасшифровкиУниверсальногоОтчета(Расшифровка, Объект, ДополнительныеПараметры);
    
КонецПроцедуры

Если мы остановим выполнение программы отладчиком внутри этой процедуры, то увидим, что параметр Расшифровка содержит коллекцию значений — Структура. Мы можем легко прочитать любое значение по имени поля:


Если ТипЗнч(Расшифровка) = Тип("Структура") Тогда
    
    // Проверим, есть ли в структуре расшифровки нужный нам аналитический разрез
    Если Расшифровка.Свойство("Номенклатура") Тогда
        ВыбраннаяНоменклатура = Расшифровка.Номенклатура;
        // Здесь мы можем открыть форму элемента или выполнить дополнительный расчет
        Предупреждение("Вы выбрали номенклатуру: " + Строка(ВыбраннаяНоменклатура));
    КонецЕсли;
    
КонецЕсли;

Магия сопоставления: как "ПутьКДанным" попадает в отбор нового отчета

Очень часто у разработчиков возникает резонный вопрос: "Я вижу структуру расшифровки, но где в коде происходит сопоставление этой структуры с отборами нового (детализирующего) отчета?"

Этот процесс скрыт внутри платформенного метода, который вызывается в недрах общего модуля УниверсальныйОтчет. Имя этого метода:


ПостроительОтчета.НастроитьРасшифровку(<НастраиваемыйПостроитель>, <Расшифровка>)

Рассмотрим детально алгоритм, который выполняет платформа 1С при вызове этого метода под капотом:

  1. Метод принимает в качестве первого параметра объект ПостроительОтчета нового отчета, который мы собираемся открыть для детализации.
  2. Второй параметр — это наша структура Расшифровка, полученная из ячейки исходного отчета.
  3. Платформа полностью очищает все пользовательские настройки отборов в настраиваемом построителе.
  4. Платформа автоматически обходит все ключи переданной структуры расшифровки.
  5. Для каждого ключа (например, "Номенклатура") производится поиск одноименного доступного поля в настройках отбора настраиваемого построителя отчетов.
  6. Если соответствие найдено, платформа автоматически создает новый элемент отбора, устанавливает вид сравнения в значение Равно (или В иерархии, если поле представляет собой иерархический справочник) и присваивает значению отбора ссылку из структуры расшифровки.

Именно поэтому вы не найдете в программном коде явного добавления элементов в коллекцию ПостроительОтчета.Отбор. Вся рутинная работа по сопоставлению типов данных и путей к данным делегирована платформе 1С.

Особенности и подводные камни при работе с расшифровкой

Несмотря на кажущуюся простоту, при работе с расшифровкой в Построителе отчетов следует помнить о нескольких важных нюансах:

1. Обработка значений NULL.
Если в исходном запросе Построителя отчетов используются левые соединения, в полях группировок могут оказаться значения типа Null. При попытке выполнить метод НастроитьРасшифровку() с такими значениями в структуре расшифровки платформа может отработать некорректно или выдать ошибку времени выполнения. Мы рекомендуем обрабатывать такие поля на уровне запроса с помощью функции ЕСТЬNULL(), заменяя их на пустые ссылки соответствующих типов.

2. Ручная модификация структуры перед вызовом стандартного механизма.
Поскольку Расшифровка — это обычная структура, мы можем программно вмешиваться в процесс открытия нового отчета. Например, мы можем принудительно добавить в нее дополнительные параметры фильтрации или переопределить существующие до того, как управление будет передано в общий модуль:


Процедура ОбработкаРасшифровки(Расшифровка, Объект) Экспорт
    
    Если ТипЗнч(Расшифровка) = Тип("Структура") Тогда
        // Принудительно устанавливаем отбор по конкретной организации,
        // даже если пользователь кликнул по строке без этой группировки
        Расшифровка.Вставить("Организация", Объект.Организация);
    КонецЕсли;
    
    ДополнительныеПараметры = Неопределено;
    УниверсальныйОтчет.ОбработкаРасшифровкиУниверсальногоОтчета(Расшифровка, Объект, ДополнительныеПараметры);
    
КонецПроцедуры

3. Отличие от Системы компоновки данных (СКД).
Помните, что данный механизм специфичен исключительно для ПостроителяОтчета. В СКД расшифровка работает принципиально иначе: вместо передачи структур данных напрямую в ячейки, СКД генерирует числовые идентификаторы, которые ссылаются на объект типа ДанныеРасшифровкиКомпоновкиДанных, хранящийся во временном хранилище. Не пытайтесь применять методы Построителя при работе с отчетами на СКД.

← На главную