Как динамически изменять тип периода в функции ДОБАВИТЬКДАТЕ в запросе 1С?

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

При разработке отчетов или обработок на платформе 1С:Предприятие часто возникает потребность изменить дату, добавив к ней определенный интервал. Стандартная функция ДОБАВИТЬКДАТЕ отлично справляется с этой задачей, однако многие разработчики сталкиваются с ограничением: как передать тип интервала (день, месяц, год) динамически через параметр, основываясь на данных из базы?

В этой статье мы подробно разберем, почему стандартный механизм УстановитьПараметр здесь не работает и какие эффективные способы существуют для решения этой задачи.

Почему нельзя просто передать параметр?

Важно понимать, что язык запросов 1С — это статически типизированный язык. Парсер запроса должен знать структуру выполнения операции еще на этапе компиляции плана запроса. Ключевые слова, такие как МЕСЯЦ, ГОД или ДЕНЬ в функции ДОБАВИТЬКДАТЕ, являются системными константами. Поэтому, если вы попытаетесь передать строку вида «Месяц» через параметр, система воспримет это как синтаксическую ошибку. Параметры запроса предназначены для значений данных, а не для замены ключевых слов языка.

Способ №1: Использование конструкции ВЫБОР

Если в вашем запросе необходимо обрабатывать разные типы периодов для разных записей (например, в зависимости от настроек в справочнике), идеальным решением будет использование конструкции ВЫБОР КОГДА. Этот метод позволяет жестко прописать все допустимые варианты интервалов прямо внутри текста запроса.

Рассмотрим пример реализации:


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

Этот подход делает запрос предсказуемым и безопасным. Его главное преимущество в том, что он корректно обрабатывает выборку, где для каждой строки может быть свое правило расчета даты.

Способ №2: Динамическое формирование текста запроса

Если тип интервала выбирается пользователем один раз перед выполнением запроса (например, в диалоговом окне), самым эффективным методом будет модификация текста запроса до его выполнения. Мы можем использовать методы работы со строками, чтобы внедрить нужное ключевое слово.

Посмотрим, как это сделать программно:


// Предположим, пользователь выбрал период "МЕСЯЦ"
ТипПериодаСтрокой = "МЕСЯЦ"; 

ТекстЗапроса = 
    "ВЫБРАТЬ ДОБАВИТЬКДАТЕ(&ИсходнаяДата, #Тип, 1) КАК Дата";

ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#Тип", ТипПериодаСтрокой);

Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("ИсходнаяДата", ТекущаяДата());
Результат = Запрос.Выполнить();

Этот метод работает максимально быстро, так как запрос попадает на сервер уже с «вшитой» командой МЕСЯЦ. Это избавляет систему от необходимости анализировать дополнительные условия ВЫБОР.

Важные рекомендации и ограничения

  1. Системные константы: Помните, что функция ДОБАВИТЬКДАТЕ принимает строго определенный набор типов: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД, ДЕКАДА, ПОЛУГОДИЕ. Использование любого другого слова приведет к ошибке.
  2. Читаемость: Если вариантов интервалов очень много (например, более 5-6), конструкция ВЫБОР может стать трудночитаемой. В таких случаях мы рекомендуем разбивать запрос на несколько частей или использовать предварительную обработку данных на стороне встроенного языка 1С.
  3. Производительность: Старайтесь избегать использования специфичных функций СУБД (например, DATEADD в MS SQL) через механизм прямых запросов, так как это нарушает кроссплатформенность вашего решения и затрудняет перенос кода между различными базами данных.

Теперь, когда мы проанализировали ситуацию, вы можете выбрать наиболее подходящий метод в зависимости от вашей задачи: либо гибкость с ВЫБОР, либо производительность с динамическим изменением текста запроса. Применяйте эти знания, чтобы сделать ваш код чище и профессиональнее!

← На главную