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

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

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

Разберем подробно, почему возникает такое поведение, как устроена типизация в запросах 1С и какими способами можно корректно прибавить количество месяцев к дате.

Анализ причин возникновения ошибки

Рассмотрим синтаксис системной функции языка запросов:

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

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

  1. Дата: исходное поле типа Дата.
  2. ТипУвеличения: ключевое слово интервала (СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, МЕСЯЦ, КВАРТАЛ, ГОД).
  3. Количество: обязательное числовое значение типа Число, указывающее, на сколько единиц смещается дата.

Если вместо числа в третий параметр передается строка, составной тип или нетипизированное значение, платформа возвращает ошибку «Неверные параметры».

Частая попытка исправить ситуацию с помощью оператора ВЫРАЗИТЬ(Поле КАК Число) приводит либо к ошибке несовместимости типов, либо к результату NULL. Выясним причину такого поведения: в языке запросов 1С оператор ВЫРАЗИТЬ не выполняет конвертацию значений (как оператор CAST в классическом SQL), а лишь сужает (уточняет) составной тип данных до конкретного. Если поле в исходной таблице или регистре изначально сохранено с типом Строка, попытка применить к нему ВЫРАЗИТЬ(... КАК Число) вернет NULL.

Кроме того, если реквизит смещения содержит значение NULL (например, при левом соединении таблиц), функция ДОБАВИТЬКДАТЕ также вернет NULL.

Способ 1. Корректировка типов в метаданных конфигурации

Проанализируем структуру источника данных. Если реквизит (например, СрокИспользования в регистре или документе) хранит числовое количество месяцев, наиболее правильным решением будет изменение типа данных реквизита в дереве метаданных конфигуратора с типа Строка на тип Число.

После изменения типа данных в запросе можно напрямую использовать поле со смещением, обязательно обработав возможное значение NULL:


ВЫБРАТЬ
    ВТ_Осн.Сотрудник,
    ВТ_Осн.ДатаДокумента,
    ДОБАВИТЬКДАТЕ(ВТ_Осн.ДатаДокумента, МЕСЯЦ, ЕСТЬNULL(ВТ_Осн.СрокИспользования, 0)) КАК ДатаКонецИспользования
ИЗ
    ВТ_Осн КАК ВТ_Осн

Способ 2. Преобразование строки в число с помощью конструкции ВЫБОР

Если изменить структуру метаданных невозможно, а список возможных строковых значений срока ограничен (например, фиксированные периоды: 1, 3, 6, 12 месяцев), выполним явную подмену строк на числа внутри запроса.

Посмотрим на пример реализации с конструкцией ВЫБОР:


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

В этом случае конструкция ВЫБОР гарантированно возвращает числовой результат, что исключает возникновение ошибки «Неверные параметры».

Способ 3. Расчет даты во встроенном языке 1С

Если строковые значения могут быть произвольными и их невозможно перебрать в запросе через ВЫБОР, разберем вычисление итоговой даты после выполнения запроса с помощью средств встроенного языка 1С.

Для этого в запросе выбираем исходные строковые поля и дату, а расчет выполняем при обходе выборки с помощью функций Число() и ДобавитьМесяц():


Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
    // Преобразуем строку в числовое значение
    ЧислоМесяцев = Число(Выборка.СрокИспользования);
    
    // Рассчитываем дату окончания
    ДатаОкончания = ДобавитьМесяц(Выборка.ДатаДокумента, ЧислоМесяцев);
    
    // Дальнейшая обработка полученных данных
КонецЦикла;

Способ 4. Передача типизированной таблицы через МенеджерВременныхТаблиц

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

  1. Получаем исходные данные из базы.
  2. Выгружаем их в объект ТаблицаЗначений.
  3. Добавляем типизированную числовую колонку и заполняем ее преобразованными значениями через функцию Число().
  4. Передаем подготовленную таблицу значений в пакетный запрос через МенеджерВременныхТаблиц и выполняем функцию ДОБАВИТЬКДАТЕ уже по числовой колонке.
← На главную