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