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

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

В процессе разработки в системе 1С:Предприятие 8 часто возникает задача подбора или поиска существующего объекта (будь то характеристика номенклатуры, сам справочник номенклатуры или документ) по набору дополнительных реквизитов. Сложность заключается в том, что дополнительные реквизиты хранятся в подчиненной табличной части, и стандартный поиск по реквизитам «через точку» здесь не работает. Если свойств два или три, можно обойтись простыми соединениями, но если их количество заранее неизвестно или их достаточно много, требуется универсальный и производительный подход.

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

Метод 1: Использование временной таблицы и условия ИМЕЮЩИЕ

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

Предположим, у нас есть массив или таблица значений, содержащая пары Свойство и Значение. Мы передаем эту таблицу в запрос в качестве параметра &ТЗ. Проанализируем текст запроса:


// 1. Помещаем искомые свойства во временную таблицу
ВЫБРАТЬ
    ТЗ.Свойство КАК Свойство,
    ТЗ.Значение КАК Значение
ПОМЕСТИТЬ ВТ_КритерииПоиска
ИЗ
    &ТЗ КАК ТЗ
;

////////////////////////////////////////////////////////////////////////////////
// 2. Основной запрос для поиска ссылки
ВЫБРАТЬ
    ТЧ.Ссылка КАК Ссылка
ИЗ
    Справочник.ХарактеристикиНоменклатуры.ДополнительныеРеквизиты КАК ТЧ
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ_КритерииПоиска КАК Критерии
        ПО ТЧ.Свойство = Критерии.Свойство
            И ТЧ.Значение = Критерии.Значение

СГРУППИРОВАТЬ ПО
    ТЧ.Ссылка

ИМЕЮЩИЕ
    КОЛИЧЕСТВО(*) = &КоличествоСвойств

Разберем логику этого запроса. Мы выполняем ВНУТРЕННЕЕ СОЕДИНЕНИЕ табличной части характеристик с нашей временной таблицей. В результат соединения попадут только те строки, где совпали и свойство, и значение. Далее мы группируем результат по полю Ссылка. Если характеристика обладает всеми искомыми свойствами, то количество записей в группе для этой ссылки будет в точности равно количеству искомых свойств (переменная &КоличествоСвойств).

Важный нюанс: этот метод найдет характеристики, в которых присутствуют искомые свойства, но он не исключает наличие у характеристики других (лишних) реквизитов. Если нам нужно найти строгое соответствие «один в один», этот запрос требует доработки.

Метод 2: Обеспечение строгого соответствия (поиск без лишних свойств)

Если задача стоит найти характеристику, у которой набор свойств полностью совпадает с искомым (ни больше, ни меньше), нам необходимо добавить проверку общего количества реквизитов у найденного объекта. Проанализируем, как модифицировать условие ИМЕЮЩИЕ.

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


ВЫБРАТЬ
    ТЧ.Ссылка КАК Ссылка
ИЗ
    Справочник.ХарактеристикиНоменклатуры.ДополнительныеРеквизиты КАК ТЧ
ГДЕ
    (ТЧ.Свойство, ТЧ.Значение) В (ВЫБРАТЬ Свойство, Значение ИЗ ВТ_КритерииПоиска)

СГРУППИРОВАТЬ ПО
    ТЧ.Ссылка

ИМЕЮЩИЕ
    КОЛИЧЕСТВО(*) = &КоличествоСвойств
    И КОЛИЧЕСТВО(*) = (ВЫБРАТЬ КОЛИЧЕСТВО(*) 
                       ИЗ Справочник.ХарактеристикиНоменклатуры.ДополнительныеРеквизиты КАК ТЧ_Все 
                       ГДЕ ТЧ_Все.Ссылка = ТЧ.Ссылка)

Такой подход гарантирует, что количество совпадений не только равно количеству искомых параметров, но и равно общему количеству реквизитов у данного объекта 1С.

Метод 3: Динамическое построение текста запроса

В некоторых случаях, особенно когда количество свойств невелико (до 5–7), разработчики применяют метод динамических соединений. Выясним причину использования такого подхода: для SQL-сервера цепочка ВНУТРЕННЕЕ СОЕДИНЕНИЕ часто более прозрачна при построении плана выполнения, чем сложная группировка с условием по количеству.

При этом методе текст запроса формируется в цикле:

  1. Для каждого свойства из набора мы добавляем новое соединение с табличной частью ДополнительныеРеквизиты.
  2. Каждому соединению присваивается уникальный псевдоним (например, ТЧ1, ТЧ2 и т.д.).
  3. В условии связи прописывается конкретное свойство и значение.

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


ТекстЗапроса = "ВЫБРАТЬ ТЧ0.Ссылка ИЗ Справочник.ХарактеристикиНоменклатуры.ДополнительныеРеквизиты КАК ТЧ0";
Для Итератор = 1 По СписокСвойств.Количество() - 1 Цикл
    ТекстЗапроса = ТекстЗапроса + " ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ХарактеристикиНоменклатуры.ДополнительныеРеквизиты КАК ТЧ" + Итератор + 
                   " ПО ТЧ0.Ссылка = ТЧ" + Итератор + ".Ссылка";
КонецЦикла;
// Далее добавляются условия ГДЕ для каждого псевдонима ТЧ...

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

При работе с дополнительными реквизитами в высоконагруженных системах (например, в 1С:ERP или УТ 11, где количество характеристик может исчисляться сотнями тысяч) следует учитывать несколько критических факторов:

  1. Типизация поля Значение: Поле Значение в типовых конфигурациях имеет составной тип. Поиск по полям с составным типом всегда медленнее, чем по полям с простым типом (например, только СправочникСсылка.ЗначенияСвойствОбъектов). Если возможно, ограничивайте типы значений в запросе.
  2. Индексация: Поле Свойство в табличных частях дополнительных реквизитов обычно индексировано, а поле Значение — нет. Это может привести к сканированию всей таблицы. В критических ситуациях для ускорения поиска рекомендуется использовать механизм хеширования.
  3. Хеширование состава реквизитов: Суть метода в том, что при записи характеристики программно формируется уникальная строка (хеш), представляющая собой отсортированный список всех свойств и значений. Эта строка записывается в отдельный индексированный реквизит. Тогда поиск сводится к простому сравнению строк, что работает мгновенно даже на миллионах записей.
  4. Пустые значения: Рассмотрим ситуацию, когда свойство выбрано, но значение не заполнено. В архитектуре 1С пустые дополнительные реквизиты часто просто удаляются из табличной части, чтобы не занимать место. Перед выполнением поиска обязательно очищайте входную таблицу параметров от пустых значений, иначе запрос с КОЛИЧЕСТВО(*) не найдет объект.

Посмотрим на механизмы БСП (Библиотеки стандартных подсистем). В модуле УправлениеСвойствами существуют функции для работы с реквизитами, однако они чаще предназначены для отображения свойств в формах. Для задач массового поиска прямой запрос к базе данных, как мы разобрали выше, остается самым быстрым и надежным инструментом программиста 1С.

← На главную