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