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

Программист 1С v8.3 (Обычные формы) 1C:Бухгалтерия Бухгалтерский учет
← На главную

При работе в конфигурациях на базе обычных форм (например, 1С:Бухгалтерия 2.0) программисты часто сталкиваются с необходимостью расширения функционала типовых обработок. Одной из таких задач является добавление возможности фильтрации объектов по дополнительным сведениям в «Групповой обработке справочников и документов». Основная сложность здесь заключается в специфике хранения этих данных: они находятся не в самом объекте, а во внешнем регистре сведений ДополнительныеСведения.

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

Архитектурная проблема: Документы и Регистры

Прежде всего, проанализируем, как хранятся дополнительные сведения. В системе 1С для этого используется независимый регистр сведений (обычно с именем ДополнительныеСведения или ЗначенияСвойствОбъектов). Он имеет два ключевых измерения: Объект (ссылка на документ или справочник) и Свойство (ссылка на план видов характеристик). Само значение хранится в ресурсе Значение.

Когда мы хотим отобрать документы, у которых определенное свойство (например, «Зарегистрирован») имеет значение «Нет» или вовсе не заполнено, мы сталкиваемся с технической ловушкой. Если пользователь никогда не устанавливал значение этого свойства для документа, то записи в регистре для этого документа просто не существует. Рассмотрим, как это влияет на логику запроса.

Разбор типичной ошибки при использовании ЛЕВОГО СОЕДИНЕНИЯ

Рассмотрим пример запроса, который на первый взгляд кажется верным, но фактически работает как ВНУТРЕННЕЕ СОЕДИНЕНИЕ, отсекая все нужные нам пустые значения. Проанализируем код:


ВЫБРАТЬ
    Приложение2КНалоговойНакладной.Ссылка
ИЗ
    Документ.Приложение2КНалоговойНакладной КАК Приложение2КНалоговойНакладной
ЛЕВОЕ СОЕДИНЕНИЕ 
    РегистрСведений.ДополнительныеСведения КАК ДополнительныеСведения
ПО 
    Приложение2КНалоговойНакладной.Ссылка = ДополнительныеСведения.Объект
ГДЕ
    Приложение2КНалоговойНакладной.Дата >= &ДатаС 
    И Приложение2КНалоговойНакладной.Дата <= &ДатаПо 
    И ДополнительныеСведения.Свойство = &Свойство 
    И ДополнительныеСведения.Значение = &Значение

Почему этот код не работает для поиска незаполненных значений? Проблема кроется в секции ГДЕ. Когда мы указываем условие ДополнительныеСведения.Свойство = &Свойство, СУБД ожидает конкретное значение. Если записи в регистре нет, поле Свойство принимает значение NULL. Сравнение NULL = &Свойство всегда дает ложь, и в результате документ исключается из выборки. Таким образом, наше ЛЕВОЕ СОЕДИНЕНИЕ превращается во внутреннее, и мы теряем все документы без записей в регистре.

Правильная реализация отбора через ЕСТЬNULL

Чтобы корректно обработать ситуацию, когда записи в регистре отсутствуют, нам необходимо использовать функцию ЕСТЬNULL и правильно перераспределить условия запроса. Выясним, как это сделать по шагам.

Шаг 1. Перенос условия по свойству в параметры связи. Условие на то, какое именно свойство мы проверяем, должно быть частью соединения ПО. Это позволит нам получить NULL в значениях только для интересующего нас свойства, а не для всех свойств объекта сразу.

Шаг 2. Обработка NULL в секции ГДЕ. Мы должны проверить, совпадает ли значение из регистра с искомым, либо (если мы ищем незаполненные) является ли оно NULL.

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


ВЫБРАТЬ
    Док.Ссылка КАК Ссылка
ИЗ
    Документ.Приложение2КНалоговойНакладной КАК Док
ЛЕВОЕ СОЕДИНЕНИЕ 
    РегистрСведений.ДополнительныеСведения КАК Сведения
ПО 
    Док.Ссылка = Сведения.Объект 
    И Сведения.Свойство = &Свойство
ГДЕ
    Док.Дата МЕЖДУ &ДатаНачала И &ДатаКонца
    И ВЫБОР
        КОГДА &ТолькоНезаполненные = ИСТИНА 
            ТОГДА ЕСТЬNULL(Сведения.Значение, Ложь) = Ложь
        ИНАЧЕ Сведения.Значение = &Значение
    КОНЕЦ

В данном случае, если записи в регистре нет, функция ЕСТЬNULL(Сведения.Значение, Ложь) вернет Ложь, что позволит нам отобрать документы с «пустым» свойством. Это и есть решение проблемы «бубльгума», как выразились участники обсуждения.

Разница между Дополнительными реквизитами и Сведениями

Для качественной разработки важно понимать различие между этими объектами, так как в новых версиях платформы (8.3) и БСП подходы изменились:

  1. Дополнительные сведения (как в нашем примере) хранятся в отдельном регистре. Они не увеличивают размер таблиц документов, но требуют соединений в запросах.
  2. Дополнительные реквизиты в современных конфигурациях часто хранятся в табличных частях самих объектов. Для их отбора нужно обращаться к табличной части документа, что технически проще, но логика обработки отсутствия строки в табличной части остается схожей (использование ЛЕВОЕ СОЕДИНЕНИЕ).

Оптимизация производительности при больших объемах данных

Проанализируем ситуацию, когда в базе данных сотни тысяч документов. Прямое соединение с регистром сведений по полю Объект может работать медленно, так как поле Объект имеет составной тип. Чтобы помочь оптимизатору SQL, рекомендуется использовать конструкцию ВЫРАЗИТЬ.

Рассмотрим пример оптимизированного соединения:


ЛЕВОЕ СОЕДИНЕНИЕ 
    РегистрСведений.ДополнительныеСведения КАК Сведения
ПО 
    Док.Ссылка = ВЫРАЗИТЬ(Сведения.Объект КАК Документ.Приложение2КНалоговойНакладной)
    И Сведения.Свойство = &Свойство

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

Использование в современных конфигурациях (БСП)

Если вы работаете в 1С:Бухгалтерия 3.0 или ERP, вам, скорее всего, не придется писать такие запросы вручную. Современная обработка «Групповое изменение реквизитов» уже включает в себя механизмы работы с подсистемой свойств. Она автоматически строит сложные динамические запросы, которые учитывают и отсутствие записей в регистрах, и значения по умолчанию.

Однако понимание работы ЛЕВОЕ СОЕДИНЕНИЕ и функции ЕСТЬNULL остается фундаментальным навыком для любого программиста 1С, так как это база для построения любых сложных отчетов в консоли запросов или СКД.

Итоги

Мы разобрали, как решить проблему отбора по незаполненным дополнительным свойствам. Подведем итоги нашего анализа:

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

← На главную