Как исправить ошибку «Значение не представляет агрегатный объект (Идентификатор)» при программном проведении документа в 1С 7.7?

Программист 1С v7.7 1С:Комплексная автоматизация Управленческий учет IT и автоматизация бизнеса
← На главную

При программном создании, заполнении и проведении документов в типовых конфигурациях платформы «1С:Предприятие 7.7» (таких как «Комплексная конфигурация 4.5» или «Торговля и склад 9.2») разработчики часто сталкиваются с ошибкой времени выполнения:

{Глобальный модуль(8846)}: Значение не представляет агрегатный объект (Идентификатор)

Разберем причины возникновения этой ситуации, проанализируем поведение платформы 7.7 и рассмотрим по шагам правильный способ программного заполнения строк табличной части документов.

Анализ проблемы и механизма работы платформы 1С 7.7

Проанализируем контекст ошибки. В глобальном модуле при проведении документа вызывается функция определения статуса партии:


Функция глПолучитьСтатусПартииПрихода(ВидТМЦ, Номенклатура, КодОперации, Склад = 0) Экспорт
    // ...
    Иначе // продукция или полуфабрикаты     
        Статус = глСП.ЗначениеПоИдентификатору(ВидТМЦ.Идентификатор());
    КонецЕсли;
    Возврат Статус;
КонецФункции

Ошибка возникает из-за того, что переменная ВидТМЦ оказывается пустой или содержит не агрегатный объект (не значение перечисления), в результате чего вызов метода Идентификатор() приводит к аварийному завершению транзакции.

Выясним причину, почему реквизит оказывается незаполненным, даже если разработчик пытается передать туда значение:

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

Пошаговое решение проблемы

Для корректного заполнения табличной части документа необходимо выполнить два обязательных действия:

  1. Явно назначить тип колонке табличной части с помощью метода НазначитьТип().
  2. Присвоить реквизиту ВидСтатус нужное значение из метаданных перечисления ВидыТМЦ.

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


Функция ЗаполнитьВозвратОтПокупателя(Док, ОснДок)
    
    Док.ДатаДок = ОснДок.ДатаДок;
    Док.ЮрЛицо = Док.Фирма.ЮрЛицо;
    Док.Проект = ОснДок.Проект;
    Док.Автор = ОснДок.Автор;
    Док.Комментарий = "Возврат товара с филиала (торговой точки)";
    Док.ДокОснование = ОснДок.ТекущийДокумент();
    Док.Валюта = глРубли;
    Док.Курс = 1;
    Док.Кратность = 1;
    
    Спр = СоздатьОбъект("Справочник.Номенклатура");
    Если Спр.НайтиПоНаименованию("Товары в ассортименте", 0, 1) = 0 Тогда
        Сообщить("Не найдена номенклатура ""Товары в ассортименте""!");
        Возврат 0;
    КонецЕсли;
    ТовВАсрт = Спр.ТекущийЭлемент();
    
    ВрТЗ = СоздатьОбъект("ТаблицаЗначений");
    ОснДок.ВыгрузитьТабличнуюЧасть(ВрТЗ);
    
    ВрТЗ.ВыбратьСтроки();
    Пока ВрТЗ.ПолучитьСтроку() = 1 Цикл
        ВрТЗ.РозничнаяЦена = ВрТЗ.РозничнаяЦена * ВрТЗ.Количество;
    КонецЦикла;
    
    ВрТЗ.Свернуть("СтавкаНДС,СтавкаНП", "Сумма,СуммаНДС,СуммаНП,РозничнаяЦена");
    
    Док.УдалитьСтроки();
    
    // Обязательно назначаем тип реквизиту табличной части перед записью
    Док.НазначитьТип("ВидСтатус", "Перечисление.ВидыТМЦ");
    
    ВрТЗ.ВыбратьСтроки();
    Пока ВрТЗ.ПолучитьСтроку() = 1 Цикл    
        Док.НоваяСтрока();
        
        Док.Номенклатура = ТовВАсрт;
        // Заполняем реквизит текущей строки документа
        Док.ВидСтатус = Перечисление.ВидыТМЦ.Товар;
        
        Док.Количество = 1;
        Док.Единица = Док.Номенклатура.БазоваяЕдиница;
        Док.Коэффициент = 1;        
        Док.Сумма = ВрТЗ.РозничнаяЦена;
        Док.Цена = ?(Док.Количество = 0, 0, Док.Сумма / Док.Количество);
        
        // Вызываем типовой пересчет реквизитов строки
        глПересчетТаблЧасти(Док, "РозничнаяЦена");
    КонецЦикла;
    
    Возврат 1;
КонецФункции

Особенности использования методов типизации в 1С 7.7

Рассмотрим подробнее правила работы с типизацией реквизитов платформы 1С 7.7:

  1. Метод НазначитьТип(<ИмяРеквизита>, <ИмяТипа>) применяется исключительно к тем полям шапки или табличной части, у которых в конфигураторе установлен базовый тип «Неопределенный». Если тип реквизита в метаданных жестко задан (например, «Справочник.Номенклатура»), вызов данного метода вызовет ошибку.
  2. Не следует путать метод НазначитьТип с методом НазначитьВид(<Реквизит>, <ИмяВида>). Метод НазначитьВид применяется тогда, когда базовый тип уже известен (например, «Справочник» или «Документ»), но не определен его конкретный вид. Для реквизитов с типом «Неопределенный» необходимо использовать строго НазначитьТип.
  3. Если реквизиту с неопределенным типом требуется присвоить строковое значение, платформе необходимо явно передать длину строки в третьем параметре метода НазначитьТип("Реквизит", "Строка", 50). В противном случае платформа ограничит длину строки 23 символами.

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

← На главную