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