Как правильно выбрать данные из регистра сведений за период в 1С?

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

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

Анализ типовых ошибок при фильтрации по периоду

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


ВЫБРАТЬ
    КурсыВалют.Период КАК Период,
    КурсыВалют.Валюта КАК Валюта,
    КурсыВалют.Курс КАК Курс
ИЗ
    РегистрСведений.КурсыВалют КАК КурсыВалют
ГДЕ
    КурсыВалют.Период МЕЖДУ &НачДата И &КонДата

Выясним причину такого поведения. На практике чаще всего встречаются следующие ошибки:

  1. Некорректные значения параметров дат. Банальная, но самая распространенная ошибка — опечатка в переданном значении года (например, перепутан 2015 и 2016 год) или перепутанные местами границы начала и окончания периода, когда дата начала оказывается больше даты конца.
  2. Учет времени в границах периода. В платформе 1С тип данных Дата всегда содержит и дату, и время. Если параметр &КонДата передается без явного указания времени, платформа подставляет время 00:00:00. В таком случае оператор МЕЖДУ отсечет все записи, сделанные в течение этого же дня, но имеющие время позже полуночи.

Для корректной работы с границей периода всегда передавайте в параметр &КонДата значение с концом дня (КонецДня(КонДата)) либо формируйте строгое условие в самом запросе:


ГДЕ
    КурсыВалют.Период >= &НачДата
    И КурсыВалют.Период < ДОБАВИТЬКДАТЕ(&КонДата, ДЕНЬ, 1)

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

Проанализируем разницу между обращением к реальной таблице регистра и использованием виртуальной таблицы СрезПоследних. Выбор подхода напрямую зависит от поставленной задачи:

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

2. Получение актуального среза. Виртуальная таблица СрезПоследних позволяет получить наиболее актуальное значение на определенный момент времени. Однако параметр Период виртуальной таблицы среза принимает только одну конкретную дату (точку на шкале времени), а не интервал. Задать диапазон дат непосредственно в параметрах среза невозможно на уровне синтаксиса платформы.

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

Если требуется получить значения, которые фактически действовали на протяжении интервала, включая курс на начало и все его последующие изменения, объединим срез на дату старта и движения внутри диапазона:


ВЫБРАТЬ
    СрезНаНачало.Период КАК Период,
    СрезНаНачало.Валюта КАК Валюта,
    СрезНаНачало.Курс КАК Курс
ИЗ
    РегистрСведений.КурсыВалют.СрезПоследних(&НачДата, ) КАК СрезНаНачало

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    КурсыДвижения.Период,
    КурсыДвижения.Валюта,
    КурсыДвижения.Курс
ИЗ
    РегистрСведений.КурсыВалют КАК КурсыДвижения
ГДЕ
    КурсыДвижения.Период > &НачДата
    И КурсыДвижения.Период <= &КонДата

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

  1. Система компоновки данных (СКД). СКД умеет автоматически вычислять срезы периодических регистров на каждую точку времени. При настройке ролей полей периода платформа сама рассчитывает актуальный срез на каждый день или месяц группировки отчета.
  2. Соединение с календарем дат. Если нужно вывести значение ресурса на абсолютно каждый день диапазона (даже если курс не менялся неделями), формируется таблица дат (например, из производственного календаря), к которой левым соединением подтягивается срез регистра сведений на каждую дату подзапросом.

Куда пропадает поле «Активность» в регистре?

Иногда при попытке отфильтровать записи в консоли запросов разработчики не находят системное поле Активность. Разберем, с чем это связано.

Наличие поля Активность строго регламентировано режимом записи регистра в конфигураторе:

  1. Подчинение регистратору. Системное поле Активность существует только в регистрах, движения которых формируются документами. Это поле определяет, учитывается ли данная запись при формировании итогов и срезов.
  2. Независимый регистр сведений. Большинство справочных регистров (включая классический регистр «Курсы валют») являются независимыми. В физической таблице таких регистров поля Активность нет, поскольку все внесенные в них записи безусловно активны и сразу влияют на срезы.

Также важно помнить, что в виртуальных таблицах СрезПоследних и СрезПервых поле Активность отсутствует всегда, так как платформа на уровне алгоритма виртуальной таблицы отбирает исключительно активные записи.

← На главную