Как использовать необязательный параметр в вычисляемом поле запроса СКД и избежать ошибки «Не задано значение параметра»?

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

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

Суть проблемы: почему возникает ошибка?

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

Код в поле запроса выглядит примерно так:


ВЫБОР 
   КОГДА СчетаОплаты.СчетОплаты = &СчетОплаты 
      ТОГДА (Остатки.Сумма1 + Остатки.Сумма2) * (СчетаОплаты.Коэффициент / 100) 
   ИНАЧЕ Остатки.Сумма1 + Остатки.Сумма2
КОНЕЦ

Проблема возникает в тот момент, когда пользователь формирует отчет, не заполнив поле параметра &СчетОплаты. Система выдает критическую ошибку: «Не задано значение параметра "СчетОплаты"».

Давайте разберемся, почему это происходит. СКД формирует итоговый SQL-запрос к СУБД. В языке запросов SQL (и транслируемом в него языке запросов 1С) все параметры, упомянутые в секции ВЫБРАТЬ или жестких условиях, должны быть инициализированы перед выполнением. Если параметр не задан в настройках, платформа не знает, какое значение передать серверу баз данных (NULL, пустую ссылку или что-то еще), и блокирует выполнение запроса.

Даже если вы снимите галочку "Запрещать незаполненные значения" или "Использование" в настройках параметра, само упоминание переменной &СчетОплаты в тексте поля запроса делает его обязательным для инициализации на уровне платформы.

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

Способ 1: Инициализация параметра через «Выражение» (Рекомендуемый)

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

Проанализируем шаги настройки:

  1. Откройте конструктор схемы компоновки данных.
  2. Перейдите на вкладку Параметры.
  3. Найдите ваш параметр СчетОплаты.
  4. Обратите внимание на колонку Выражение. Именно здесь мы можем задать логику инициализации.

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

Значение(Документ.СчетаОплаты.ПустаяСсылка)

Или, если это справочник:

Справочники.СчетаОплаты.ПустаяСсылка()

Как это работает:

Когда СКД начинает компоновку макета, она проверяет параметры. Если пользователь не ввел значение, система вычисляет формулу из колонки "Выражение". В параметр &СчетОплаты попадает пустая ссылка. Запрос к базе данных выполняется корректно, так как параметр инициализирован. В условии КОГДА СчетаОплаты.СчетОплаты = &СчетОплаты будет происходить сравнение с пустой ссылкой. Если в данных нет пустых ссылок, условие вернет ЛОЖЬ, и отработает ветка ИНАЧЕ. Ошибка исчезнет.

Способ 2: Использование Вычисляемых полей СКД

Этот способ часто считается более "чистым" с точки зрения архитектуры отчетов на СКД. Вместо того чтобы загромождать текст запроса сложными конструкциями ВЫБОР КОГДА, мы переносим логику на уровень вычислений самой СКД (после получения данных из СУБД).

Давайте реализуем это пошагово:

  1. Упростите запрос. Уберите конструкцию ВЫБОР из текста запроса. Вместо этого просто выберите все необходимые поля, которые участвуют в расчете. В нашем примере нужно выбрать:
    • НачисленныйОстатокКонечныйОстаток
    • ОстаточныйОстатокКонечныйОстаток
    • СчетаОплаты.Коэффициент (можно через точку от поля регистра или отдельным соединением)
    • СчетаОплаты.СчетОплаты
  2. Создайте Вычисляемое поле. Перейдите на вкладку Вычисляемые поля в конструкторе схемы. Добавьте новое поле, назовите его, например, СуммаСУчетомКоэффициента.
  3. Напишите выражение. В колонке "Выражение" для этого поля пропишите логику, используя язык выражений СКД. Он похож на язык запросов, но имеет свои особенности.

Текст выражения в вычисляемом поле:


ВЫБОР 
   КОГДА СчетОплаты = Параметры.СчетОплаты 
   ТОГДА (НачисленныйОстатокКонечныйОстаток + ОстаточныйОстатокКонечныйОстаток) * (Коэффициент / 100)
   ИНАЧЕ НачисленныйОстатокКонечныйОстаток + ОстаточныйОстатокКонечныйОстаток
КОНЕЦ

В чем преимущество этого метода?

В вычисляемых полях обращение к Параметры.ИмяПараметра не требует жесткой инициализации на уровне SQL. Если параметр не задан, он может принимать значение Неопределено. Кроме того, здесь можно использовать функцию ЗначениеЗаполнено(Параметры.СчетОплаты) для более гибкой проверки. Запрос к базе данных становится проще и быстрее, а логика расчета выполняется уже в оперативной памяти сервера приложений.

Способ 3: Проверка на NULL и использование фигурных скобок (для продвинутых)

Иногда возникают советы использовать фигурные скобки {} или проверку на NULL. Давайте разберем, когда это уместно, а когда нет.

Использование { } (расширения языка запросов)

Фигурные скобки в СКД (например, {ГДЕ ...} или {ВЫБРАТЬ ...}) служат для того, чтобы части запроса включались в итоговый SQL только тогда, когда пользователь использует соответствующие поля или отборы.

Если вы напишете в секции ВЫБРАТЬ конструкцию вида:


{ВЫБРАТЬ
   (ВЫБОР КОГДА ... &СчетОплаты ... КОНЕЦ) КАК МоеПоле
}

То поле МоеПоле будет рассчитываться только если пользователь явно выберет его в настройках отчета. Если он его не выберет, параметр &СчетОплаты не попадет в запрос, и ошибки не будет. Но если поле выбрано, а параметр пуст — ошибка вернется. Поэтому для решения нашей задачи фигурные скобки сами по себе не помогают без инициализации параметра.

Проверка на значение (ЗНАЧЕНИЕ(...))

Попытка проверить параметр внутри запроса конструкцией:

ВЫБОР КОГДА &СчетОплаты = ЗНАЧЕНИЕ(Документ.СчетаОплаты.ПустаяСсылка) ТОГДА ...

Не спасет от ошибки "Не задано значение параметра", потому что платформа 1С все равно попытается передать значение &СчетОплаты в СУБД для выполнения сравнения. Если значения нет — будет ошибка. Поэтому этот метод работает только в комбинации со Способом 1.

Итоговый алгоритм действий

Чтобы гарантированно решить проблему с необязательным параметром в поле запроса, выполните следующие действия:

  1. Оставьте вашу логику с ВЫБОР КОГДА ... в тексте запроса (если не хотите переделывать на вычисляемые поля).
  2. Перейдите на вкладку Параметры в Схеме Компоновки Данных.
  3. Для параметра СчетОплаты убедитесь, что флажок Ограничение доступности настроен так, как вам нужно (обычно его не ставят, если пользователь должен иметь возможность менять параметр).
  4. Самое важное: в колонке Выражение пропишите дефолтное значение: Значение(Справочник.СчетаОплаты.ПустаяСсылка) или Справочники.СчетаОплаты.ПустаяСсылка().
  5. В колонке Значение ничего указывать не обязательно, если есть выражение.

Теперь, при запуске отчета:

Этот подход является стандартом при разработке отчетов на СКД в системах 1С:Предприятие 8.

← На главную