Как исправить ошибку «Неверные параметры "*"» в запросе СКД 1С?

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

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

«Ошибка в запросе набора данных по причине: Неверные параметры "*" (а также "+" или "-")»

Давайте подробно разберем, почему возникает эта проблема, проанализируем внутренние механизмы работы платформы «1С:Предприятие 8» и рассмотрим надежные практические методы её решения.

В чем суть проблемы? Выясняем причину

Типичный сценарий: в конфигурацию (например, в справочник Номенклатура) добавляется новый реквизит с типом Число. После этого разработчик создает запрос в СКД, где пытается перемножить этот реквизит на другое числовое поле (например, на количество в табличной части документа). На первый взгляд, оба поля имеют числовой тип данных, и СУБД должна без проблем выполнить математическую операцию. Однако СКД на этапе синтаксического анализа блокирует запрос.

Это происходит по трем основным причинам:

  1. Неявное левое соединение при обращении через точку. Когда мы пишем в запросе ОбъектАренды.ПлановаяСтавка, платформа автоматически преобразует это обращение в SQL-запрос с оператором LEFT JOIN. Если в документе поле ОбъектАренды не заполнено, или в справочнике у конкретного элемента отсутствует значение, результатом такого соединения станет значение NULL. Попытка умножить NULL на число в жестко типизированной среде СКД приводит к ошибке.
  2. Сбой кэша метаданных при динамическом обновлении конфигурации. Если новый реквизит был добавлен в базу и конфигурация была обновлена «динамически» (без монопольного перезапуска), СУБД уже знает о существовании нового поля, а вот локальный кэш конфигуратора и сама СКД все еще считают тип этого поля неопределенным.
  3. Различие между реквизитом объекта и элементом формы. Иногда разработчики путают тип данных реквизита в метаданных и тип поля, привязанного к нему на форме. Если в метаданных тип остался неопределенным (или строковым), а на форме настроен числовой ввод, в базе данных значение будет храниться некорректно.

Рассмотрим подробнее по шагам, как исправить эту ошибку в зависимости от вызвавшей её причины.

Решение 1. Явная обработка значений NULL с помощью функции ЕСТЬNULL

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

Замените прямое умножение полей на конструкцию с функцией ЕСТЬNULL, которая принудительно преобразует пустое значение в числовой ноль.

Вместо проблемного кода:


бит_ар_РегистрацияДоговоровАрендыОбъектыАренды.ОбъектАренды.бит_казань_ПлановаяСтавка * бит_ар_РегистрацияДоговоровАрендыОбъектыАренды.Количество КАК Поле1

Используйте безопасное выражение:


ЕСТЬNULL(бит_ар_РегистрацияДоговоровАрендыОбъектыАренды.ОбъектАренды.бит_казань_ПлановаяСтавка, 0) * ЕСТЬNULL(бит_ар_РегистрацияДоговоровАрендыОбъектыАренды.Количество, 0) КАК Поле1

Эта простая мера страхует запрос от падения в тех строках, где данные по какой-то причине не заполнены.

Решение 2. Явное приведение типов с помощью функции ВЫРАЗИТЬ

Если СКД не может однозначно определить тип поля из-за того, что поле связи имеет составной тип данных, оператор математического умножения выдаст ошибку. Нам необходимо принудительно указать платформе, что значение является числом с определенной разрядностью.

Применим функцию ВЫРАЗИТЬ. Пропишем явное приведение типов в запросе:


ВЫРАЗИТЬ(ЕСТЬNULL(бит_ар_РегистрацияДоговоровАрендыОбъектыАренды.ОбъектАренды.бит_казань_ПлановаяСтавка, 0) КАК ЧИСЛО(15, 2)) * ЕСТЬNULL(бит_ар_РегистрацияДоговоровАрендыОбъектыАренды.Количество, 0) КАК Поле1

Важное замечание: Если при попытке использовать ВЫРАЗИТЬ конфигуратор выдает ошибку «Несовместимые типы ВЫРАЗИТЬ», это сигнализирует о том, что в метаданных тип вашего реквизита определен не как Число (например, это Строка или ЛюбаяСсылка). Обязательно откройте свойства реквизита в дереве метаданных и убедитесь, что там выбран правильный тип.

Решение 3. Замена обращений «через точку» на явное соединение таблиц

Обращение к реквизитам через точку (разыменование ссылок) в сложных запросах является плохим тоном разработки в 1С, так как создает скрытые неконтролируемые левые соединения на уровне СУБД. Это ухудшает производительность и часто путает планировщик СКД при определении типов.

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


ВЫБРАТЬ
    ОбъектыАренды.ОбъектАренды КАК ОбъектАренды,
    ОбъектыАренды.Количество КАК Площадь,
    ЕСТЬNULL(СпрНоменклатура.бит_казань_ПлановаяСтавка, 0) * ЕСТЬNULL(ОбъектыАренды.Количество, 0) КАК Поле1
ИЗ
    Документ.бит_ар_РегистрацияДоговоровАренды.ОбъектыАренды КАК ОбъектыАренды
    ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК СпрНоменклатура
        ПО ОбъектыАренды.ОбъектАренды = СпрНоменклатура.Ссылка

При таком подходе СКД гораздо легче сопоставить типы данных, так как связь таблиц описана прозрачно, а реквизит бит_казань_ПлановаяСтавка берется непосредственно из его физической таблицы.

Решение 4. Очистка кэша метаданных и монопольное обновление

Если вы выполнили все рекомендации по написанию запроса (применили ЕСТЬNULL, сделали явное соединение, проверили типы данных), но конфигуратор при сохранении схемы СКД упорно продолжает сыпать ошибками арифметических операторов, дело в кэше метаданных.

Проанализируем шаги для исправления этой системной ошибки:

  1. Полностью закройте Конфигуратор и сеансы «1С:Предприятие» данной базы.
  2. Если база файловая, очистите локальный кэш конфигурационной информации на вашем компьютере (папки по пути %LocalAppData%\1C\1Cv8\).
  3. Если база клиент-серверная, перезапустите службу сервера «1С:Предприятие» для принудительного обновления кэша сервера.
  4. Запустите конфигуратор, откройте свойства проблемного реквизита и выполните любое несущественное изменение (например, временно измените длину числа с 15 на 16), после чего сохраните конфигурацию БД (нажмите клавишу F7).
  5. Верните исходную длину числа и обновите базу данных еще раз.

После проведения этих манипуляций платформа обновит внутренние идентификаторы типов данных, и СКД успешно скомпилирует ваш запрос с использованием нового числового реквизита.

← На главную