Как правильно передать год в параметр запроса 1С?

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

При написании запросов в 1С разработчики часто сталкиваются с задачей ограничения выборки по конкретному периоду, например, за определенный год. Часто возникает желание использовать конструкцию ДАТАВРЕМЯ прямо в тексте запроса, подставляя туда переменную. Однако, при попытке написать ДАТАВРЕМЯ(&Год, 1, 1, 0, 0, 0), мы получаем ошибку синтаксиса. Давайте разберемся, почему это происходит и как правильно организовать работу с датами.

Почему нельзя использовать переменные в конструкции ДАТАВРЕМЯ?

Важно понимать, что ДАТАВРЕМЯ — это не функция языка запросов, а специальный литерал. Это означает, что синтаксический анализатор 1С ожидает увидеть в скобках жестко заданные константы, которые будут определены на этапе компиляции запроса. Передача туда параметров (переменных 1С) невозможна, так как система не может вычислить их значение до начала выполнения запроса. Попытка передать переменную приведет к ошибке.

Вариант 1: Использование функций даты (не рекомендуется)

Одним из способов решить задачу является использование функций ГОД(), МЕСЯЦ() и ДЕНЬ() прямо в условии ГДЕ. Это позволяет получить нужные данные, однако этот метод имеет серьезный недостаток с точки зрения производительности.

Пример такого подхода:


ВЫБРАТЬ
    Док.Ссылка
ИЗ
    Документ.РеализацияТоваровУслуг КАК Док
ГДЕ
    ГОД(Док.Дата) = &Год
    И МЕСЯЦ(Док.Дата) = 1
    И ДЕНЬ(Док.Дата) = 1

Почему это плохо: При использовании функций от поля выборки СУБД вынуждена производить вычисления для каждой строки таблицы. Это отключает возможность использования индексов по полю Дата, что приводит к полному сканированию таблицы (Table Scan). На больших базах данных такой запрос будет работать крайне медленно.

Вариант 2: Передача диапазона дат через параметры (лучшая практика)

Профессиональный подход к написанию запросов подразумевает предварительный расчет границ периода на стороне кода 1С и передачу этих границ в запрос в виде готовых параметров. Это позволяет СУБД эффективно использовать индексы по полю Дата и выполнять запрос за минимальное время.

Разберем, как это реализовать по шагам:

  1. Вычислите начало и конец периода в коде 1С перед инициализацией объекта Запрос.
  2. Используйте метод УстановитьПараметр() для передачи дат.
  3. В тексте запроса используйте классическое сравнение >= и <=.

Пример реализации в коде 1С:


ДатаНачала = Дата(Год, 1, 1, 0, 0, 0);
ДатаКонца = Дата(Год, 1, 1, 23, 59, 59);

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

Запрос.УстановитьПараметр("ДатаНачала", ДатаНачала);
Запрос.УстановитьПараметр("ДатаКонца", ДатаКонца);
Результат = Запрос.Выполнить();

Почему этот метод эффективен?

Когда вы передаете в запрос готовые значения дат, СУБД воспринимает их как константы. Условие Дата >= &ДатаНачала И Дата <= &ДатаКонца является «сверточным» для оптимизатора базы данных. Это позволяет системе выполнить прямой поиск по индексу, обращаясь только к тем записям, которые попадают в указанный диапазон. Это критически важно для обеспечения высокого быстродействия при работе с документами.

Стоит ли формировать текст запроса через сложение строк?

Иногда можно встретить подход, когда переменные «вклеиваются» прямо в текст запроса: "... ГДЕ Док.Дата >= ДАТАВРЕМЯ(" + ПеременнаяГод + ",1,1,0,0,0) ...".

Хотя этот метод технически работоспособен, мы настоятельно не рекомендуем его использовать. Это нарушает чистоту кода и делает невозможным кэширование планов выполнения запросов на сервере СУБД. Каждый раз, когда меняется год, система воспринимает запрос как «новый», что заставляет её каждый раз заново строить план выполнения. Использование УстановитьПараметр() — это стандарт индустрии, который обеспечивает как безопасность, так и высокую производительность ваших отчетов и обработок.

Подводя итог: всегда старайтесь переносить логику вычисления дат из текста запроса в код 1С и передавать готовые диапазоны. Это лучший способ сделать вашу программу быстрой и надежной.

← На главную