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