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

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

При работе с механизмом дополнительных реквизитов программисты часто сталкиваются с ситуацией, когда стандартный запрос с условием ГДЕ Значение = ЛОЖЬ не возвращает никаких данных. Это происходит из-за особенностей хранения данных в 1С: если булево свойство не установлено или имеет значение Ложь, запись в базе данных (в регистре сведений или табличной части) может просто отсутствовать для экономии места. Разберем подробно, как правильно составить запрос, чтобы найти такие объекты.

Почему обычное соединение не работает?

Рассмотрим ситуацию: в документе ПоступлениеТоваровУслуг есть дополнительный реквизит типа Булево. Если мы попытаемся использовать ВНУТРЕННЕЕ СОЕДИНЕНИЕ документа с регистром ЗначенияСвойствОбъектов, в результат попадут только те документы, для которых это свойство было явно установлено в значение Истина. Те документы, где флаг снят, физически не имеют соответствующей записи в регистре, и внутреннее соединение их просто отсечет. Проанализируем, как обойти это ограничение.

Решение 1: Использование ЛЕВОГО СОЕДИНЕНИЯ и проверки на NULL

Это самый распространенный и эффективный способ. Мы берем все документы и «приклеиваем» к ним таблицу с дополнительными реквизитами. Если записи о реквизите нет, в полях присоединяемой таблицы мы получим NULL. Проверка на NULL как раз и будет означать, что значение реквизита — Ложь или оно не задано.

Важный нюанс: условие по конкретному свойству (его наименованию или ссылке) обязательно должно находиться в секции ПО (условие соединения), а не в секции ГДЕ. Если вынести его в ГДЕ, запрос превратится во внутреннее соединение, и логика сломается.

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


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

В этом примере &СвойствоБулево — это ссылка на элемент плана видов характеристик. Если запись в регистре отсутствует, условие ЕСТЬ NULL вернет истину, и мы получим список документов, у которых данный реквизит не заполнен (что эквивалентно ложному значению в контексте интерфейса).

Решение 2: Использование конструкции ВЫБОР для получения булева значения

Если нам нужно не просто отфильтровать документы, а вывести в списке наглядную колонку со значением флага (Да/Нет), мы можем использовать конструкцию ЕСТЬNULL. Это позволит привести отсутствие записи к значению Ложь.

Проанализируем пример формирования такого поля:


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

Решение 3: Подзапрос с условием НЕ В

Иногда удобнее действовать от обратного: выбрать все документы, кроме тех, у которых значение реквизита установлено в Истина. Этот метод бывает более производительным на некоторых СУБД, так как оптимизатор запросов лучше обрабатывает исключение множества.

Разберем этот вариант запроса:


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

Особенности приведения типов и БСП

В современных конфигурациях на базе БСП (Библиотека стандартных подсистем) дополнительные реквизиты могут храниться не в регистрах сведений, а в табличных частях самих объектов с именем ДополнительныеРеквизиты. Принцип построения запроса остается тем же: Левое соединение к табличной части с фильтром по свойству и проверка на NULL.

Также стоит помнить о следующих моментах:

  1. Типизация поля Значение: Поле Значение в регистре или табличной части имеет составной тип. Если вы сравниваете его со значениями, отличными от Истина или Ложь, может потребоваться использование функции ВЫРАЗИТЬ(Значение КАК Тип).
  2. Индексация: Поле Свойство проиндексировано в типовых механизмах, поэтому поиск по нему работает быстро. Однако при работе с огромными массивами документов (миллионы записей) старайтесь максимально ограничивать выборку документов (например, по дате или организации) до соединения с таблицей свойств.
  3. Наборы свойств: Перед поиском важно понимать, что документ может не иметь записи в регистре просто потому, что для данного типа документов этот реквизит вообще не назначен в справочнике Наборы дополнительных реквизитов и сведений. Если это критично, нужно предварительно проверять связь объекта с его набором свойств.
← На главную