При разработке запросов в системе 1С:Предприятие начинающие разработчики нередко сталкиваются с синтаксической ошибкой при попытке прибавить интервал к дате. Ошибка возникает из-за смешения функций встроенного языка 1С и языка запросов. Разберем причины возникновения этой ошибки и выясним, как правильно выполнять арифметические действия с датами в текстах запросов.
Проанализируем ситуацию: если в тексте запроса написать выражение ДобавитьМесяц(Рег.Дата1, Спр.КолМес), платформа выдаст синтаксическую ошибку. Это связано с тем, что функция ДобавитьМесяц() предназначена исключительно для встроенного языка 1С (модулей объектов, форм, общих модулей) и не поддерживается парсером языка запросов.
Кроме того, в языке запросов 1С запрещена прямая арифметика с датами через операторы плюс и минус (например, Дата + 86400). Любое изменение даты на определенный интервал времени в запросе выполняется с помощью специализированной встроенной функции ДОБАВИТЬКДАТЕ.
Рассмотрим структуру функции языка запросов ДОБАВИТЬКДАТЕ:
ДОБАВИТЬКДАТЕ(<ИсходнаяДата>, <ТипУвеличения>, <Количество>)
Разберем назначение каждого из трех параметров:
Дата, поле таблицы или параметр запроса, к которому необходимо прибавить интервал. Если передано значение NULL, результатом вычисления также будет NULL.СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, НЕДЕЛЯ, ДЕКАДА, МЕСЯЦ, КВАРТАЛ, ГОД (или их английские эквиваленты SECOND, MINUTE, HOUR, DAY, WEEK, DECADE, MONTH, QUARTER, YEAR).Посмотрим на практический пример исправления исходной ошибки, где количество месяцев берется из поля справочника:
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(Рег.Дата1, МЕСЯЦ, Спр.КолМес) КАК СлДата
ИЗ
РегистрНакопления.Взаиморасчеты КАК Рег
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Договоры КАК Спр
ПО Рег.Договор = Спр.Ссылка
Рассмотрим пример добавления фиксированного количества месяцев к дате документа:
ВЫБРАТЬ
Счет.Ссылка КАК Счет,
Счет.Дата КАК ДатаСчета,
ДОБАВИТЬКДАТЕ(Счет.Дата, МЕСЯЦ, 3) КАК ДатаОплатыПлановая
ИЗ
Документ.СчетНаОплатуПокупателю КАК Счет
Разберем пример вычитания интервала (получение даты на 10 дней раньше исходной):
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(Заказ.Дата, ДЕНЬ, -10) КАК КрайнийСрокПодготовки
ИЗ
Документ.ЗаказПокупателя КАК Заказ
При использовании функции ДОБАВИТЬКДАТЕ важно учитывать следующие нюансы:
31.01.2024, функция корректно вернет последний день следующего месяца — 29.02.2024 (с учетом високосного года). При этом время исходной даты (часы, минуты, секунды) сохраняется без изменений.НАЧАЛОПЕРИОДА или КОНЕЦПЕРИОДА:
КОНЕЦПЕРИОДА(ДОБАВИТЬКДАТЕ(Рег.Дата1, МЕСЯЦ, 1), МЕСЯЦ)
ДОБАВИТЬКДАТЕ к полям таблиц в условиях ГДЕ или соединениях ПО блокирует использование индексов по полю даты, так как СУБД вынуждена вычислять выражение для каждой строки (происходит сканирование таблицы — Index/Table Scan). Чтобы сохранить высокую скорость выполнения, рассчитывайте смещенную дату заранее в коде встроенного языка и передавайте ее в условие через параметр запроса:
// В коде 1С:
Запрос.УстановитьПараметр("ГраничнаяДата", ДобавитьМесяц(ТекущаяДата(), -1));
// В тексте запроса:
ГДЕ
Таблица.Дата >= &ГраничнаяДата