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