Как исправить ошибку «Значение не является значением объектного типа (Значение)» в отчетах 1С

Программист 1С v8.3 (Управляемые формы) Управленческий учет Торговля и дистрибуция
← На главную

При доработке и кастомизации типовых отчетов в современных конфигурациях 1С (таких как ERP, Комплексная автоматизация, Управление торговлей или отраслевых решениях на их базе) разработчики часто сталкиваются с крайне неприятной ошибкой: «Значение не является значением объектного типа (Значение)» или «Значение не является значением объектного типа (Использование)». Эта ошибка происходит на этапе формирования отчета и полностью блокирует вывод данных.

В этой статье мы подробно разберем, почему возникает данная проблема, рассмотрим внутренние механизмы работы компоновщика настроек в БСП (Библиотеке стандартных подсистем) и изучим три надежных способа ее решения.

---

Выясняем причину возникновения ошибки

Давайте проанализируем ситуацию. Предположим, мы работаем с типовым отчетом «Ведомость по товарам на складах в ценах номенклатуры». В оригинальном запросе схемы компоновки данных (СКД) присутствует жесткая привязка к одному параметру цены:

ЦеныНоменклатуры.ВидЦены = &ВидЦены

Перед нами стоит задача: изменить отчет таким образом, чтобы он выводил информацию одновременно по двум видам цен — например, оптовой и розничной. Мы заменяем один параметр в запросе на два новых: &ВидЦеныОптовая и &ВидЦеныРозничная. Наш код в запросе принимает следующий вид:


(((&ОценкаЗапасовПоВидуЦен = 3 И ЦеныНоменклатуры.ВидЦены = &ВидЦеныОптовая)
ИЛИ (&ОценкаЗапасовПоВидуЦен = 3 И ЦеныНоменклатуры.ВидЦены = &ВидЦеныРозничная)))

После сохранения схемы и запуска отчета мы получаем ту самую ошибку. Почему это происходит?

Дело в том, что типовые отчеты в современных конфигурациях управляются не только интерактивными настройками пользователя, но и жестким программным кодом. В модуле объекта отчета (чаще всего в предопределенном обработчике ПриКомпоновкеРезультата) или в недрах общих модулей БСП система пытается программно инициализировать и заполнить параметры СКД.

Программа «рассчитывает» на то, что структура параметров СКД неизменна. В коде это выглядит примерно так:


ПараметрВидЦены = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("ВидЦены");
ПараметрВидЦены.Значение = Справочники.ВидыЦен.НайтиПоНаименованию("Оптовая");
ПараметрВидЦены.Использование = Истина;

Когда мы убрали параметр &ВидЦены из текста запроса СКД, платформа 1С автоматически удалила его (или сделала недоступным) из коллекции параметров компоновщика настроек. В результате вызова метода Найти("ВидЦены") система возвращает пустое значение — Неопределено. На следующей строке, пытаясь обратиться к свойству Значение или Использование у переменной со значением Неопределено, платформа закономерно генерирует исключение: «Значение не является значением объектного типа».

---

Способ 1. Создание «фиктивного» параметра (Наиболее простой и безопасный путь)

Если мы не хотим переписывать сложный программный код общих модулей конфигурации (что особенно важно при сохранении базы на поддержке), мы можем применить небольшую хитрость. Нам нужно сделать так, чтобы параметр ВидЦены физически присутствовал в схеме компоновки данных, но не влиял на результат нашего запроса.

Разберем по шагам, как это реализовать:

  1. Откроем нашу измененную схему компоновки данных (СКД) в конструкторе.
  2. Перейдем на вкладку «Параметры».
  3. Добавим новый параметр вручную, нажав на кнопку «Плюс».
  4. Зададим ему имя в точности так, как ожидает система: ВидЦены.
  5. Укажем для него тип данных (например, СправочникСсылка.ВидыЦен).
  6. Обязательно установим флаг «Ограничение доступности». Это скроет данный параметр от конечного пользователя в настройках отчета, чтобы он не вносил путаницу.
  7. При этом наши новые рабочие параметры ВидЦеныОптовая и &ВидЦеныРозничная остаются в запросе и СКД в неизменном виде.

Как это работает: При формировании отчета типовой программный код успешно находит параметр ВидЦены в коллекции компоновщика, записывает в него данные и продолжает работу без ошибок. Наш измененный запрос игнорирует этот параметр и выбирает данные по новым переменным &ВидЦеныОптовая и &ВидЦеныРозничная.

---

Способ 2. Оптимизация запроса СКД через оператор «В» (Рекомендуемый)

Вместо создания кучи новых параметров мы можем переписать логику работы отчета более изящно. Зачем плодить параметры, если можно передавать список нужных видов цен в один стандартный параметр? Для этого перепишем наше условие в запросе, используя оператор множественного сравнения.

Посмотрим на пример изменения условия запроса:

(&ОценкаЗапасовПоВидуЦен = 3 И ЦеныНоменклатуры.ВидЦены В (&ВидЦены))

При таком подходе нам не нужно ломать структуру параметров компоновки:

  1. Параметр ВидЦены остается на месте. Программный код конфигурации успешно находит его и не выдает критических ошибок.
  2. На вкладке «Параметры» в СКД для параметра ВидЦены мы можем разрешить использование списка значений. Для этого убедимся, что тип параметра поддерживает коллекцию или не имеет жестких ограничений на одиночный выбор.
  3. В пользовательских настройках отчета теперь можно будет выбрать не один конкретный вид цены, а целый список (например, сразу «Оптовая» и «Розничная»).

Важное примечание: Этот способ идеально сработает, если типовой программный код принудительно не очищает настройки и не перезаписывает тип значения параметра ВидЦены на одиночную ссылку непосредственно перед выводом. Если код жестко выполняет приведение к типу одиночной ссылки, используйте Способ 1.

---

Способ 3. Обход компоновщика в модуле внешнего отчета

Если мы разрабатываем отчет как внешний (файл формата .erf), мы можем перехватить управление компоновкой непосредственно в коде модуля объекта самого отчета. Разберем, как это сделать в процедуре ПриКомпоновкеРезультата.

Проанализируем пример кода, который предотвратит падение системы:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // Отключаем стандартный вывод, если планируем управлять процессом вручную
    // СтандартнаяОбработка = Ложь;
    
    // Проверим наличие параметра в настройках компоновщика перед вызовом типовых процедур БСП
    ПараметрыДанных = КомпоновщикНастроек.Настройки.ПараметрыДанных;
    
    Если ПараметрыДанных.Элементы.Найти("ВидЦены") = Неопределено Тогда
        // Если параметр был удален из запроса, мы можем программно добавить его в коллекцию настроек,
        // чтобы предотвратить падение общего кода БСП
        НовыйПараметр = ПараметрыДанных.Элементы.Добавить();
        НовыйПараметр.Параметр = Новый ПараметрКомпоновкиДанных("ВидЦены");
        НовыйПараметр.Использование = Ложь;
    КонецЕсли;
    
    // Вызываем типовой механизм формирования отчета БСП
    // ВариантыОтчетов.ПриКомпоновкеРезультата(ЭтотОбъект, ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка);

КонецПроцедуры

Этот способ позволяет гарантировать стабильность работы отчета даже в том случае, если структура метаданных или логика запроса СКД претерпела значительные изменения, а отчет должен оставаться внешним и не требовать изменения основной конфигурации.

---

Резюме

Мы выяснили, что ошибка «Значение не является значением объектного типа» в отчетах 1С практически всегда связана с несоответствием структуры параметров в СКД и ожиданий программного кода, управляющего отчетом. Использование «фиктивных» параметров (Способ 1) или переход к оператору В для работы со списками значений (Способ 2) позволяют решить эту задачу быстро, красиво и безболезненно для последующих обновлений системы.

← На главную