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