Добрый день! Подскажите пожалуйста, нет ли у кого примера реализации подбора товаров с характеристиками. Никак не могу составить динамический запрос, который вытягивал бы товар с присущими ему характеристиками. Характеристики реализованы по схеме:ПланВидовХарактеристик.СвойстваНоменклатуры, подчиненный ему Справочник.ВидыХарактеристик и РегистрСведений.ЗначенияСвойствНоменклатуры с измерениями НаборСвойств(СправочникСсылка.Номенклатура), ВидСвойства(ПланВидовХарактеристикСсылка.СвойстваНоменклатуры) и ресурсом Значение(Характеристика.СвойстваНоменклатуры)
---
Т.к. у вас номенклатура с характеристиками (т.е. может быть несколько одинаковых номенклатур), сделать иерархию через динамический список стандартными средствами не выйдет. У вас 2 варианта:
1. Переделать на дерево значений и использовать ИТОГИ.
2. Вынести иерархию в отдельный список (как в типовых: слева дерево папок, справа номенклатура и остатки с ценами).
И еще один момент: когда делаете полное соединение, необходимо использовать ЕСТЬNULL для всех полей, например:

```1c
    ЕСТЬNULL(ОстаткиНаСкладахОстатки.Номенклатура, ЦеныНоменклатурыСрезПоследних.Номенклатура) КАК Номенклатура
```
---
если конфа типовая, почему бы не передрать с какого нибудь документа, товарного ?
---
Конфа самописная и я уже почти реализовал подбор, но не удается подвязать в запрос Справочник.Номенклатура, чтобы товары отображались в иерархии. Без иерархии сделал.
---
Вы ведете учет остатков в разрезе характеристик ?
---
Да
---
Ну значит у вас есть регистр накопления вида "Номенклатура, Характеристика" - 1 шт.

При подборе товара по остаткам открывайте форму выбора с таблицей с колонками "Номенклатура, Характеристика, количество" и заполняйте ее из своего регистра.

Собственно так и сделано во всех конфигурациях, в чем ваше отличие ?
---
Я изначально так и сделал, соеденив в запросе РегистрНакоплений.ОстаткиНаСкладах и РегистрСведений.ЦеныНоменклатуры, чтобы еще получить остатки и цену для товаров. Но мне хочется, чтобы номенклатура отображалась в иерархии, значит туда нужно как то подвязать Справочник.Номенклатура. И если бы не было характеристик, никаких проблем, но именно наличие характеристик у меня и вызывает затруднение.
---
Делайте заполнение с помощью СКД, там в группировке можно указать, что нужно выводить с иерархией.
---
А не могли бы Вы подробней написать как это сделать? У меня немного опыта программирования. Есть динамический запрос в форме подбора справочника Номенклатура как оттуда выйти в СКД?
---
Много и долго писать. Поищите как результат СКД вывести в дерево значений. В вашем случае это будет именно дерево, раз иерархия.
---
Тут еще одна проблема. Если товара нет на остатках, то при реализации подбора через регистр накопления ОстаткиНаСкладах мы его не увидим в форме подбора. И тут снова встает проблема, как связать Справочник.Номенклатура с регистрами остатков и цен, так чтобы подтянуть туда и характеристики? И СКД тут не поможет, потому как снова все упирается в запрос. А будет запрос связывающий все воедино, так можно и без СКД обойтись так как Справочник Номенклатура иерархический.
---
Элементарная задача через левое соединение связать таблицу номенклатуры с таблицей остатков.
---
Когда нет характеристик задача действительно элементарная. Левое соединение Справочник.Номенклатура с регистрами ОстаткиНаСкладах и ЦеныНоменклатуры где СправочникСсылкаНоменклатура = Измерение Номенклатура у регистров. Но когда присутствуют характеристики, с чем связывать измерение Характеристика у регистров? Справочник.Номенклатура не является владельцем справочника ХарактеристикиНоменклатуры и как тут быть?

Вот запрос из моего подбора но там нет справочника Номенклатура:

```1c
    ВЫБРАТЬ
    ОстаткиНаСкладахОстатки.Номенклатура КАК Номенклатура,
    ОстаткиНаСкладахОстатки.Характеристика КАК Характеристика,
    ЦеныНоменклатурыСрезПоследних.ВидЦены КАК ВидЦены,
    ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.Цена, 0) КАК Цена,
    ОстаткиНаСкладахОстатки.Склад КАК Склад,
    ЕСТЬNULL(ОстаткиНаСкладахОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток
    ИЗ
    РегистрНакопления.ОстаткиНаСкладах.Остатки(&Дата, ) КАК ОстаткиНаСкладахОстатки
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ВидЦены = &ВидЦены) КАК ЦеныНоменклатурыСрезПоследних
    ПО ОстаткиНаСкладахОстатки.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
    И ОстаткиНаСкладахОстатки.Характеристика = ЦеныНоменклатурыСрезПоследних.Характеристика
```
---
Вам остался один шаг. Поместите данный запрос в подзапрос или во временную таблицу и соедините со справочником Номенклатура только по номенклатуре левым соединением. Если вам нужно, дерево и у вас не СКД, смотрите в сторону ИТОГИ ПО... ИЕРАРХИЯ.
А вообще рекомендую агрегировать остатки и цены полным соединением или объединением, т.к. может же быть ситуация, когда остатков нет, а цена есть, тогда пользователь ее просто не увидит.
---
Спасибо! Я так и сделал, но в динамическом запросе нет итогов.

```1c
    ВЫБРАТЬ РАЗРЕШЕННЫЕ
    ОстаткиНаСкладахОстатки.Характеристика КАК Характеристика,
    ЦеныНоменклатурыСрезПоследних.ВидЦены КАК ВидЦены,
    ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.Цена, 0) КАК Цена,
    ОстаткиНаСкладахОстатки.Склад КАК Склад,
    ЕСТЬNULL(ОстаткиНаСкладахОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток,
    ОстаткиНаСкладахОстатки.Номенклатура КАК Номенклатура
    ПОМЕСТИТЬ ВТ
    ИЗ
    РегистрНакопления.ОстаткиНаСкладах.Остатки(&Дата, ) КАК ОстаткиНаСкладахОстатки
    ПОЛНОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ВидЦены = &ВидЦены) КАК ЦеныНоменклатурыСрезПоследних
    ПО ОстаткиНаСкладахОстатки.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
    И ОстаткиНаСкладахОстатки.Характеристика = ЦеныНоменклатурыСрезПоследних.Характеристика
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    СпрНоменклатура.Ссылка КАК Номенклатура,
    ВТ.Характеристика КАК Характеристика,
    ВТ.ВидЦены КАК ВидЦены,
    ВТ.Цена КАК Цена,
    ВТ.Склад КАК Склад,
    ВТ.КоличествоОстаток КАК КоличествоОстаток
    ИЗ
    Справочник.Номенклатура КАК СпрНоменклатура
    ЛЕВОЕ СОЕДИНЕНИЕ ВТ КАК ВТ
    ПО СпрНоменклатура.Ссылка = ВТ.Номенклатура
    ГДЕ
    СпрНоменклатура.ВидНоменклатуры <> ЗНАЧЕНИЕ(Справочник.ВидыНоменклатуры.Услуга)
```

И у меня по итогу так и не выходит получить дерево как хотелось бы
---
Т.к. у вас номенклатура с характеристиками (т.е. может быть несколько одинаковых номенклатур), сделать иерархию через динамический список стандартными средствами не выйдет. У вас 2 варианта:
1. Переделать на дерево значений и использовать ИТОГИ.
2. Вынести иерархию в отдельный список (как в типовых: слева дерево папок, справа номенклатура и остатки с ценами).
И еще один момент: когда делаете полное соединение, необходимо использовать ЕСТЬNULL для всех полей, например:

```1c
    ЕСТЬNULL(ОстаткиНаСкладахОстатки.Номенклатура, ЦеныНоменклатурыСрезПоследних.Номенклатура) КАК Номенклатура
```
---
Спасибо, я как раз и пошел этим путем. Создал РеквизитФормы ИерархияНоменклатуры (ТаблицаЗначений) и переделал Список из ДинамическогоСписка в ТаблицуЗначений.

Это код формы подбора

```1c
    &НаКлиенте
    Процедура СписокВыборЗначения(Элемент, Значение, СтандартнаяОбработка)//Выбор номенклатуры кликом
    ТекСтрока = Элементы.Список.ТекущиеДанные;

    Структура = Новый Структура("Номенклатура, Характеристика, Цена", ТекСтрока.Номенклатура,ТекСтрока.Характеристика, ТекСтрока.Цена);

    СтандартнаяОбработка = ЛОЖЬ;
    //Поиск идентичной номенклатуры в ТаблицеЗначений
    Строка = ОтобранныеТовары.НайтиСтроки(Новый Структура("Номенклатура, Характеристика, Цена", Структура.Номенклатура, Структура.Характеристика, Структура.Цена));
    //Если Номенклатура уже записана то просто добавляем 1 к Количеству
    Если Строка.Количество() > 0 Тогда
    Строка[0].Количество = Строка[0].Количество+1;
    Строка[0].Сумма = Строка[0].Количество * Строка[0].Цена;
    Иначе//Создаем новый элемент
    НовСтр = ОтобранныеТовары.Добавить();
    НовСтр.Номенклатура = ТекСтрока.Номенклатура;
    НовСтр.Характеристика = ТекСтрока.Характеристика;
    НовСтр.Количество = 1;
    НовСтр.Цена = ТекСтрока.Цена;
    НовСтр.Сумма = ТекСтрока.Цена;
    КонецЕсли;
    КонецПроцедуры

    &НаКлиенте
    Процедура СписокНачалоПеретаскивания(Элемент, ПараметрыПеретаскивания, Выполнение)//Выбор номенклатуры перетаскиванием
    ТекСтрока = Элементы.Список.ТекущиеДанные;

    Структура = Новый Структура("Номенклатура, Характеристика, Цена", ТекСтрока.Номенклатура,ТекСтрока.Характеристика, ТекСтрока.Цена);

    СтандартнаяОбработка = ЛОЖЬ;
    //Поиск идентичной номенклатуры в ТаблицеЗначений
    Строка = ОтобранныеТовары.НайтиСтроки(Новый Структура("Номенклатура, Характеристика", Структура.Номенклатура, Структура.Характеристика));
    //Если Номенклатура уже записана то просто добавляем 1 к Количеству
    Если Строка.Количество() > 0 Тогда
    Строка[0].Количество = Строка[0].Количество+1;
    Строка[0].Сумма = Строка[0].Количество * Строка[0].Цена;
    Иначе//Создаем новый элемент
    НовСтр = ОтобранныеТовары.Добавить();
    НовСтр.Номенклатура = ТекСтрока.Номенклатура;
    НовСтр.Характеристика = ТекСтрока.Характеристика;
    НовСтр.Количество = 1;
    НовСтр.Цена = ТекСтрока.Цена;
    НовСтр.Сумма = ТекСтрока.Цена;
    КонецЕсли;
    КонецПроцедуры

    &НаСервере
    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    ВидЦены = Параметры.ВидЦены;
    Склад =Параметры.Склад;
    Дата = Параметры.Дата;
    КонецПроцедуры

    &НаКлиенте
    Процедура ПеренестиВДокумент(Команда)
    ОповеститьОВыборе(ОтобранныеТовары);
    КонецПроцедуры

    &НаСервере
    Функция ЗаполнитьСписокНаСервере(Родитель)

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ РАЗРЕШЕННЫЕ
    | ЕСТЬNULL(ОстаткиНаСкладахОстатки.Характеристика, ЦеныНоменклатурыСрезПоследних.Характеристика) КАК Характеристика,
    | ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.ВидЦены, "") КАК ВидЦены,
    | ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.Цена, 0) КАК Цена,
    | ЕСТЬNULL(ОстаткиНаСкладахОстатки.Склад, "") КАК Склад,
    | ЕСТЬNULL(ОстаткиНаСкладахОстатки.КоличествоОстаток, 0) КАК КоличествоОстаток,
    | ОстаткиНаСкладахОстатки.Номенклатура КАК Номенклатура
    |ПОМЕСТИТЬ ВТ
    |ИЗ
    | РегистрНакопления.ОстаткиНаСкладах.Остатки(&Дата, Склад = &Склад) КАК ОстаткиНаСкладахОстатки
    | ПОЛНОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(, ВидЦены = &ВидЦены) КАК ЦеныНоменклатурыСрезПоследних
    | ПО ОстаткиНаСкладахОстатки.Номенклатура = ЦеныНоменклатурыСрезПоследних.Номенклатура
    | И ОстаткиНаСкладахОстатки.Характеристика = ЦеныНоменклатурыСрезПоследних.Характеристика
    |;
    |
    |////////////////////////////////////////////////////////////­////////////////////
    |ВЫБРАТЬ
    | СпрНоменклатура.Ссылка КАК Номенклатура,
    | ВТ.Характеристика КАК Характеристика,
    | ВТ.ВидЦены КАК ВидЦены,
    | ВТ.Цена КАК Цена,
    | ВТ.Склад КАК Склад,
    | ВТ.КоличествоОстаток КАК КоличествоОстаток
    |ИЗ
    | Справочник.Номенклатура КАК СпрНоменклатура
    | ЛЕВОЕ СОЕДИНЕНИЕ ВТ КАК ВТ
    | ПО СпрНоменклатура.Ссылка = ВТ.Номенклатура
    |ГДЕ
    | СпрНоменклатура.Родитель = &Родитель
    | И СпрНоменклатура.ВидНоменклатуры = ЗНАЧЕНИЕ(Справочник.ВидыНоменклатуры.Товар)";

    Запрос.УстановитьПараметр("ВидЦены", ВидЦены);
    Запрос.УстановитьПараметр("Дата", Дата);
    Запрос.УстановитьПараметр("Склад", Склад);
    Запрос.УстановитьПараметр("Родитель", Родитель);

    РезультатЗапроса = Запрос.Выполнить();

    ВДЗ = РезультатЗапроса.Выбрать();

    Список.Очистить();
    Пока ВДЗ.Следующий() Цикл
    Строка = Список.Добавить();
    Строка.Номенклатура = ВДЗ.Номенклатура;
    Строка.Характеристика = ВДЗ.Характеристика;
    Строка.Склад = ВДЗ.Склад;
    Строка.Цена = ВДЗ.Цена;
    Строка.ВидЦены = ВДЗ.ВидЦены;
    Строка.КоличествоОстаток = ВДЗ.КоличествоОстаток;
    КонецЦикла;

    КонецФункции

    &НаКлиенте
    Процедура ИерархияНоменклатурыВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    Родитель = Элементы.ИерархияНоменклатуры.ТекущаяСтрока;
    ЗаполнитьСписокНаСервере(Родитель);
    КонецПроцедуры

    &НаКлиенте
    Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    ТекСтрока = Элементы.Список.ТекущиеДанные;

    Структура = Новый Структура("Номенклатура, Характеристика, Цена", ТекСтрока.Номенклатура,ТекСтрока.Характеристика, ТекСтрока.Цена);

    СтандартнаяОбработка = ЛОЖЬ;
    //Поиск идентичной номенклатуры в ТаблицеЗначений
    Строка = ОтобранныеТовары.НайтиСтроки(Новый Структура("Номенклатура, Характеристика, Цена", Структура.Номенклатура, Структура.Характеристика, Структура.Цена));
    //Если Номенклатура уже записана то просто добавляем 1 к Количеству
    Если Строка.Количество() > 0 Тогда
    Строка[0].Количество = Строка[0].Количество+1;
    Строка[0].Сумма = Строка[0].Количество * Строка[0].Цена;
    Иначе//Создаем новый элемент
    НовСтр = ОтобранныеТовары.Добавить();
    НовСтр.Номенклатура = ТекСтрока.Номенклатура;
    НовСтр.Характеристика = ТекСтрока.Характеристика;
    НовСтр.Количество = 1;
    НовСтр.Цена = ТекСтрока.Цена;
    НовСтр.Сумма = ТекСтрока.Цена;
    КонецЕсли;
    КонецПроцедуры

    (
```
---
А вы сами хотите сделать? Не подойдет что-то из этого?

https://infostart.ru/public/656128/
https://infostart.ru/public/601863/
---
Спасибо. Я хочу попробовать реализовать подбор самостоятельно , ну или почти самостоятельно))