Как реализовать периодическую константу в 1С:Предприятии 8?

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

Разработчики, перешедшие на платформу 1С:Предприятие 8 с версии 7.7, нередко ищут свойство «Периодическая» в объекте метаданных Константа или пытаются искусственно связать обычную константу с регистром сведений. В платформе 1С:Предприятие 8 архитектурный подход кардинально изменился: константа предназначена исключительно для хранения единичного, редко изменяемого значения, не привязанного ко времени. Если значение должно изменяться во времени и иметь историю, объект Константа создавать не требуется вовсе.

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

Архитектура периодической настройки: создаем регистр сведений

Для создания настройки или параметра, изменяющегося во времени, используем отдельный объект конфигурации — Регистр сведений. Рассмотрим по шагам правильную настройку его структуры:

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

Типичная ошибка: почему метод ПолучитьПоследнее возвращает пустые данные

Проанализируем распространенную ошибку начинающих разработчиков. Иногда при создании регистра хранимое значение ошибочно добавляют в ветку Измерения вместо ветки Ресурсы. После этого при попытке прочитать срез данных получают неожиданное поведение:


// Попытка получить срез на текущую дату
ЗначенияПараметра = РегистрыСведений.МояНастройка.ПолучитьПоследнее(ТекущаяДатаСеанса());

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

Кроме того, структура будет содержать пустые значения по умолчанию (ноль для чисел, пустая строка для строк, пустая ссылка для ссылочных типов), если в переданном параметре даты запрошен срез на момент времени, предшествующий самой первой записи в регистре сведений.

Получение значений: метод менеджера против запроса

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

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

Метод менеджера регистра сведений удобен для точечного получения значения в коде формы, при интерактивном открытии или в редких серверных операциях. Посмотрим на пример вызова:


// Для глобальной настройки без измерений отбор не требуется
Отбор = Новый Структура;
АктуальныеНастройки = РегистрыСведений.СтавкаНалога.ПолучитьПоследнее(ТекущаяДатаСеанса(), Отбор);

Если АктуальныеНастройки.Свойство("Ставка") Тогда
    ТекущаяСтавка = АктуальныеНастройки.Ставка;
КонецЕсли;

Обратим внимание: если опустить параметр даты или передать пустую дату, метод вернет самую последнюю запись во всем регистре (значение на бесконечность).

Способ 2. Запрос к виртуальной таблице СрезПоследних

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ТаблицаСреза.Период КАК ДатаДействия,
    |	ТаблицаСреза.Ставка КАК Ставка
    |ИЗ
    |	РегистрСведений.СтавкаНалога.СрезПоследних(&Период, ) КАК ТаблицаСреза";

Запрос.УстановитьПараметр("Период", ТекущаяДатаСеанса());
РезультатЗапроса = Запрос.Выполнить();

Если Не РезультатЗапроса.Пустой() Тогда
    Выборка = РезультатЗапроса.Выбрать();
    Выборка.Следующий();
    ТекущаяСтавка = Выборка.Ставка;
    ДатаНачалаДействия = Выборка.ДатаДействия;
КонецЕсли;

В отличие от метода менеджера, запрос позволяет извлечь не только ресурсы, но и точный Период, с которого действует текущее значение, а также реквизиты записи (например, комментарий).

Особенности производительности и кэширования

Важно помнить об архитектурной разнице между классическими константами и регистрами сведений:

  1. Механизм кэширования: значения стандартных констант 1С кэшируются на уровне платформы в памяти сеанса. Регистры сведений платформой автоматически не кэшируются, поэтому каждое чтение среза формирует обращение к СУБД.
  2. Оптимизация чтения: если значение периодической настройки считывается регулярно (например, при расчете каждой строки в документах), рекомендуется поместить функцию получения в общий модуль с повторным использованием возвращаемых значений (на время сеанса или время вызова сервера) либо заполнять значением параметр сеанса при старте системы.
  3. Использование функциональных опций: если периодическая константа определяет доступность интерфейса, подсистем или колонок документов во времени, к ресурсу такого регистра сведений можно привязать механизм Функциональные опции.
← На главную