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

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

При работе с типовыми конфигурациями на базе Библиотеки Стандартных Подсистем (БСП), такими как 1С:Управление торговлей 11, 1С:ERP или 1С:Комплексная автоматизация, часто возникает необходимость найти элементы справочника (например, Номенклатура), у которых не заполнен тот или иной дополнительный реквизит. Разберем детально, как правильно построить запрос для решения этой задачи и какие нюансы следует учитывать.

Разберем природу хранения дополнительных реквизитов

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

  1. Запись в табличной части отсутствует полностью. Элемент никогда не сохраняли с данным реквизитом, либо значение для него не задавалось.
  2. Запись в табличной части существует, но её значение сброшено. В этом случае строка присутствует в табличной части, но в поле Значение находится пустое значение соответствующего типа (пустая ссылка ЗНАЧЕНИЕ(Справочник.ЗначенияСвойствОбъектов.ПустаяСсылка), пустая строка "", число 0 или значение ЛОЖЬ).

Из-за этих особенностей простой отбор может дать неточные результаты, если не учесть оба варианта хранения.

Способ 1. Использование конструкции НЕ В с подзапросом

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

В этом случае подзапрос выбирает ссылки на элементы, содержащие запись о данном реквизите в своей табличной части:


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

Данный вариант прост в написании, однако стоит брать во внимание, что использование оператора НЕ В на больших объемах данных может снижать производительность из-за построения неоптимального плана запроса СУБД.

Способ 2. Левое соединение с проверкой на NULL и пустые значения

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

При таком подходе условие отбора по свойству обязательно выносится в секцию соединения (ПО), а в секции ГДЕ проверяется либо отсутствие связи (ЕСТЬ NULL), либо отсутствие фактического значения:


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

Выясним преимущества этого метода: запрос выполняется быстро и корректно обрабатывает как полное отсутствие строки с реквизитом, так и наличие строки с пустым значением.

Привязка к наборам дополнительных реквизитов

Посмотрим на ситуацию, когда в справочнике присутствуют элементы разных видов. В 1С дополнительный реквизит назначается не всей номенклатуре подряд, а через назначенный **Вид номенклатуры** и связанный с ним набор свойств из справочника НаборыДополнительныхРеквизитовИСведений.

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


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

Особенности работы в СКД (Системе компоновки данных)

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

В настройках компоновки данных достаточно добавить отбор по нужному реквизиту с видом сравнения Не заполнено. Платформа самостоятельно сформирует оптимальный SQL-запрос с учетом проверки на пустые ссылки и отсутствие записей.

← На главную