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