Как прибавить месяц к дате в запросе 1С?

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

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

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

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

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

Синтаксис и параметры функции ДОБАВИТЬКДАТЕ

Рассмотрим структуру функции языка запросов ДОБАВИТЬКДАТЕ:

ДОБАВИТЬКДАТЕ(<ИсходнаяДата>, <ТипУвеличения>, <Количество>)

Разберем назначение каждого из трех параметров:

  1. ИсходнаяДата — выражение типа Дата, поле таблицы или параметр запроса, к которому необходимо прибавить интервал. Если передано значение NULL, результатом вычисления также будет NULL.
  2. ТипУвеличения — предопределенное ключевое слово, указывающее единицу измерения сдвига. Задается строго литералом в тексте запроса (его нельзя передать через параметр). Допустимые значения: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, НЕДЕЛЯ, ДЕКАДА, МЕСЯЦ, КВАРТАЛ, ГОД (или их английские эквиваленты SECOND, MINUTE, HOUR, DAY, WEEK, DECADE, MONTH, QUARTER, YEAR).
  3. Количество — числовое выражение, числовая константа, поле другой таблицы или параметр запроса, определяющий величину смещения. Для вычитания периода указываются отрицательные значения.

Примеры использования функции в запросах

Посмотрим на практический пример исправления исходной ошибки, где количество месяцев берется из поля справочника:


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

Рассмотрим пример добавления фиксированного количества месяцев к дате документа:


ВЫБРАТЬ
    Счет.Ссылка КАК Счет,
    Счет.Дата КАК ДатаСчета,
    ДОБАВИТЬКДАТЕ(Счет.Дата, МЕСЯЦ, 3) КАК ДатаОплатыПлановая
ИЗ
    Документ.СчетНаОплатуПокупателю КАК Счет

Разберем пример вычитания интервала (получение даты на 10 дней раньше исходной):


ВЫБРАТЬ
    ДОБАВИТЬКДАТЕ(Заказ.Дата, ДЕНЬ, -10) КАК КрайнийСрокПодготовки
ИЗ
    Документ.ЗаказПокупателя КАК Заказ

Особенности работы с концами месяцев и производительность

При использовании функции ДОБАВИТЬКДАТЕ важно учитывать следующие нюансы:

  1. Переход через границы месяцев: если прибавить один месяц к дате 31.01.2024, функция корректно вернет последний день следующего месяца — 29.02.2024 (с учетом високосного года). При этом время исходной даты (часы, минуты, секунды) сохраняется без изменений.
  2. Комбинация с функциями периода: для получения начала или окончания рассчитанного периода функцию часто комбинируют с НАЧАЛОПЕРИОДА или КОНЕЦПЕРИОДА: КОНЕЦПЕРИОДА(ДОБАВИТЬКДАТЕ(Рег.Дата1, МЕСЯЦ, 1), МЕСЯЦ)
  3. Влияние на производительность и индексы: применение функции ДОБАВИТЬКДАТЕ к полям таблиц в условиях ГДЕ или соединениях ПО блокирует использование индексов по полю даты, так как СУБД вынуждена вычислять выражение для каждой строки (происходит сканирование таблицы — Index/Table Scan). Чтобы сохранить высокую скорость выполнения, рассчитывайте смещенную дату заранее в коде встроенного языка и передавайте ее в условие через параметр запроса:
    
    // В коде 1С:
    Запрос.УстановитьПараметр("ГраничнаяДата", ДобавитьМесяц(ТекущаяДата(), -1));
    
    // В тексте запроса:
    ГДЕ
        Таблица.Дата >= &ГраничнаяДата
    
← На главную