При разработке отчетов или обработок на платформе 1С:Предприятие часто возникает потребность изменить дату, добавив к ней определенный интервал. Стандартная функция ДОБАВИТЬКДАТЕ отлично справляется с этой задачей, однако многие разработчики сталкиваются с ограничением: как передать тип интервала (день, месяц, год) динамически через параметр, основываясь на данных из базы?
В этой статье мы подробно разберем, почему стандартный механизм УстановитьПараметр здесь не работает и какие эффективные способы существуют для решения этой задачи.
Важно понимать, что язык запросов 1С — это статически типизированный язык. Парсер запроса должен знать структуру выполнения операции еще на этапе компиляции плана запроса. Ключевые слова, такие как МЕСЯЦ, ГОД или ДЕНЬ в функции ДОБАВИТЬКДАТЕ, являются системными константами. Поэтому, если вы попытаетесь передать строку вида «Месяц» через параметр, система воспримет это как синтаксическую ошибку. Параметры запроса предназначены для значений данных, а не для замены ключевых слов языка.
Если в вашем запросе необходимо обрабатывать разные типы периодов для разных записей (например, в зависимости от настроек в справочнике), идеальным решением будет использование конструкции ВЫБОР КОГДА. Этот метод позволяет жестко прописать все допустимые варианты интервалов прямо внутри текста запроса.
Рассмотрим пример реализации:
ВЫБРАТЬ
Заказ.Дата,
ВЫБОР
КОГДА Заказ.ТипПериода = ЗНАЧЕНИЕ(Перечисление.ТипыПериодов.Месяц)
ТОГДА ДОБАВИТЬКДАТЕ(Заказ.Дата, МЕСЯЦ, 1)
КОГДА Заказ.ТипПериода = ЗНАЧЕНИЕ(Перечисление.ТипыПериодов.Год)
ТОГДА ДОБАВИТЬКДАТЕ(Заказ.Дата, ГОД, 1)
ИНАЧЕ ДОБАВИТЬКДАТЕ(Заказ.Дата, ДЕНЬ, 1)
КОНЕЦ КАК НоваяДата
ИЗ
Документ.ЗаказКлиента КАК Заказ
Этот подход делает запрос предсказуемым и безопасным. Его главное преимущество в том, что он корректно обрабатывает выборку, где для каждой строки может быть свое правило расчета даты.
Если тип интервала выбирается пользователем один раз перед выполнением запроса (например, в диалоговом окне), самым эффективным методом будет модификация текста запроса до его выполнения. Мы можем использовать методы работы со строками, чтобы внедрить нужное ключевое слово.
Посмотрим, как это сделать программно:
// Предположим, пользователь выбрал период "МЕСЯЦ"
ТипПериодаСтрокой = "МЕСЯЦ";
ТекстЗапроса =
"ВЫБРАТЬ ДОБАВИТЬКДАТЕ(&ИсходнаяДата, #Тип, 1) КАК Дата";
ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "#Тип", ТипПериодаСтрокой);
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("ИсходнаяДата", ТекущаяДата());
Результат = Запрос.Выполнить();
Этот метод работает максимально быстро, так как запрос попадает на сервер уже с «вшитой» командой МЕСЯЦ. Это избавляет систему от необходимости анализировать дополнительные условия ВЫБОР.
ДОБАВИТЬКДАТЕ принимает строго определенный набор типов: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД, ДЕКАДА, ПОЛУГОДИЕ. Использование любого другого слова приведет к ошибке.ВЫБОР может стать трудночитаемой. В таких случаях мы рекомендуем разбивать запрос на несколько частей или использовать предварительную обработку данных на стороне встроенного языка 1С.DATEADD в MS SQL) через механизм прямых запросов, так как это нарушает кроссплатформенность вашего решения и затрудняет перенос кода между различными базами данных.Теперь, когда мы проанализировали ситуацию, вы можете выбрать наиболее подходящий метод в зависимости от вашей задачи: либо гибкость с ВЫБОР, либо производительность с динамическим изменением текста запроса. Применяйте эти знания, чтобы сделать ваш код чище и профессиональнее!