Как исправить ошибку «Не задано значение параметра» в запросах 1С и СКД

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

При разработке отчетов и запросов в платформе 1С разработчики часто сталкиваются с ситуацией, когда параметр отчета является необязательным. Если пользователь не заполнил поле ввода, платформа генерирует исключение: «Ошибка при исполнении запроса "Не задано значение параметра"». Попытка обернуть такой параметр в функцию ЕСТЬNULL не дает результата.

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

Почему функция ЕСТЬNULL не работает с параметрами запроса

Разберем распространенное заблуждение. Выражение вида ЕСТЬNULL(&Дни, 0) не предотвращает ошибку незаданного параметра. Функция ЕСТЬNULL предназначена исключительно для обработки значений NULL, которые возвращаются СУБД из таблиц базы данных (например, при выполнении левого или правого соединения).

Проверка наличия и заполненности параметров выполняется синтаксическим анализатором 1С еще до отправки SQL-запроса в СУБД. Если параметр указан в тексте запроса, но его значение не передано в структуру параметров или отключено в настройках, система выдает ошибку на этапе подготовки выполнения запроса.

Способ 1. Настройка свойства параметров в схеме компоновки данных

Если разработка отчета выполняется с использованием Системы компоновки данных (СКД), управлять поведением необязательных параметров можно на уровне схемы компоновки.

Проанализируем необходимые действия на закладке «Параметры» в схеме компоновки данных:

  1. Найдем параметр (например, Дни) в списке параметров схемы.
  2. Снимем флажок в колонке «Запрещать незаполненные значения». Это позволит платформе принимать пустые значения или значение 0.
  3. Установим в колонке «Использование» значение Всегда (вместо Авто). Это заставит СКД всегда передавать данный параметр в запрос, даже если пользователь сбросил галочку его использования в форме настроек.

После этой настройки синтаксический анализатор не будет блокировать выполнение запроса, а нулевое значение передастся корректно.

Способ 2. Вынос логики вычисления даты в выражения СКД

Часто необязательный параметр используется для смещения даты, например: ДОБАВИТЬКДАТЕ(&КонецПериода, ДЕНЬ, -&Дни). Если пользователь отключает параметр &Дни, сложная конструкция внутри виртуальной таблицы запроса может вызвать ошибку.

Чтобы сделать код надежным и гибким, вынесем расчет граничной даты на закладку «Параметры» схемы компоновки данных:

  1. Создадим служебный параметр, например &ГраницаДатыОприходования.
  2. Включим для него флаг «Ограничение доступности», чтобы скрыть параметр от пользователя.
  3. В поле «Выражение» пропишем условие проверки с помощью встроенного языка СКД:

Выбор 
    Когда &Дни Заполнено И &Дни <> 0 Тогда 
        ДобавитьКДате(&КонецПериода, "День", -&Дни) 
    Иначе 
        &КонецПериода 
Конец

В самом тексте запроса избавимся от прямой обработки численного параметра &Дни и перейдем к использованию сформированной даты в расширении языка запросов:


ВЫБРАТЬ
    ПартииТоваров.Номенклатура КАК Номенклатура,
    ПартииТоваров.КоличествоПриход КАК КоличествоПриход,
    ПартииТоваров.КоличествоРасход КАК КоличествоРасход
ИЗ
    РегистрНакопления.ПартииТоваровНаСкладах.ОстаткиИОбороты(
        , 
        , 
        , 
        , 
        {(ДокументОприходования.Дата < &ГраницаДатыОприходования)}
    ) КАК ПартииТоваров

Использование фигурных скобок {} сообщает СКД, что данное условие является необязательным. Если пользователь не задействует параметр, СКД полностью удалит это условие из итогового текста SQL-запроса.

Способ 3. Установка параметра в коде на платформе 1С

Если запрос выполняется программно (в модуле объекта или формы) без применения СКД, значение параметра должно задаваться явно перед вызовом метода Выполнить().

Проанализируем пример кода с проверкой заполнения значения переменной:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Партии.Номенклатура КАК Номенклатура,
    |	Партии.КоличествоОстаток КАК КоличествоОстаток
    |ИЗ
    |	РегистрНакопления.ПартииТоваровНаСкладах.Остатки(&Период, ) КАК Партии";

// Передаем дату периода
Запрос.УстановитьПараметр("Период", ТекущаяДата());

// Если число дней может быть не задано, передаем дефолтное значение 0
ЧислоДнейЗначение = ?(ЗначениеЗаполнено(Дни), Дни, 0);
Запрос.УстановитьПараметр("Дни", ЧислоДнейЗначение);

РезультатЗапроса = Запрос.Выполнить();

Как убрать пустые и нулевые строки из итогового отчета

При левом соединении таблиц или при расчете разницы прихода и расхода в результатах отчета могут появляться пустые строки или строки с нулевыми остатками. Для их исключения рассмотрим два подхода.

Подход 1. Фильтрация на уровне СКД (рекомендуемый)

Для исключения пустых строк лучше использовать механизмы компоновки, чтобы не нарушать работу иерархических итогов. На закладке «Настройки» в разделе «Отбор» добавим условие:

Остатки Не равно 0 или Остатки Заполнено

Подход 2. Фильтрация в тексте запроса

Если необходимо отсечь нули непосредственно на уровне СУБД, добавим секцию ГДЕ или условие ВЫБОР КОГДА в тексте запроса. Разберем пример расчета поля остатка с заменой NULL через ЕСТЬNULL:


ВЫБРАТЬ
    Приход.Номенклатура КАК Номенклатура,
    Приход.КоличествоПриход КАК КоличествоПриход,
    ЕСТЬNULL(Расход.КоличествоРасход, 0) КАК КоличествоРасход,
    ВЫБОР
        КОГДА Приход.КоличествоПриход - ЕСТЬNULL(Расход.КоличествоРасход, 0) > 0
            ТОГДА Приход.КоличествоПриход - ЕСТЬNULL(Расход.КоличествоРасход, 0)
        ИНАЧЕ 0
    КОНЕЦ КАК Остаток
ИЗ
    РегистрНакопления.ПартииТоваровНаСкладах.ОстаткиИОбороты КАК Приход
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ПартииТоваровНаСкладах.ОстаткиИОбороты КАК Расход
    ПО Приход.Номенклатура = Расход.Номенклатура
ГДЕ
    (Приход.КоличествоПриход - ЕСТЬNULL(Расход.КоличествоРасход, 0)) <> 0

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

← На главную