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