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