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

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

При переносе данных из внешних систем (например, старых баз 1С v7.7 или таблиц Excel) в современные конфигурации на платформе 1С:Предприятие 8.3 (такие как 1С:Бухгалтерия 3.0 или 1С:Управление торговлей 11) часто возникает необходимость расширить стандартные реквизиты объектов без изменения конфигурации на уровне метаданных. Для этого идеально подходит механизм Дополнительных реквизитов и сведений, входящий в состав Библиотеки стандартных подсистем (БСП).

Однако при работе с такими реквизитами стандартные методы поиска (например, НайтиПоРеквизиту) не работают напрямую, так как эти данные хранятся в подчиненных табличных частях. В этой статье мы подробно разберем, как связать сторонний справочник с номенклатурой через механизм дополнительных реквизитов, как быстро находить связанные объекты и как одним запросом выявить элементы, оставшиеся без привязки.

Архитектурные особенности БСП: Дополнительные реквизиты vs Дополнительные сведения

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

  1. Дополнительные реквизиты — они визуально выглядят как обычные реквизиты на форме объекта, но физически хранятся в табличной части самого объекта. Для номенклатуры это табличная часть Номенклатура.ДополнительныеРеквизиты.
  2. Дополнительные сведения — они не входят в состав самого объекта, а хранятся отдельно во внешнем регистре сведений РегистрСведений.ДополнительныеСведения. Связующим звеном выступает измерение Объект.

Важный нюанс: Если при импорте данных из Excel свойства были записаны как дополнительные сведения, то любые попытки обратиться к табличной части Номенклатура.ДополнительныеРеквизиты вернут пустой результат. Всегда проверяйте, какой тип свойств используется в вашей системе.

Поиск «несвязанных» элементов одним запросом

Рассмотрим ситуацию, когда у нас есть вспомогательный справочник (например, Справочник.Ярлыки), элементы которого выбраны в качестве значений дополнительного реквизита номенклатуры. Нам необходимо определить, какие элементы справочника Ярлыки еще не привязаны ни к одной номенклатуре.

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

Рассмотрим текст запроса:


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

Разберем этот запрос по шагам:

  1. Мы выбираем все элементы из нашего справочника Справочник.Ярлыки.
  2. Используем ЛЕВОЕ СОЕДИНЕНИЕ с табличной частью ДополнительныеРеквизиты справочника номенклатуры. Это позволяет сопоставить каждый ярлык с записями в номенклатуре, где данный ярлык выступает в качестве значения реквизита.
  3. Критически важное условие в соединении: Мы обязательно добавляем отбор И НоменклатураДополнительныеРеквизиты.Свойство = &СвойствоЯрлык. Это исключает ложные сопоставления. Если этого не сделать, а справочник Ярлыки используется как значение для других свойств базы (например, у договоров или контрагентов), запрос отработает некорректно и скроет нужные ярлыки.
  4. В секции ГДЕ мы накладываем условие НоменклатураДополнительныеРеквизиты.Ссылка ЕСТЬ NULL. Это отсекает все успешно соединенные записи, оставляя в результате только те элементы справочника Ярлыки, для которых соответствие в номенклатуре отсутствует.

Использование стандартного программного интерфейса (API) БСП

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

1. Получение значения конкретного свойства для одного объекта:

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


ЗначениеРеквизита = УправлениеСвойствами.ЗначениеСвойства(СсылкаНаНоменклатуру, СсылкаНаСвойство);

2. Пакетное получение значений свойств (оптимально для списков):

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


МассивНоменклатуры = Новый Массив;
// Заполняем массив ссылками...

ТаблицаЗначенийСвойств = УправлениеСвойствами.ЗначенияСвойств(МассивНоменклатуры, Истина, Ложь);

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

3. Безопасная запись дополнительных реквизитов (актуально при импорте данных):

При записи данных из Excel напрямую заполнять табличную часть объекта кодом не рекомендуется, так как это может обойти внутренние бизнес-правила БСП и нарушить ссылочную целостность. Используем безопасный метод записи:


ТаблицаСвойств = Новый ТаблицаЗначений;
ТаблицаСвойств.Колонки.Добавить("Свойство", Новый ОписаниеТипов("ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения"));
ТаблицаСвойств.Колонки.Добавить("Значение");

НоваяСтрока = ТаблицаСвойств.Добавить();
НоваяСтрока.Свойство = СсылкаНаСвойствоЯрлык;
НоваяСтрока.Значение = СсылкаНаЯрлык;

УправлениеСвойствами.ЗаписатьСвойстваУОбъекта(СсылкаНаНоменклатуру, ТаблицаСвойств);

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

При работе с крупными базами данных запросы к табличным частям дополнительных реквизитов могут начать существенно замедляться. Это связано с тем, что СУБД по умолчанию не индексирует поле Значение в подчиненных таблицах 1С.

Чтобы решить эту проблему и ускорить поиск номенклатуры по дополнительным свойствам в десятки раз, необходимо настроить индексирование:

  1. Перейдем в режим 1С:Предприятие под правами администратора.
  2. Откроем список дополнительных реквизитов для справочника «Номенклатура».
  3. В карточке нужного нам реквизита (например, нашего свойства, хранящего ярлыки) включим опцию «Индексировать» (в некоторых версиях БСП эта настройка находится в меню «Дополнительное упорядочение» или доступна при настройке списка).

После сохранения этой настройки платформа автоматически создаст соответствующий индекс в базе данных SQL, что обеспечит мгновенное выполнение наших запросов даже при миллионных объемах записей.

← На главную