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