К статье
Практический материал

Разработка и Конфигурация · 9 мин

1С 7.7: как получить значение периодического реквизита

Как в 1С 7.7 получить значение периодического реквизита: методы Получить, ИспользоватьДату, работа с ПереборЗначений, типичные ошибки и проверка результата.

Периодический реквизит в 1С 7.7 — это реквизит справочника (или константа), значение которого хранится с привязкой к дате и может меняться во времени. Классический пример — цена товара, оклад сотрудника, ставка НДС у номенклатуры. В отличие от обычного реквизита, простое обращение через точку не всегда даёт нужный результат: платформа вернёт значение либо на текущую дату, либо на дату, заданную методом ИспользоватьДату().

Основная задача разработчика — корректно указать дату, на которую нужно получить значение, и правильно выбрать метод доступа. Ошибки здесь типичны: запрос возвращает устаревшую цену, отчёт показывает оклад не на дату документа, а на сегодня, а при переборе истории теряются промежуточные значения.

Ниже разобраны рабочие способы получения периодического реквизита: через метод Получить(), через позиционирование объекта на дату, перебор истории значений и получение значения в запросах. Все примеры приведены на встроенном языке 1С 7.7.

Что такое периодический реквизит и как он хранится

При редактировании справочника в конфигураторе у реквизита можно установить флаг «Периодический». После этого значение сохраняется не одно на элемент, а целая история: каждая пара «дата — значение» записывается отдельно. При смене значения пользователем старое не затирается, а остаётся в истории.

Физически история хранится в таблице значений периодических реквизитов, привязанной к элементу справочника. Платформа при обращении к реквизиту ищет запись с максимальной датой, не превышающей заданную. Это важно: если вы запрашиваете значение на 15 марта, а последнее изменение было 10 марта, вернётся значение от 10 марта. Если изменений до запрошенной даты не было вовсе — реквизит вернёт пустое значение.

Способ 1. Метод Получить() с указанием даты

Самый прямой способ — вызвать метод Получить() у объекта типа «Справочник» и передать дату. Метод возвращает значение периодического реквизита, актуальное на эту дату, не меняя текущего позиционирования объекта по дате.

Пример: получить цену товара на дату документа.

СпрТов = СоздатьОбъект("Справочник.Товары");

Если СпрТов.НайтиПоКоду(КодТовара) = 1 Тогда

ЦенаНаДату = СпрТов.Цена.Получить(ДатаДокумента);

Сообщить("Цена на " + ДатаДокумента + " = " + ЦенаНаДату);

КонецЕсли;

Обратите внимание на синтаксис: Получить() вызывается у самого периодического реквизита, а не у объекта справочника. Запись СпрТов.Получить() — ошибка, у объекта такого метода нет. Если реквизит не периодический, метод Получить() для него недоступен.

1c
Значение = Спр.Реквизит.Получить(НужнаяДата);

Способ 2. ИспользоватьДату() и прямое обращение

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

СпрСотр = СоздатьОбъект("Справочник.Сотрудники");

СпрСотр.ИспользоватьДату(ДатаОтчета);

СпрСотр.ВыбратьЭлементы();

Пока СпрСотр.ПолучитьЭлемент() = 1 Цикл

Сообщить("" + СпрСотр.Наименование + " — оклад: " + СпрСотр.Оклад);

КонецЦикла;

Этот способ удобен, когда нужно прочитать несколько периодических реквизитов сразу на одну дату — например, оклад и должность сотрудника. Не придётся вызывать Получить() для каждого реквизита отдельно.

Важное ограничение: ИспользоватьДату() действует на весь объект. Если после него понадобится значение на другую дату, дату нужно переустановить. Также метод влияет на выборку элементов — если забыть, что дата установлена, можно получить неожиданные значения в дальнейшем коде.

Сравнение способов

Реквизит.Получить(Дата)

Точечное чтение одного реквизита на дату. Не меняет состояние объекта, безопасен в циклах с разными датами.

ИспользоватьДату(Дата)

Удобен при чтении нескольких периодических реквизитов на одну дату. Требует аккуратности: дата действует на весь объект до отмены.

ВыбратьЗначения()

Перебор всей истории изменений реквизита. Нужен для отчётов по истории, а не для получения одного значения.

Перебор всей истории значений

Если нужна не одна дата, а вся история изменений — например, построить отчёт о динамике цен — используют методы ВыбратьЗначения() и ПолучитьЗначение() периодического реквизита. При переборе доступны дата и значение каждой записи.

СпрТов.НайтиПоКоду(КодТовара);

СпрТов.Цена.ВыбратьЗначения();

Пока СпрТов.Цена.ПолучитьЗначение() = 1 Цикл

Сообщить("С " + СпрТов.Цена.ДатаЗнач + " цена = " + СпрТов.Цена.Значение);

КонецЦикла;

Атрибут ДатаЗнач содержит дату установки значения, Значение — само значение. Записи перебираются в хронологическом порядке. Если истории нет, цикл просто не выполнится ни разу — это нормальная ситуация, а не ошибка.

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

Периодические реквизиты в запросах

В запросах 1С 7.7 периодические реквизиты обрабатываются особо. Если запрос строится без указания даты, значения периодических реквизитов берутся на рабочую дату информационной базы. Чтобы получить значения на конкретную дату, её задают в тексте запроса конструкцией обработки периода либо запрос выполняют объектом «Запрос» с установленной датой.

ТекстЗапроса =

"Период с НачДата по КонДата;

|Товар = Справочник.Товары.ТекущийЭлемент;

|Цена = Справочник.Товары.Цена;

|Группировка Товар;";

На практике надёжнее получать значения периодических реквизитов внутри цикла обхода результатов запроса методом Получить() — так поведение прозрачнее и не зависит от нюансов настройки периода запроса. Для больших выборок это медленнее, но предсказуемее.

Типичные ошибки и как их избежать

Самая частая ошибка — чтение реквизита без указания даты там, где нужна дата документа. Отчёт по продажам за прошлый месяц покажет текущие цены, а не исторические. Всегда явно передавайте дату документа или дату отчёта.

Вторая ошибка — получение пустого значения и его трактовка как «ноль» или «отсутствие цены». Пустое значение чаще означает, что на запрошенную дату история ещё не началась: первое значение установлено позже. Проверяйте дату первой записи истории, прежде чем делать выводы.

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

Типичные ошибки
01
Чтение реквизита без даты — получаете значение на рабочую дату вместо даты документа
02
Вызов Получить() у объекта вместо реквизита — синтаксическая ошибка, метод есть только у периодического реквизита
03
Интерпретация пустого значения как нуля — на самом деле история на эту дату ещё не началась
04
Забытый ИспользоватьДату() — все последующие обращения читаются на устаревшую дату
05
Ожидание значения на дату раньше первой записи истории — таких данных в базе нет

Проверка результата

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

Контрольные точки

Как проверить результат

Значение на дату документа
Норма

Совпадает со значением в истории реквизита на эту дату

Тревожный признак

Возвращается текущее значение при запросе старой даты — дата не передана

Пустое значение
Норма

В истории нет записей с датой не позже запрошенной

Тревожный признак

Записи есть, но значение пустое — проверьте правильность имени реквизита

Перебор истории
Норма

Количество итераций равно числу записей в истории

Тревожный признак

Цикл не выполняется при заполненной истории — проверьте, что найден элемент справочника

FAQ

Как получить значение периодического реквизита на текущую дату?

Достаточно обратиться к реквизиту напрямую: Спр.Реквизит. Платформа вернёт значение на рабочую дату информационной базы. Учтите, что рабочая дата может отличаться от календарной — проверьте её через РабочаяДата().

Почему Получить(Дата) возвращает пустое значение?

Наиболее вероятная причина — на запрошенную дату история ещё не началась: первая запись имеет более позднюю дату. Переберите историю через ВыбратьЗначения() и посмотрите дату первой записи. Также проверьте, что элемент справочника действительно найден.

Можно ли получить периодический реквизит у несохранённого элемента?

Нет. История периодических реквизитов привязана к записанному элементу справочника. Сначала вызовите Записать(), затем устанавливайте и читайте периодические значения.

Чем отличается Получить() от ИспользоватьДату()?

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

Как установить значение периодического реквизита на дату из кода?

Используйте метод Установить(Дата, Значение) периодического реквизита, после чего запишите элемент: Спр.Цена.Установить(НужнаяДата, НоваяЦена); Спр.Записать();. Если запись на эту дату уже существует, она будет перезаписана.

Итог

Что важно запомнить

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