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