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

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

При работе с запросами в системе 1С:Предприятие одной из самых частых задач является фильтрация данных по времени. Часто возникает необходимость получить записи не за конкретный интервал, а начиная с определенного момента и до текущего времени (или «до бесконечности»). В этой статье мы подробно разберем, как правильно реализовать условие ОТ в запросе, как избежать синтаксических ошибок и как сделать такой запрос максимально производительным.

Базовая реализация условия «ОТ» в тексте запроса

Рассмотрим стандартную ситуацию: у нас есть физическая таблица (например, РегистрНакопления.ПродажиПоДисконтнымКартам), и нам нужно выбрать все записи, начиная с определенного дня. В языке запросов 1С нет специального оператора «ОТ», вместо него используются стандартные операторы сравнения.

Проанализируем правильный синтаксис условия в секции ГДЕ. Если нам нужно включить саму дату начала в выборку, мы используем оператор «больше или равно» (>=). Если дата начала должна быть исключена — оператор «больше» (>).

Пример правильного написания запроса:


Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
               |    Продажи.Период КАК Период,
               |    Продажи.ДисконтнаяКарта КАК ДисконтнаяКарта,
               |    Продажи.Сумма КАК Сумма
               |ИЗ
               |    РегистрНакопления.ПродажиПоДисконтнымКартам КАК Продажи
               |ГДЕ
               |    Продажи.Период >= &ДатаНачала
               |УПОРЯДОЧИТЬ ПО
               |    Период УБЫВ";

Важно обратить внимание на ошибку, которую часто допускают начинающие разработчики: попытку повторно использовать ключевое слово ГДЕ внутри условия или неверное указание полей. Условие должно следовать строго после обращения к таблице и содержать имя поля, оператор сравнения и параметр.

Корректная передача параметров даты

После того как мы определили параметр в тексте запроса (используя символ амперсанда &), его необходимо передать из кода на языке 1С. Разберем, как правильно инициализировать дату, чтобы запрос отработал без ошибок.

Выясним причину частых ошибок: функция Дата() в 1С может принимать разные форматы. Если мы передаем строку, она должна соответствовать формату "ГГГГММДДЧЧММСС". Однако профессиональнее и надежнее передавать дату через конструктор с разделением по числам.

Посмотрим на пример установки параметра:


// Вариант 1: Через конструктор (год, месяц, день)
Запрос.УстановитьПараметр("ДатаНачала", Дата(2019, 2, 27)); 

// Вариант 2: Через строку формата ГГГГММДД
Запрос.УстановитьПараметр("ДатаНачала", Дата("20190227")); 

// Вариант 3: Начало текущего дня
Запрос.УстановитьПараметр("ДатаНачала", НачалоДня(ТекущаяДата()));

Оптимизация: Использование виртуальных таблиц

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

Рассмотрим, как применить условие «ОТ» в виртуальной таблице Обороты. У этой таблицы есть встроенные параметры: НачалоПериода, КонецПериода, Периодичность и Условие. Чтобы задать период «ОТ», достаточно передать значение в первый параметр, а второй оставить пустым или передать Неопределено.


Запрос.Текст = "ВЫБРАТЬ
               |    ПродажиОбороты.ДисконтнаяКарта,
               |    ПродажиОбороты.СуммаОборот
               |ИЗ
               |    РегистрНакопления.ПродажиПоДисконтнымКартам.Обороты(&ДатаНачала, , , ) КАК ПродажиОбороты";
               
Запрос.УстановитьПараметр("ДатаНачала", Дата(2019, 2, 27));

Использование виртуальных таблиц значительно ускоряет работу программы, так как СУБД считывает гораздо меньше данных, обращаясь к уже готовым агрегатам.

Работа с функциями дат внутри запроса

Иногда требуется модифицировать дату непосредственно внутри запроса. Платформа предоставляет для этого ряд встроенных функций. Проанализируем самые полезные из них:

  1. НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ): Позволяет гарантировать, что отбор начнется с 00:00:00 указанного дня, даже если в параметре передана дата со временем.
  2. КОНЕЦПЕРИОДА(&Дата, МЕСЯЦ): Помогает быстро получить границу конца периода.
  3. ДОБАВИТЬКДАТЕ: Позволяет строить динамические интервалы (например, «за последние 10 дней от заданной даты»).

Пример использования функции для «очистки» времени в запросе:


|ГДЕ
|    Продажи.Период >= НАЧАЛОПЕРИОДА(&ДатаНачала, ДЕНЬ)

Объект «Граница» и точность отбора

При работе с периодами в 1С важно учитывать понятие Границы. Если запись в базе данных имеет время ровно 2023-01-01 00:00:00, и вы ставите условие Период >= &Дата, где параметр равен этой же секунде, результат может зависеть от того, как система интерпретирует момент времени.

Для максимально точного управления вхождением моментов времени в интервал рекомендуется использовать объект Граница. Рассмотрим его создание:


// Создаем границу, которая включает в себя каждую запись указанной секунды
МоментНачала = Новый Граница(ВыбраннаяДата, ВидГраницы.Включая);
Запрос.УстановитьПараметр("ДатаНачала", МоментНачала);

Производительность и индексация полей

Поле Период в стандартных регистрах 1С индексируется автоматически. Это означает, что условие ГДЕ Период >= &Дата работает крайне быстро, так как СУБД использует индекс для поиска нужного диапазона строк. Однако существует риск замедлить систему.

Важное правило: Старайтесь не применять функции к полям таблиц в секции ГДЕ. Например, условие ГДЕ НАЧАЛОПЕРИОДА(Период, ДЕНЬ) >= &Дата заставит сервер базы данных выполнять вычисления для каждой строки таблицы, что сделает невозможным использование индекса (запрос станет «не-SARGable»). Всегда старайтесь преобразовать параметр на языке 1С перед передачей в запрос, а поле Период оставлять в чистом виде.

Использование литералов дат

Если дата в вашем запросе является константой и никогда не изменится, вы можете прописать её прямо в тексте запроса, не используя УстановитьПараметр. Это называется «литерал даты». Синтаксис следующий:


|ГДЕ
|    Период >= ДАТАВРЕМЯ(2019, 02, 27, 0, 0, 0)

Этот способ удобен для быстрой отладки в консоли запросов или для жестко заданных бизнес-правил (например, начало ведения учета в новой базе).

Заключение

Мы подробно разобрали, как реализовать отбор по периоду «ОТ» в 1С. Подведем итог: для простых физических таблиц используйте ГДЕ Период >= &Параметр, для регистров накопления и бухгалтерии отдавайте приоритет виртуальным таблицам, а при передаче параметров всегда следите за типом данных и точностью (используя НачалоДня или Границу). Правильный подход к работе с датами не только лишит вас ошибок в результатах отчетов, но и обеспечит высокую скорость работы вашей системы.

← На главную