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