Почему в запросе 1С не срабатывает ЕСТЬNULL внутри конструкции ВЫБОР?

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

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

Проанализируем причину ошибки

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


ВЫБОР
    КОГДА ЦеныНоменклатурыСрезПоследних.ВидЦены = &ВидЦены2
        ТОГДА ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.Цена, "*****")
КОНЕЦ

В этом выражении кроется фундаментальная ошибка логики выполнения запросов при наличии ЛЕВОЕ СОЕДИНЕНИЕ:

  1. Если для конкретной номенклатуры в регистре сведений нет записи с ценой, то все поля присоединенной таблицы ЦеныНоменклатурыСрезПоследних (включая ВидЦены и Цена) принимают значение NULL.
  2. При вычислении выражения ЦеныНоменклатурыСрезПоследних.ВидЦены = &ВидЦены2 происходит сравнение NULL = &ВидЦены2. По правилам трехзначной логики SQL результат такого сравнения не является истинным (он равен Неизвестно / False).
  3. Так как условие в секции КОГДА не выполнилось, вложенная ветка ТОГДА вообще не вычисляется. Соответственно, функция ЕСТЬNULL для цены даже не начинает выполняться.
  4. Поскольку ветка ИНАЧЕ в выражении отсутствует, вся конструкция ВЫБОР возвращает NULL, и колонка отчета остается пустой вместо ожидаемого текста.
  5. Если же запись с указанным видом цены существует, то поле Цена уже содержит числовое значение, и ЕСТЬNULL просто возвращает саму цену, никогда не доходя до значения по умолчанию.

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

Способ 1. Добавление ветки ИНАЧЕ в конструкцию ВЫБОР

Если требуется вывести определенную заглушку при невыполнении условия, необходимо явно определить ветку ИНАЧЕ:


ВЫБОР
    КОГДА ЦеныНоменклатурыСрезПоследних.ВидЦены = &ВидЦены2
        ТОГДА ЦеныНоменклатурыСрезПоследних.Цена
    ИНАЧЕ "*****"
КОНЕЦ

В данном случае, если запись с нужным видом цены отсутствует (поле ВидЦены равно NULL), условие не выполнится, и запрос вернет значение из ветки ИНАЧЕ.

Способ 2. Перенос отбора в параметры виртуальной таблицы (Рекомендуемый)

Наиболее производительный и архитектурно правильный подход в платформе 1С — фильтровать данные среза на уровне параметров виртуальной таблицы. Разберем по шагам:

  1. Накладываем отбор по нужному виду цены непосредственно в параметрах таблицы РегистрСведений.ЦеныНоменклатуры.СрезПоследних.
  2. Соединяем основную таблицу с виртуальной по номенклатуре через ЛЕВОЕ СОЕДИНЕНИЕ.
  3. В списке полей запроса применяем ЕСТЬNULL напрямую к полю цены, без использования громоздких конструкций ВЫБОР.

Посмотрим на пример текста запроса:


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

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


ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, ) КАК Цены
    ПО СпрНоменклатура.Ссылка = Цены.Номенклатура
    И Цены.ВидЦены = &ВидЦены

Способ 3. Использование Условного оформления СКД вместо смешивания типов

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

Если цель — визуально выделить отсутствие цены в отчете, правильнее оставить поле числовым, возвращая 0 при NULL, а визуальное представление настроить через Условное оформление схемы компоновки данных:

  1. В запросе получаем числовую цену: ЕСТЬNULL(Цены.Цена, 0) КАК Цена.
  2. В настройках СКД на вкладке Условное оформление добавляем новый элемент.
  3. В оформляемых полях выбираем поле Цена.
  4. В условии задаем: Цена Равно 0 (или Цена Не заполнено).
  5. В свойствах оформления устанавливаем флажок Текст и указываем значение *****.

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

← На главную