Часто при разработке отчетов на системе компоновки данных (СКД) мы сталкиваемся с ситуацией, когда условие в блоке ГДЕ запроса работает не так, как мы ожидаем. Особенно это заметно, когда в запросе используется ЛЕВОЕ СОЕДИНЕНИЕ. Давайте разберемся, почему программа «игнорирует» ваш фильтр и как заставить его работать правильно.
Рассмотрим ситуацию: вы соединяете основной документ (например, ПоступлениеУслугРабот) с регистром сведений ОперацииДокументов через ЛЕВОЕ СОЕДИНЕНИЕ. Если для документа нет записи в регистре, поле ОперацииДокументов.Операция будет иметь значение NULL.
Когда вы добавляете в раздел ГДЕ условие вида ОперацииДокументов.Операция <> ЗНАЧЕНИЕ(...), база данных пытается сравнить значение операции с вашим параметром. Проблема в том, что в языке запросов 1С любое сравнение (кроме использования оператора ЕСТЬ NULL) с NULL дает результат ЛОЖЬ. В итоге записи, у которых нет данных в регистре, просто исчезают из результата, так как условие отсекает их как «неудовлетворяющие критерию».
Существует несколько проверенных способов исправить это поведение и получить корректную выборку данных. Давайте рассмотрим их подробно.
Это самый популярный и надежный способ. Мы можем принудительно заменить NULL на пустое значение справочника, которое мы сможем корректно сравнить с нашим параметром. Для этого используем функцию ЕСТЬNULL.
Рассмотрим, как изменить условие в запросе:
ГДЕ
ПоступлениеУслугРаботУслугиИРаботы.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода
И НЕ ПоступлениеУслугРаботУслугиИРаботы.Ссылка.ПометкаУдаления
И ЕСТЬNULL(ОперацииДокументов.Операция, ЗНАЧЕНИЕ(Справочник.ТиповыеОперации.ПустаяСсылка)) <> ЗНАЧЕНИЕ(Справочник.ТиповыеОперации.ПоступлениеУслугРабот_Резерв_НачислениеОбязательствЗаСчетРезерва)
Используя этот подход, мы гарантируем, что если записи в регистре нет, вместо NULL будет подставлена пустая ссылка, которая успешно пройдет проверку на неравенство.
Если вы не хотите использовать функцию ЕСТЬNULL, можно явно указать в условии, что нам подходят либо записи, где операция отличается от указанной, либо записи, где операции вовсе нет (т.е. она равна NULL).
ГДЕ
ПоступлениеУслугРаботУслугиИРаботы.Ссылка.Дата МЕЖДУ &НачалоПериода И &КонецПериода
И НЕ ПоступлениеУслугРаботУслугиИРаботы.Ссылка.ПометкаУдаления
И (ОперацииДокументов.Операция <> ЗНАЧЕНИЕ(Справочник.ТиповыеОперации.ПоступлениеУслугРабот_Резерв_НачислениеОбязательствЗаСчетРезерва)
ИЛИ ОперацииДокументов.Операция ЕСТЬ NULL)
Этот способ позволяет добиться того же результата, четко разделив логику фильтрации в запросе.
Чтобы в будущем быстрее находить причины странного поведения отчетов, воспользуйтесь следующими рекомендациями:
ЛЕВОГО СОЕДИНЕНИЯ в разделе ГДЕ может замедлить выполнение запроса. Если вы работаете с большими объемами данных, попробуйте перенести условие непосредственно в блок ПО вашего соединения. Это позволит отфильтровать записи еще на этапе объединения таблиц, что значительно повысит производительность.Проанализировав эти методы, вы сможете легко диагностировать подобные проблемы в своих будущих разработках и строить более стабильные и быстрые отчеты!