При разработке запросов к периодическим регистрам сведений часто возникает задача получения данных за определенный промежуток времени. Начинающие разработчики нередко сталкиваются с ситуацией, когда запрос к регистру без условий возвращает данные, а при добавлении условия на интервал дат результат оказывается пустым. Кроме того, возникают вопросы о применимости виртуальных таблиц срезов и доступности системного поля Активность. Разберем по шагам, почему возникают подобные проблемы и как правильно строить выборку.
Рассмотрим классическую ситуацию: запрос без условий успешно возвращает строки, но стоит наложить фильтр по датам, как выборка становится пустой.
ВЫБРАТЬ
КурсыВалют.Период КАК Период,
КурсыВалют.Валюта КАК Валюта,
КурсыВалют.Курс КАК Курс
ИЗ
РегистрСведений.КурсыВалют КАК КурсыВалют
ГДЕ
КурсыВалют.Период МЕЖДУ &НачДата И &КонДата
Выясним причину такого поведения. На практике чаще всего встречаются следующие ошибки:
Дата всегда содержит и дату, и время. Если параметр &КонДата передается без явного указания времени, платформа подставляет время 00:00:00. В таком случае оператор МЕЖДУ отсечет все записи, сделанные в течение этого же дня, но имеющие время позже полуночи.Для корректной работы с границей периода всегда передавайте в параметр &КонДата значение с концом дня (КонецДня(КонДата)) либо формируйте строгое условие в самом запросе:
ГДЕ
КурсыВалют.Период >= &НачДата
И КурсыВалют.Период < ДОБАВИТЬКДАТЕ(&КонДата, ДЕНЬ, 1)
Проанализируем разницу между обращением к реальной таблице регистра и использованием виртуальной таблицы СрезПоследних. Выбор подхода напрямую зависит от поставленной задачи:
1. Получение физических записей, внесенных в интервале. Запрос к таблице РегистрСведений.КурсыВалют с отбором по полю Период возвращает только те строки, которые были непосредственно записаны в указанном интервале. Если курс валюты был зафиксирован до даты начала периода и в течение всего выбранного диапазона не менялся, прямой запрос не вернет ни одной записи, хотя курс продолжал действовать.
2. Получение актуального среза. Виртуальная таблица СрезПоследних позволяет получить наиболее актуальное значение на определенный момент времени. Однако параметр Период виртуальной таблицы среза принимает только одну конкретную дату (точку на шкале времени), а не интервал. Задать диапазон дат непосредственно в параметрах среза невозможно на уровне синтаксиса платформы.
Если требуется получить значения, которые фактически действовали на протяжении интервала, включая курс на начало и все его последующие изменения, объединим срез на дату старта и движения внутри диапазона:
ВЫБРАТЬ
СрезНаНачало.Период КАК Период,
СрезНаНачало.Валюта КАК Валюта,
СрезНаНачало.Курс КАК Курс
ИЗ
РегистрСведений.КурсыВалют.СрезПоследних(&НачДата, ) КАК СрезНаНачало
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
КурсыДвижения.Период,
КурсыДвижения.Валюта,
КурсыДвижения.Курс
ИЗ
РегистрСведений.КурсыВалют КАК КурсыДвижения
ГДЕ
КурсыДвижения.Период > &НачДата
И КурсыДвижения.Период <= &КонДата
Рассмотрим подробнее другие варианты решения этой задачи:
Иногда при попытке отфильтровать записи в консоли запросов разработчики не находят системное поле Активность. Разберем, с чем это связано.
Наличие поля Активность строго регламентировано режимом записи регистра в конфигураторе:
Активность существует только в регистрах, движения которых формируются документами. Это поле определяет, учитывается ли данная запись при формировании итогов и срезов.Активность нет, поскольку все внесенные в них записи безусловно активны и сразу влияют на срезы.Также важно помнить, что в виртуальных таблицах СрезПоследних и СрезПервых поле Активность отсутствует всегда, так как платформа на уровне алгоритма виртуальной таблицы отбирает исключительно активные записи.