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

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

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

Разберем подробнее исходную проблему, выясним причины возникновения ошибок и рассмотрим правильные варианты построения условий в запросах 1С.

Анализ синтаксических ошибок в условии отбора

Рассмотрим фрагмент ошибочного запроса:


ГДЕ
    Значение(РеализацияТоваровТовары.Количество) = ЕСТЬNULL

В приведенном фрагменте допущено сразу несколько принципиальных ошибок:

  1. Некорректное использование функции ЗНАЧЕНИЕ(): данная конструкция предназначена исключительно для получения литералов предопределенных данных конфигурации (например, ЗНАЧЕНИЕ(Перечисление.Статусы.Новый) или ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)). В нее нельзя передавать поля таблиц или переменные.
  2. Путаница между оператором проверки и функцией ЕСТЬNULL:

    В языке запросов 1С существуют две разные конструкции:

    1. Функция ЕСТЬNULL(Поле, ЗначениеЗамены): принимает два обязательных параметра и подставляет значение по умолчанию, если проверяемое поле равно NULL.
    2. Логический оператор Поле ЕСТЬ NULL (или Поле ЕСТЬ НЕ NULL): используется для проверки наличия отсутствующего значения при соединениях таблиц.
  3. Смешивание понятий 0 и NULL: числовое значение 0 — это реальное число. Значение NULL обозначает отсутствие значения как такового в контексте базы данных. В физических таблицах табличных частей реквизиты числового типа имеют признак NOT NULL и значение по умолчанию 0. Значение NULL в таком поле может появиться только в результате левого или полного соединения.

Правильный способ отбора нулевых значений

Если в запросе мы обращаемся напрямую к табличной части документа без внешних соединений, для отбора строк с нулевым количеством достаточно простого сравнения с числом 0.

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


ГДЕ
    РеализацияТоваровТовары.Количество = 0

Если же мы хотим исключить любые некорректные и отрицательные значения (например, при контроле корректности данных), условие можно расширить:


ГДЕ
    РеализацияТоваровТовары.Количество <= 0

Оптимизация и исправление исходного запроса

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

  1. Избыточное обращение Ссылка.Ссылка: для получения ссылки на документ достаточно обращаться к полю Ссылка табличной части. Повторное разыменование порождает лишние операции.
  2. Разыменование полей через точку: обращение к полям Ссылка.Дата, Ссылка.СкладКомпании и Номенклатура.Код создает неявные соединения с таблицами шапки документа и справочника. Для оптимизации лучше использовать явные соединения либо фильтровать шапку отдельно.
  3. Сравнение дат: последовательные проверки >= и <= рекомендуется заменять оператором МЕЖДУ, передавая правую границу периода с учетом конца дня.

Рассмотрим оптимизированный и корректный вариант итогового запроса:


ВЫБРАТЬ
    Товары.Количество КАК Количество,
    Товары.Номенклатура КАК Номенклатура,
    Товары.Ссылка КАК Документ,
    Товары.Номенклатура.Код КАК Код
ИЗ
    Документ.РеализацияТоваров.Товары КАК Товары
ГДЕ
    Товары.Ссылка.Дата МЕЖДУ &Дата1 И &Дата2
    И Товары.Ссылка.СкладКомпании = &ВыбСклад
    И Товары.Количество = 0

Когда действительно необходим оператор ЕСТЬ NULL?

Посмотрим на практический сценарий, когда оператор ЕСТЬ NULL действительно необходим. Например, если стоит задача найти не строки с нулевым количеством, а документы, у которых вообще отсутствуют строки в табличной части.

В этом случае запрос строится к таблице шапки с левым соединением к табличной части:


ВЫБРАТЬ
    Документ.Ссылка КАК Документ,
    Документ.Номер КАК Номер,
    Документ.Дата КАК Дата
ИЗ
    Документ.РеализацияТоваров КАК Документ
    ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваров.Товары КАК Товары
    ПО Документ.Ссылка = Товары.Ссылка
ГДЕ
    Товары.НомерСтроки ЕСТЬ NULL
    И Документ.Дата МЕЖДУ &Дата1 И &Дата2

В таком запросе условие Товары.НомерСтроки ЕСТЬ NULL вернет только те документы, для которых в табличной части Товары не нашлось ни одной соответствующей записи.

← На главную