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

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

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

Причины возникновения ошибки

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

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

Способ 1. Корректное использование метода ИспользоватьДату

Рассмотрим первый подход. Если в модуле для позиционированного объекта справочника уже задана рабочая дата с помощью ИспользоватьДату, обращаться к периодическому реквизиту нужно напрямую, без вызова метода Получить.

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


// Устанавливаем дату для объекта справочника
СпрЦена1.ИспользоватьДату(ДатаДок, 1);

// Прямое чтение значения периодического реквизита на установленную дату
Если Число(ЦенаИзФайла) > СпрЦена1.Цена Тогда
    // Прямая запись нового значения на установленную дату
    СпрЦена1.Цена = Число(ЦенаИзФайла);
    СпрЦена1.Записать();
КонецЕсли;

Обратите внимание: второй параметр метода ИспользоватьДату(ДатаДок, 1) указывает режим записи периодических реквизитов при вызове метода Записать(). Значение 1 означает, что изменения будут записаны именно на указанную дату.

Способ 2. Использование метода Получить без установки даты объекту

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

Посмотрим на пример:


// Справочник позиционирован через поиск, ИспользоватьДату не вызывался
Если СпрЦена.НайтиПоРеквизиту("ТипЦен", ВыбТипЦен, 0) = 1 Тогда
    // Получение значения цены на определенную дату
    ТекущаяЦена = СпрЦена.Цена.Получить(ДатаДок);
    
    Если ТекущаяЦена > 0 Тогда
        Сообщить("Актуальная цена: " + ТекущаяЦена);
    КонецЕсли;
КонецЕсли;

Важно помнить: метод Спр.Реквизит.Установить(Дата, Значение) можно использовать только для уже существующих и записанных элементов справочника. Если создается новый элемент через Спр.Новый(), его периодические реквизиты следует заполнять исключительно через метод ИспользоватьДату(Дата, 1) перед вызовом Спр.Записать().

Способ 3. Универсальная работа через системный объект «Периодический»

Наиболее надежным и универсальным способом чтения и пакетной записи периодических реквизитов является использование системного объекта Периодический. Этот способ исключает конфликты с текущим состоянием выборки или установленной датой справочника.

Разберем по шагам, как прочитать и записать значение с помощью объекта Периодический:


// Создаем объект для работы с периодическими данными
ОбъектПериодика = СоздатьОбъект("Периодический");

// Привязываем объект к конкретному периодическому реквизиту элемента
ОбъектПериодика.ИспользоватьОбъект("Цена", СпрЦена.ТекущийЭлемент);

// Чтение значения на заданную дату
ЦенаНаДату = ОбъектПериодика.ПолучитьЗначение(ДатаДок);

// Запись нового значения на дату
ОбъектПериодика.ДатаЗнач = ДатаДок;
ОбъектПериодика.Значение = НоваяЦена;
ОбъектПериодика.Записать();

Оптимизация алгоритма при загрузке данных

Выясним типичные ошибки структуры кода при пакетной загрузке позиций (например, из файлов Excel):

  1. Лишний вызов ВыбратьЭлементы() перед поиском. Метод НайтиПоРеквизиту самостоятельно выполняет поиск и позиционирование курсора. Вызов выборки перед точечным поиском избыточен.
  2. Повторное считывание данных из COM-объектов. Чтение ячеек Excel через COM-соединение работает медленно. Рекомендуется один раз прочитать значение ячейки в локальную переменную и затем использовать её во всех сравнениях и расчетах.
  3. Проверка результата поиска. Всегда проверяйте результат выполнения функций НайтиПоРеквизиту, НайтиПоКоду или НайтиПоНаименованию (они возвращают 1 при успехе и 0 при отсутствии элемента), прежде чем обращаться к реквизитам найденного объекта.
← На главную