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

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

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

Анализ исходной ситуации и причины ошибки

Рассмотрим пример кода, который часто вызывает затруднения у разработчиков:


ВЫБОР
    КОГДА ДополнительныеСведения.Значение <> 0
        ТОГДА ДОБАВИТЬКДАТЕ(ХозрасчетныйОстатки.Субконто3.Дата, ДЕНЬ, ДополнительныеСведения.Значение)
    ИНАЧЕ 0
КОНЕЦ

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

Решение №1: Явное приведение типов с помощью ВЫРАЗИТЬ

Самый эффективный способ обойти это ограничение — использовать функцию ВЫРАЗИТЬ. Она позволяет принудительно указать системе, что значение из составного типа нужно рассматривать как число. Разберем по шагам, как модифицировать запрос.

Посмотрим на исправленный вариант кода:


ВЫБОР
    КОГДА ВЫРАЗИТЬ(ДополнительныеСведения.Значение КАК ЧИСЛО(10, 0)) <> 0
        ТОГДА ДОБАВИТЬКДАТЕ(ХозрасчетныйОстатки.Субконто3.Дата, ДЕНЬ, ВЫРАЗИТЬ(ДополнительныеСведения.Значение КАК ЧИСЛО(10, 0)))
    ИНАЧЕ ДАТАВРЕМЯ(1, 1, 1)
КОНЕЦ

В данном примере мы использовали ВЫРАЗИТЬ(ДополнительныеСведения.Значение КАК ЧИСЛО(10, 0)). Обратите внимание на точность 0. Это критически важно, так как функция ДОБАВИТЬКДАТЕ не принимает дробные значения. Если в значении характеристики окажется число с плавающей запятой, приведение к целому числу позволит функции отработать корректно.

Решение №2: Соблюдение совместимости типов в конструкции ВЫБОР

Разберем еще одну важную деталь, которая часто упускается из виду. В исходном коде автора в ветке ТОГДА возвращается результат функции ДОБАВИТЬКДАТЕ (тип Дата), а в ветке ИНАЧЕ — число 0. Система 1С требует, чтобы все ветки одного выражения ВЫБОР возвращали значения совместимых типов.

Проанализируем последствия: попытка смешать дату и число в одной колонке приведет к тому, что запрос либо не выполнится, либо вернет непредсказуемый результат. Чтобы исправить это, в ветке ИНАЧЕ следует использовать пустую дату или NULL:

  1. Использование пустой даты: ДАТАВРЕМЯ(1, 1, 1). Это обеспечит типизацию всей колонки как "Дата".
  2. Использование NULL: NULL. В этом случае колонка будет иметь составной тип, включающий дату и пустое значение.

Решение №3: Обработка пустых значений (NULL)

При левом соединении с таблицей дополнительных сведений (а это стандартная практика), для многих записей может просто не существовать соответствующего значения. В этом случае ДополнительныеСведения.Значение вернет NULL.

Любая арифметическая операция или сравнение с NULL в языке запросов дает результат NULL. Чтобы избежать логических ошибок, выясним причину возможного сбоя и добавим функцию ЕСТЬNULL. Посмотрим на итоговый, максимально безопасный вариант конструкции:


ВЫБОР
    КОГДА ЕСТЬNULL(ВЫРАЗИТЬ(ДополнительныеСведения.Значение КАК ЧИСЛО(10, 0)), 0) <> 0
        ТОГДА ДОБАВИТЬКДАТЕ(ХозрасчетныйОстатки.Субконто3.Дата, ДЕНЬ, ВЫРАЗИТЬ(ДополнительныеСведения.Значение КАК ЧИСЛО(10, 0)))
    ИНАЧЕ ДАТАВРЕМЯ(1, 1, 1)
КОНЕЦ

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

Проанализируем еще один фрагмент: ХозрасчетныйОстатки.Субконто3.Дата. Если Субконто3 является полем составного типа (что характерно для Плана счетов), обращение через точку к полю Дата заставляет платформу выполнять неявное левое соединение со всеми таблицами объектов, которые могут входить в это субконто (документы, справочники и т.д.). Это может катастрофически снизить скорость выполнения запроса. Для выявления подобных проблемных мест можно использовать инструмент для автоматической проверки запросов на неявное разыменование полей составного типа.

Рассмотрим, как оптимизировать этот момент. Если мы заранее знаем тип объекта в Субконто3, следует применить ВЫРАЗИТЬ и здесь:

ВЫРАЗИТЬ(ХозрасчетныйОстатки.Субконто3 КАК Документ.РеализацияТоваровУслуг).Дата

Такой подход позволит SQL-серверу обратиться напрямую к таблице конкретного документа, минуя перебор всех возможных типов данных.

Рекомендации по структуре запроса

Для повышения стабильности работы сложных запросов мы рекомендуем придерживаться следующих правил:

Подводя итог, можно сказать, что ошибка "неверные параметры" в 1С почти всегда сигнализирует о несоответствии ожидаемого и реального типов данных. Применяя функцию ВЫРАЗИТЬ и внимательно следя за типизацией веток ВЫБОР, вы сможете создавать надежные и быстрые запросы.

← На главную