Почему возникает ошибка «Значение не является значением объектного типа» при копировании записей регистра накопления?

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

При программном переносе или копировании записей из одного регистра накопления в другой разработчики часто сталкиваются с ошибкой выполнения «Значение не является значением объектного типа». Разберем детально, почему возникает данное исключение, какие типичные синтаксические и архитектурные ошибки допускаются при работе с наборами записей, и как правильно переносить движения между регистрами.

Причина ошибки: неинициализированная переменная и проверка системных типов

Проанализируем фрагмент кода, вызвавший ошибку:


Если ДвСклада.ВидДвижения = "Приход" Тогда 
    Движения = ДвОгранизации.ДобавитьПриход; 
КонецЕсли; 
Если ДвСклада.ВидДвижения = "Расход" Тогда 
    Движения = ДвОгранизации.ДобавитьРасход; 
КонецЕсли;

Движения.ВидДвижения = ДвСклада.ВидДвижения;

Разберем по шагам, что здесь происходит:

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

Сопутствующие синтаксические ошибки при работе с объектами 1С

Посмотрим на другие типичные ошибки в коде работы с набором записей:

  1. Отсутствие круглых скобок при вызове методов: обращения вроде НовЗапрос.Выполнить, Выборка.Выбрать, СоздатьНаборЗаписей и ДобавитьПриход без скобок возвращают сам программный объект метода, а не результат его выполнения. Вызовы функций и процедур в 1С обязательно требуют скобок: НовЗапрос.Выполнить(), Выборка.Выбрать().
  2. Методы набора записей: у объекта РегистрНакопленияНаборЗаписей нет методов ДобавитьПриход() и ДобавитьРасход(). Добавление новой строки выполняется через метод ДвОрганизации.Добавить(), который возвращает объект РегистрНакопленияЗапись.
  3. Избыточность проверки вида движения: так как оба регистра оперируют одним и тем же системным перечислением ВидДвиженияНакопления, нет необходимости проверять тип движения через ветвление — достаточно напрямую присвоить значение: НоваяЗапись.ВидДвижения = Выборка.ВидДвижения;.
  4. Опечатки в именах свойств: обращение к несуществующему реквизиту (например, Движения.Количеств вместо Движения.Количество) приведет к ошибке отсутствия реквизита при компиляции или записи набора.

Особенности платформы: обязательность отбора по регистратору

Все регистры накопления в типовых конфигурациях (включая «Управление торговлей 10») являются подчиненными регистратору. Это накладывает строгое системное ограничение:

Один набор записей может принадлежать только одному документу-регистратору. Попытка записать набор без предварительной установки отбора по полю Регистратор вызовет системную ошибку платформы при вызове метода Записать().

Если необходимо перенести движения по множеству документов, обработку данных нужно сгруппировать по каждому регистратору отдельно.

Правильный алгоритм переноса движений между регистрами

Рассмотрим правильный пример обработки, которая выбирает движения исходного регистра и корректно перезаписывает их в целевой регистр с разбивкой по регистраторам:


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

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

Методические рекомендации для конфигурации УТ 10

Выясним важные учетные нюансы при прямой модификации движений:

  1. Связь с партионным учетом: в конфигурациях линейки «Управление торговлей» регистр ТоварыОрганизаций тесно связан с регистрами партий (например, ПартииТоваровНаСкладах). Ручное или прямое программное изменение записей без корректировки партий может привести к расхождению остатков и невозможности провести документы списания по регламентированному учету.
  2. Использование типовых документов: вместо прямой перезаписи движений через РегистрНакопленияНаборЗаписей безопаснее формировать типовой документ КорректировкаЗаписейРегистров либо выполнять ввод документов ОприходованиеТоваров / СписаниеТоваров, что сохранит ссылочную целостность и историю изменений в информационной базе.
← На главную