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

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

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

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

Давайте проанализируем ситуацию, описанную в теме. Программист пытается найти строку в табличной части дополнительных реквизитов объекта Номенклатура по ссылке на свойство. Ошибка происходит на строке присвоения значения:

ДопРек1.Значение = Строка.КодВБ;

Система сообщает, что ДопРек1 не является объектом. Это происходит потому, что метод Найти(), использованный ранее, не обнаружил подходящей строки в табличной части и вернул стандартное значение Неопределено. Пытаясь обратиться к свойству Значение через точку от Неопределено, мы закономерно получаем исключение.

Почему строки может не быть в табличной части? Рассмотрим основные причины:

  1. Новый объект или отсутствие данных: Если для конкретной позиции номенклатуры этот реквизит еще ни разу не заполнялся в интерфейсе, то строки с этим свойством в базе данных физически не существует.
  2. Наборы свойств: Дополнительный реквизит может быть создан в системе, но он не включен в «Набор свойств», к которому привязана данная номенклатура (например, реквизит относится к одежде, а мы редактируем обувь).
  3. Поиск по наименованию: Использование метода НайтиПоНаименованию для поиска самого свойства (ПВХ) может вернуть пустую ссылку, если наименование указано с ошибкой или в базе есть дубли.

Решение №1. Классический алгоритм «Найти или Создать»

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

Вместо прямого присвоения мы должны реализовать следующую логику:

  1. Найти строку в табличной части ДополнительныеРеквизиты.
  2. Проверить, не равна ли переменная значению Неопределено.
  3. Если строка не найдена — добавить новую строку методом Добавить() и установить в ней свойство.
  4. Присвоить значение.

Пример исправленного кода:


// Сначала получаем ссылку на свойство (лучше не по наименованию)
Парам1 = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Код для WB");

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

Решение №2. Использование механизмов БСП (рекомендуемое)

В современных конфигурациях (таких как УТ 11, ERP 2, КА 2 или БП 3.0), построенных на базе Библиотеки стандартных подсистем (БСП), прямое редактирование табличной части через ПолучитьОбъект() считается «плохим тоном». Это может привести к нарушению логики работы кэша свойств или записи некорректных типов данных.

Проанализируем преимущества использования общего модуля УправлениеСвойствами. Программный интерфейс этой подсистемы позволяет записывать значения дополнительных реквизитов одной командой, не заботясь о поиске или создании строк.

Рассмотрим пример использования функции для записи значений:


// Подготовим структуру со значениями реквизитов
СвойстваДляЗаписи = Новый Структура;
СвойстваДляЗаписи.Вставить(Парам1, Строка.КодВБ);

// Используем метод БСП для записи в объект
// Это автоматически создаст нужные строки и проверит типы
УправлениеСвойствами.ЗаписатьЗависимыеРеквизиты(НашаНоменклатура.Ссылка, СвойстваДляЗаписи);

Важно: Методы БСП сами заботятся о проверке типов. Если ваш доп. реквизит имеет тип «Число», а вы передаете строку, БСП может выдать ошибку или корректно преобразовать данные, в зависимости от версии.

Оптимизация производительности и важные нюансы

Посмотрим на ситуацию шире. Если вы выполняете загрузку данных (например, из Excel или по API маркетплейса) для тысяч позиций номенклатуры, постоянный вызов Записать() в цикле существенно замедлит работу системы.

Рассмотрим несколько советов по оптимизации:

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


Если ПустаяСтрока(Строка.КодВБ) Тогда
    СтрокаДляУдаления = НашаНоменклатура.ДополнительныеРеквизиты.Найти(Парам1, "Свойство");
    Если СтрокаДляУдаления <> Неопределено Тогда
        НашаНоменклатура.ДополнительныеРеквизиты.Удалить(СтрокаДляУдаления);
    КонецЕсли;
Иначе
    // Логика добавления/изменения, описанная выше
КонецЕсли;

Подведем итоги

Мы выяснили, что ошибка «Значение не является значением объектного типа» в данном контексте — это лишь следствие отсутствия данных в табличной части. Чтобы ваш код был надежным, всегда учитывайте возможность отсутствия строки в коллекции. Используйте проверку на Неопределено при ручной обработке или доверьте эту работу механизмам УправлениеСвойствами из состава БСП, что является наиболее современным и правильным подходом в разработке на платформе 1С:Предприятие 8.3.

← На главную