Разработка и Конфигурация · 11 мин
Как установить период в запросе 1С
Как задать период в запросе 1С: параметры НачалоПериода и КонецПериода, отборы в виртуальных таблицах, функции ДАТАВРЕМЯ и КОНЕЦПЕРИОДА, типичные ошибки.
Отбор по периоду — одна из самых частых задач при написании запросов в 1С. Практически любой отчёт, обработка или выборка данных ограничивается диапазоном дат: остатки на дату, обороты за месяц, документы за квартал. При этом способ задать период зависит от того, с какой таблицей работает запрос — с физической таблицей документов, с виртуальной таблицей регистра или с данными, где дата хранится в произвольном реквизите.
Ошибки в установке периода приводят к характерным проблемам: в выборку попадает лишний день или, наоборот, теряются документы последнего дня периода, остатки считаются не на ту дату, а запрос к виртуальной таблице без параметров периода начинает работать в разы медленнее. Все эти ситуации решаются правильным выбором инструмента: параметров запроса, функций языка запросов или параметров виртуальной таблицы.
Ниже разобраны основные способы установить период в запросе 1С: через параметры, через функции ДАТАВРЕМЯ и КОНЕЦПЕРИОДА, через параметры виртуальных таблиц регистров, а также типичные ошибки границ периода и способы их проверить.
Как задать период через параметры запроса
Базовый способ — объявить в тексте запроса именованные параметры со знаком амперсанда и подставить их в условие отбора. Для выборки документов за период типовой запрос выглядит так:
ВЫБРАТЬ
РеализацияТоваровУслуг.Ссылка,
РеализацияТоваровУслуг.Дата,
РеализацияТоваровУслуг.СуммаДокумента
ИЗ
Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
ГДЕ
РеализацияТоваровУслуг.Дата МЕЖДУ &НачалоПериода И &КонецПериода
И РеализацияТоваровУслуг.Проведен
После формирования текста параметры заполняются в коде модуля методом УстановитьПараметр. Имена параметров в коде указываются без амперсанда:
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(ДатаНачала));
Запрос.УстановитьПараметр("КонецПериода", КонецДня(ДатаОкончания));
Результат = Запрос.Выполнить();
Обратите внимание на функции НачалоДня() и КонецДня() встроенного языка. Если пользователь выбрал на форме даты 01.03 и 31.03, то значение даты окончания по умолчанию будет 31.03 00:00:00 — начало суток. Без КонецДня() в выборку попадут только документы, созданные ровно в полночь, а все документы за 31 марта будут потеряны. Это самая распространённая ошибка при установке периода.
- 1Добавьте в текст запроса условие ГДЕ с параметрами &НачалоПериода и &КонецПериода
- 2В коде создайте объект Запрос и задайте текст
- 3Вызовите УстановитьПараметр для обеих дат, обернув дату окончания в КонецДня()
- 4Выполните запрос и проверьте, что документы последнего дня периода попали в выборку
Функции ДАТАВРЕМЯ и КОНЕЦПЕРИОДА в языке запросов
Если границы периода нужно задать прямо в тексте запроса без передачи параметров, используется функция ДАТАВРЕМЯ. Она принимает числовые аргументы: год, месяц, день и при необходимости часы, минуты, секунды:
ГДЕ
Продажи.Период МЕЖДУ ДАТАВРЕМЯ(2026, 1, 1) И ДАТАВРЕМЯ(2026, 3, 31, 23, 59, 59)
Такой вариант подходит для жёстко зафиксированных периодов — например, в служебных запросах или при отладке. Для отчётов, где даты выбирает пользователь, ДАТАВРЕМЯ не подходит: значения нельзя изменить без правки текста запроса.
Функция КОНЕЦПЕРИОДА решает проблему границы периода на стороне запроса. Она преобразует переданную дату к концу указанной единицы времени — дня, месяца, квартала или года:
ГДЕ
Продажи.Период МЕЖДУ &НачалоПериода И КОНЕЦПЕРИОДА(&КонецПериода, ДЕНЬ)
С таким условием параметр &КонецПериода можно передавать как есть, без КонецДня() в коде — функция сама приведёт 31.03 00:00:00 к 31.03 23:59:59. Существует и зеркальная функция НАЧАЛОПЕРИОДА, полезная, когда пользовательская дата может содержать произвольное время. Использование этих функций делает запрос устойчивым к тому, как именно заполнены параметры.
Период в параметрах виртуальных таблиц регистров
Когда запрос обращается к виртуальной таблице регистра накопления (Остатки, Обороты, ОстаткиИОбороты) или регистра сведений (СрезПоследних, СрезПервых), период задаётся не в условии ГДЕ, а в круглых скобках после имени виртуальной таблицы. Это принципиально важно для производительности.
Пример получения остатков на конкретную дату:
ВЫБРАТЬ
Остатки.Номенклатура,
Остатки.КоличествоОстаток
ИЗ
РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Склад = &Склад) КАК Остатки
Пример оборотов за период:
ВЫБРАТЬ
Обороты.Номенклатура,
Обороты.КоличествоОборот
ИЗ
РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК Обороты
В параметрах виртуальной таблицы Обороты первые два аргумента — начало и конец периода, третий — периодичность (День, Месяц, Регистратор), четвёртый — условие отбора по измерениям. Неиспользуемые параметры оставляют пустыми, сохраняя запятые. Для среза последних в регистре сведений период указывается первым параметром — срез будет взят на эту дату включительно.
Ключевое правило: отбор по периоду в параметрах виртуальной таблицы выполняется на уровне механизма виртуальной таблицы и обычно эффективнее, чем фильтрация результата через ГДЕ. Если написать условие по полю Период в секции ГДЕ вместо параметров таблицы, платформа сначала построит виртуальную таблицу по всем данным, а потом отфильтрует её — на больших регистрах это даёт кратное замедление.
Установка периода в СКД и консоли запросов
В отчётах на системе компоновки данных период обычно объявляется как параметры &НачалоПериода и &КонецПериода в тексте запроса набора данных, а на закладке «Настройки» добавляется пользовательский параметр типа «Стандартный период». СКД умеет автоматически связывать стандартный период с параметрами запроса, если параметры на закладке «Компоновка данных» отмечены как доступные и включены в пользовательские настройки.
При работе с виртуальными таблицами в СКД есть нюанс: параметры внутри круглых скобок виртуальной таблицы должны быть объявлены в списке параметров компоновки, иначе компоновщик не сможет подставить значения. Для оборотов и остатков часто используют служебные параметры с типом «Момент времени» или границами, чтобы срез считался корректно на конец дня.
Для отладки периода удобна консоль запросов: она показывает список параметров запроса, позволяет заполнить их вручную и сразу увидеть результат. Проверять граничные условия лучше именно там — задайте начало и конец периода одним и тем же днём и убедитесь, что документы этого дня попадают в выборку.
При передаче даты окончания в параметры виртуальной таблицы Остатки помните: остатки рассчитываются на указанный момент. Если передать начало дня, движения этого дня в остатки не войдут. Для отчётов «на конец дня» передавайте КонецДня(Дата) или используйте объект Граница с видом «Включая».
Границы и моменты времени: тонкости отбора
Поле Дата документа в 1С хранит не только календарную дату, но и время с точностью до секунды, а в рамках одной секунды документы упорядочиваются по ссылке. Поэтому сравнение по дате иногда даёт неожиданный результат при работе с моментами времени — например, когда нужно получить остатки строго до проведения конкретного документа или сразу после него.
Для таких задач вместо простой даты используется тип МоментВремени или объект Граница. Граница с видом «Включая» означает, что документ, стоящий на границе, входит в расчёт; с видом «Исключая» — не входит. В запросах к виртуальным таблицам остатков параметр периода может принимать и момент времени, и границу:
ГраницаОстатков = Новый Граница(Документ.МоментВремени(), ВидГраницы.Включая);
Запрос.УстановитьПараметр("Период", ГраницаОстатков);
Ещё одна тонкость — часовые пояса. В распределённых базах и при интеграциях дата документа хранится в сеансовом или универсальном времени в зависимости от настроек. Если отчёт за сутки «не сходится» с аналогичным отчётом в другой системе, проверьте, не смещены ли границы периода из-за разницы часовых поясов.
Как проверить результат
Все документы последнего дня присутствуют
Документы последнего дня отсутствуют — дата окончания стоит на 00:00:00
Остатки соответствуют стандартному отчёту по регистру на ту же дату
Расхождение — проверьте границу и момент времени
Период задан в параметрах таблицы, запрос выполняется быстро
Период фильтруется через ГДЕ, запрос тормозит на больших объёмах
Типичные ошибки при установке периода
Первая ошибка — передача даты окончания без приведения к концу дня. Пользователь выбирает 31 марта, в параметр уходит 31.03 00:00:00, и весь последний день выпадает из отчёта. Лечится функцией КонецДня() в коде или КОНЕЦПЕРИОДА в тексте запроса.
Вторая ошибка — фильтрация виртуальной таблицы через ГДЕ вместо параметров в скобках. Запрос работает правильно, но платформа строит виртуальную таблицу по всем записям регистра. На небольших базах это незаметно, на больших приводит к минутам ожидания.
Третья ошибка — сравнение даты с реквизитом другого типа. Если реквизит имеет составной тип или тип «Строка», сравнение с параметром типа «Дата» может неявно не сработать или отключить использование индекса. Проверяйте типы полей в конструкторе запроса.
Четвёртая ошибка — использование оператора МЕЖДУ там, где границы могут прийти в обратном порядке. Если параметр начала больше параметра окончания, МЕЖДУ вернёт пустой результат без всякой ошибки. Перед выполнением запроса полезно проверять корректность периода и сообщать пользователю о неверном диапазоне.
Часто задаваемые вопросы
Как задать период «текущий месяц» без параметров?
Вычислите границы в коде встроенного языка: НачалоМесяца(ТекущаяДатаСеанса()) и КонецМесяца(ТекущаяДатаСеанса()), затем передайте их как обычные параметры. Вычислять даты внутри текста запроса не требуется — язык запросов не имеет функции «текущая дата».
Чем отличается условие МЕЖДУ от пары сравнений БольшеИлиРавно и МеньшеИлиРавно?
По результату они эквивалентны: МЕЖДУ включает обе границы. Разница только в читаемости.
Как получить остатки на начало дня, а не на конец?
Передайте в параметр виртуальной таблицы Остатки значение НачалоДня(Дата) — остатки будут рассчитаны на 00:00:00, то есть до движений этого дня. Либо используйте объект Граница с видом «Исключая», если нужно строго контролировать включение конкретного документа.
Почему срез последних возвращает запись с более поздней датой, чем заданный период?
Такого быть не должно: СрезПоследних берёт записи на указанный момент включительно. Проверьте, что параметр периода действительно передаётся первым аргументом в скобках виртуальной таблицы и что в него не попадает пустая дата — при пустом параметре срез берётся на максимально доступную дату.
Можно ли использовать один параметр для начала и конца периода?
Да, если выборка нужна за один день: установите оба параметра одним значением, но для условия окончания примените КОНЕЦПЕРИОДА(&Дата, ДЕНЬ) или передайте в конец значение КонецДня(Дата). Иначе будут выбраны только записи ровно в 00:00:00.
Как задать период в динамическом списке, а не в запросе?
В динамических списках используется стандартный элемент «Период» в настройках списка либо отбор по полю Дата через параметры произвольного запроса списка. Для произвольного запроса динамического списка действуют те же правила: параметры объявляются в тексте, значения подставляются через настройки компоновки или программно.
Что важно запомнить
Период в запросе 1С задаётся параметрами &НачалоПериода и &КонецПериода в условии ГДЕ или в скобках виртуальной таблицы. Дату окончания всегда приводите к концу дня — через КонецДня() в коде или КОНЕЦПЕРИОДА в запросе. Для виртуальных таблиц регистров период указывайте в параметрах таблицы, а не в ГДЕ, иначе запрос будет медленным. Проверяйте результат на граничных датах.