Как программно настроить расшифровку в группировках и ресурсах отчета СКД

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

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

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

Почему стандартная расшифровка может не работать

Прежде чем переходить к коду, выясним причину проблемы. В СКД за расшифровку отвечает специальный объект ДанныеРасшифровкиКомпоновкиДанных. Когда отчет формируется, платформа сохраняет связь между каждой ячейкой табличного документа и идентификатором в этих данных расшифровки. Если поле является простым детальным полем, платформа легко находит ссылку. Однако, если поле представлено как ресурс (например, список заказов, свернутых в одну строку) или как группировка, стандартный механизм может «потеряться», так как в одной ячейке может потенциально содержаться несколько значений или агрегированные данные.

Шаг 1. Настройка элемента формы

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

  1. Откроем форму отчета в конфигураторе.
  2. Найдем на форме элемент типа ПолеТабличногоДокумента (обычно он называется Результат).
  3. В окне свойств этого элемента перейдем к списку События.
  4. Найдем событие ОбработкаРасшифровки и создадим для него обработчик на клиенте.

Именно этот обработчик позволит нам прервать стандартное поведение платформы и выполнить свой код.

Шаг 2. Реализация программного перехвата (Клиент-Серверный вариант)

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

Разберем клиентскую часть:


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

Теперь рассмотрим серверную функцию. Важно помнить, что данные расшифровки в управляемых формах хранятся во временном хранилище. Адрес этого хранилища обычно находится в реквизите формы ДанныеРасшифровки.


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

Шаг 3. Учет различий между полями и группировками

Проанализируем важный нюанс: объекты ЭлементРасшифровкиКомпоновкиДанныхПоля и ЭлементРасшифровкиКомпоновкиДанныхГруппировка ведут себя по-разному. Если вы нажимаете на значение в детальных записях, вы работаете с типом Поля. Если же вы кликаете по заголовку группировки, метод ПолучитьПоля() может быть недоступен или возвращать пустой массив.

Для работы с группировками (например, когда нужно открыть «Заказ», по которому сгруппированы строки) рекомендуется использовать метод ПолучитьИерархию(). Это позволит «подняться» выше по структуре данных и вытащить значение измерения группировки, даже если клик произошел в ячейке ресурса. Для этой задачи можно использовать пример отчета с получением значений группировок в обработчике расшифровки.

Альтернативный способ: Выражение расшифровки в схеме СКД

Существует еще один изящный способ настройки, который не требует написания сложного кода в модуле формы. Рассмотрим настройку Выражения расшифровки непосредственно в схеме СКД:

  1. Откроем Схему компоновки данных.
  2. Перейдем на закладку Наборы данных.
  3. Выберем нужное поле (например, «НомерЗаказа»).
  4. В колонке Выражение расшифровки укажем имя поля, содержащего ссылку (например, ЗаказСсылка).

В этом случае, даже если в ячейке отображается текст «Заказ №123», при клике платформа будет знать, что основным объектом расшифровки является ссылка на документ. Это самый простой способ «починить» расшифровку в ресурсах без программирования обработчиков событий.

Использование метода «ВыбратьДействие»

Если мы хотим сохранить стандартное меню (Группировать, Отфильтровать, Оформить), но при выборе пункта «Открыть» выполнить свою логику, нам поможет объект ОбработкаРасшифровкиКомпоновкиДанных. Посмотрим, как это выглядит в коде:


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

Подведем итоги

Мы рассмотрели несколько способов управления расшифровкой. Программный перехват через событие табличного документа дает максимальную гибкость, позволяя открывать любые связанные данные, даже если они не выведены в отчет напрямую. Использование Выражения расшифровки в настройках поля СКД — самый быстрый способ исправить поведение ссылок в ресурсах.

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

← На главную